Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Đóng gói 1 ứng dụng thành executable-jar file

Đẻ đóng gói một ứng dụng thành dạng jar, ta có thể dùng tool jar sẵn có của bộ JDK. Các công việc sẽ từng bước như sau:

0. Nhớ đặt sẵn tùy biến môi trường PATH đến thư mục  %JAVA_HOME%\bin.; , trong đó %JAVA_HOME% là thư mục cài đặt JDK.

1. Đầu tiên bạn tổ chức thư mục code của bạn cho tốt, sau đó biên dịch chúng đảm bảo không có lỗi. Ghi nhớ tên lớp thực thi (lớp chứa hàm main) của ứng dụng.

2. Tạo file manifest dạng như sau

Manifest-Version: 1.0
Main-Class:tên_lớp_có chứa_hàm_main

3.Thực thi tool jar, cú pháp tổng quát của tool jar như sau

Usage: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files …
Options:
-c  create new archive
-t  list table of contents for archive
-x  extract named (or all) files from archive
-u  update existing archive
-v  generate verbose output on standard output
-f  specify archive file name
-m  include manifest information from specified manifest file
-e  specify application entry point for stand-alone application bundled into an executable jar file
-0  store only; use no ZIP compression
-M  do not create a manifest file for the entries
-i  generate index information for the specified jar files
-C  change to the specified directory and include the following file
If any file is a directory then it is processed recursively. The manifest file name, the archive file name and the entry point name are specified in the same order as the ‘m’, ‘f’ and ‘e’ flags.

Example 1: to archive two class files into an archive called classes.jar:
jar cvf classes.jar Foo.class Bar.class
Example 2: use an existing manifest file ‘mymanifest’ and archive all the
files in the foo/ directory into ‘classes.jar’:
jar cvfm classes.jar mymanifest -C foo/ .


Ví dụ:

Giả sử chúng ta có 1 ứng dụng đơn giản gồm 2 lớp MyJFame.javaRunning.java , chúng được lưu trong thư mục TyEx. Nội dung của chúng như sau

package exjar;

import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class MyJFame extends JFrame{
public MyJFame() {
super(“Hello World!”);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400,200);
JLabel lbl=new JLabel(“CIAO MONDO!”,JLabel.CENTER);
lbl.setFont(new Font(“Arial”,Font.BOLD,40));
lbl.setForeground(Color.red);
this.add(lbl);
}
}

package exjar;

public class Running {
public static void main(String[] args) {
new MyJFame().setVisible(true);
}
}

Ở đây lớp chứa hàm main là lớp Running.

Biên dịch các tập tin java bằng lệnh sau hoặc copy lệnh sau vào tập tin có tên build.bat rồi thực thi

javac -d . *.java
pause

Trong thư mục TyEx ta sẽ có thư mục exjar trong đó chứa 2 tập tin MyJFame.classRunning.class

Tiếp theo ta tạo tập tin manifest có tên Ty.mf trong thư mục TyEx với nội dung sau:

Manifest-Version: 1.0
Main-Class: exjar.Running

Cuối cùng, ta sẽ đóng gói chúng thành tập tin jar tự chạy (executable jar file) bằng lệnh sau hoặc bạn cũng có thể tạo tập tin CreateJARFile.bat trong thư mục TyEx với nội dung sau rồi thực thi nó để tạo jar fiel

jar cvfm MyApp.jar Ty.mf *.java exjar/*.*
pause

Giải thích: c: (create) tạo file jar mới,    f: chỉ định tên file jar (của chúng ta có tên MyApp.jar, v: (verbose output) in thông tin đóng gói ra màn hình, m: chỉ định file manifest. *.java: đưa tất cả source file ở thư mục hiện tại vào file jar, exjar/*.*: đưa tất cả các file của thư mục exjar vào jar file.

Thực thi file này ta sẽ được tập tin MyApp.jar. Thực thi file này bằng cách double-click hoặc enter kết quả như sau:
KetquaJAR

OK, như vậy bạn đã tạo được 1 file jar tự chạy (executable jar file) được rồi đó.

Để biến nó thành file EXE, bạn tham khảo tại đây

Chúc thành công!

22 Responses to “Đóng gói 1 ứng dụng thành executable-jar file”

  1. Đóng gòi file jar kèm theo thư viện??? said

    Cho mình hỏi đóng gói file jar kèm theo thư viện hỗ trợ thì mình đóng gói ntn ạ?

  2. thanhtan said

    em da thuc hien theo cac buoc o tren.va da tao duoc MyApp.jar.Nhung khi thuc thi file jar nay thi bao loi:Failed to load Main-Class manifest attribute from:E:/TyEx/MyApp.jar
    Nho thay giai thich giup em voi!

  3. Huy said

    Cho em hỏi 1 chút a! em có làm 1 ứng dụng viết bằng Java, em đóng gói chương trình thành File thực thi .Jar, nhưng khi chạy thì nó không chạy hay báo lỗi j cả, máy của em đã cài biến môi trường, em đã đóng gói thử các ứng dụng khác thì vẫn chạy ngon lành, còn cái này thì thử mãi ko đc, em chạy ứng dụng của em bằng lệnh java thì vẫn chạy được bình thường, chỉ khi đóng gói lại thì không chạy đc, em đã kiểm tra File META-INF không có j sai cả, mong được sự giúp đỡ…

  4. ATM said

    Cho em hỏi cách tạo ra file build.bat và tạo tập tin manifest có tên Ty.mf như thế nào ạ?

  5. Võ Văn Hải said

    build.bat là script để chạy lại khi cần chạy thay vì ngồi gõ lại câu lệnh. File manifest có ý nghĩa nhiều, ví dụ như chỉ định file tự chạy, hay bean, version,…

  6. Sang Nguyen Van said

    em có một ứng dụng, khi chạy nó bằng netbeans 6.9 thì nó chạy bình thường – hình ảnh của các thành phần nó hiện đầy đủ, khi em tạo file jar và chạy ứng dụng bằng file jar thì ứng dụng không nhân được đường dẫn tời các hình ảnh(thư mục Images em để ngang hàng với các thư mục chứa các thư mục chứa file class)em đã tạo một phương thức và sử dụng chúng:

    public final ImageIcon createImageIcon(String path) {
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
    return new ImageIcon(imgURL);
    } else {
    System.out.println(“Path khong ton tai!!!”);
    return null;
    }
    }

    Mong thầy giúp đỡ. xin chân thành cám ơn!

  7. Võ Văn Hải said

    Em copy thư mục hình ảnh và để cùng cấp với file jar là xong hoặc nếu em để nó trong file jar luôn thì em phải code để mà lấy ra.

  8. Hoang Minh Tý said

    Chào anh!
    – Để chạy 1 file .jar có sẵn, ta làm như thế nào ? Xin hướng dẫn dùm em!
    Xin cảm ơn nhiều!

  9. Võ Văn Hải said

    File jar đó phải là runnable jar file mới chạy được và tất nhiên máy anh có cài JRE. Anh chạy nó bình thường bằng chương trình java.exe/javaw.exe.

  10. nhu cuong said

    làm sao để đóng gói một ứng dụng viết băng c# có kem cơ sở dư liệu nhỉ

  11. Võ Văn Hải said

    Nếu cơ sở dữ liệu dạng Server/Client thì khỏi nói. Còn dạng file như MS Access thì thêm nó vào install project là được. Tuy nhiên trong quá trình viết code phải dùng đường dẫn tương đối đến file access dạng

    Application.StartupPath+”\somewhere\yourfiles.mdb

  12. bachthevu said

    Thầy ơi cho e hỏi , e có 1 ứng dụng java viết trên netbean , e compile bằng lệnh javac các file .java thì nó báo rất nhìu lỗi nhưng chủ yếu là lỗi font(vì trong code có nhiều chỗ e dùng tiếng Việt ví dụ như xuất ra 1 thông báo v.v..) , e dùng lệnh jar cvfm để đóng gói kèm theo file manifest.mf. Cấu trúc file manifest của e như sau:

    Manifest-Version: 1.0
    Created-By: 1.6.0_16 (Sun Microsystems Inc.)
    Main-Class: Main

    Sau đó e dùng lệnh java để thực thi file jar đóng gói được nhưng nó lại báo lỗi “could not find main class: Main.Program will exit” , e đã kiểm tra lại tên class ko có j sai , xin thầy giúp đỡ e , cám ơn thầy rất nhiều!!!

  13. Võ Văn Hải said

    1. khi compile bằng command-line, thêm option “-encoding UTF8.”
    2. Xem lại package của em có đúng chưa

  14. vanle said

    Thầy ơi cho em hỏi, em có 3 class là: Account năm trong package com.vn.accouting , HumanResource nằm trong com.vn.hr và class Main nằm trong package com.vn. Lớp Main truy xuất đến phương thức của 2 lớp còn lại. Sau khi đóng gói 2 class Account và HumanResource thành file jar, giờ thì làm sao đế chạy hàm Main bằng cách link đến 2 flie jar này mà chạy ạ?
    Mong thầy và các bạn giúp đỡ!

  15. nguyên said

    mình muốn tạo 1 file giống như file phần mền vitalk vậy đó .vậy mình phải làm như thế nào bạn có thể giúp mình được không ?

  16. Hoan said

    Thầy cho em hỏi khi em dùng exe4j tạo file exe cho một ứng dụng Destop trên Winxp thì mọi thứ không vấn đề gì nhưng khi chạy nó trên Win7 hoặc trực tiếp tạo file exe trên win7 thì thông báo lỗi “com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host has failed. java.net.SocketException: Invalid argument”, khi biên dịch và chạy chương trình này trên Netbean thì vẫn chạy bình thường! Cảm ơn thầy!

  17. Võ Văn Hải said

    Coi lại cách kety61 nối với SQL server thế nào? Xem thử port 1433 đã enable chưa? Username/password kết nối thế nào? Driver ra sao?

  18. Lê Nương said

    thầy ơi, em thật sự gặp vấn đề khi biên dịch 1 chương trình code java, em không thể nào thiết lập được để chạy, và cũng mù tịt về java, nhưng em lại phải làm bài tập môn hệ chuyên gia, cái shell này viết bằng java và nó cần biên dịch bằng java mới có thể chạy được, thầy có thể xem giúp em pack của cái shell này, rồi chỉ giáo cho em cách chạy không ạ? em cám ơn thầy nhiều, vì đề tài này không hề có tiếng Việt, mà tiếng anh thì rất khó để có 1 chỉ dẫn đúng, cần người đọc phải hiểu về java. mong thầy giúp em.
    thầy có thể có em xin địa chỉ mail vào mail của em không ạ? em sẽ gửi thầy pack phần mềm này.
    thầy xem giúp em với ạ.

  19. Lê Nương said

    ah, cái file cần biên dịch của em nó là file đuôi CLP, nhưng nó vẫn cần phải biên dịch, em đọc hướng dẫn thì thật sự không hiểu gì”http://www.jessrules.com/jess/docs/52/intro.html” ở đây có hướng dẫn nhưng em không hiểu j hết, thầy có thể xem và nói lại cho em rõ được không ạ? em cám ơn thầy lắm lắm

  20. Lê Nương said

    Mr.hải ơi, giúp em nhanh với, đây là demo bài tập lớn của em,, huhu

  21. Lê Dũng said

    thầy ơi! Sửa lổi này giùm em với: PWC2788: setAttribute: Non-serializable attribute with name maTK.
    em đang học JSP nên không biết.Mog thầy sữa giùm em với.Cảm ơn thầy nhiều.
    maTK la session.

  22. Hung Nguyen said

    thưa thầy.lúc build chương trình trong NETBEAN.nó tự sinh ra 1 thư mục dist có chứa file .jar .em sử dụng luôn file này để đóng gói thành .exe thì nó toàn báo lỗi như thế này là sao ạ?

    java.lang.UnsupportedClassVersionError: Bad version number in .class file
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
    at com.exe4j.runtime.WinLauncher.main(Unknown Source)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: