Chạy một tệp JAR từ dòng lệnh và chỉ định classpath


115

Tôi đã biên dịch tệp JAR và chỉ định Lớp chính trong tệp kê khai (Tôi đã sử dụng chức năng Xuất Eclipse ). Các phụ thuộc của tôi đều nằm trong một thư mục có nhãn lib. Tôi dường như không thể nhận được câu trả lời thẳng thắn về cách thực thi tệp JAR của mình trong khi chỉ định nó nên sử dụng lib/*làm đường dẫn phân nhánh.

Tôi đã thử:

]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main

Vân vân...

Mỗi lỗi cho biết:

Error: Could not find or load main class ....

hoặc cho NoClassDefFoundErrorbiết các thư viện không được tìm thấy.

Tôi thậm chí đã thử tạo lại tệp JAR và bao gồm libthư mục và nội dung, nhưng vẫn không có xúc xắc ...

Làm cách nào để thực thi tệp JAR từ dòng lệnh và chỉ định đường dẫn phân nhánh để sử dụng?


Câu trả lời:


204

Khi bạn chỉ định -jarthì -cptham số sẽ bị bỏ qua.

Từ tài liệu :

Khi bạn sử dụng tùy chọn này, tệp JAR là nguồn của tất cả các lớp người dùng và các cài đặt đường dẫn lớp người dùng khác bị bỏ qua.

Bạn cũng không thể "bao gồm" các tệp jar cần thiết vào một tệp jar khác (bạn sẽ cần trích xuất nội dung của chúng và đặt các tệp .class vào tệp jar của bạn)

Bạn có hai lựa chọn:

  1. bao gồm tất cả các tệp jar từ libthư mục vào tệp kê khai (bạn có thể sử dụng các đường dẫn tương đối ở đó)
  2. Chỉ định mọi thứ ( bao gồm cả jar của bạn) trên dòng lệnh bằng cách sử dụng -cp:
    java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

22
; thay vì: nếu bạn sử dụng các cửa sổ như sau java -cp MyJar.jar; lib / * com.somepackage.subpackage.Main
Lỗi

Bạn cũng không thể "gộp" các tệp jar cần thiết vào một tệp jar khác. Chắc chắn bạn có thể. Nếu nó để sử dụng nội bộ (tức là, bạn mong đợi người dùng có một số kỹ năng kỹ thuật, v.v.), bạn có thể chỉ cần hỏi rằng bước 1, trước khi cố gắng chạy jar, là chạy unzip MyJar.jar lib/*.jar. Sau đó, như bạn đề xuất, họ có thể chạyjava -cp MyJar.jar:lib/* ...
Roger

3
bummer là trường hợp sử dụng phổ biến của nó để chạy một jar uber "bao gồm tất cả" với tham chiếu đến tệp thuộc tính máy chủ cụ thể bên ngoài. Rõ ràng không phải là một chặn, nhưng chắc chắn một ít tiết lệnh nếu bạn có thể sử dụng -jar và không cần phải xác định chính
Andrew Norman

Tôi mất một thời gian để tìm hiểu. Và mất khoảng 6 dòng để tải tệp log4j một cách rõ ràng. Một lỗi Java khác sẽ không bao giờ được sửa.
Tuntable

1
Lưu ý rằng Class-Path của tệp kê khai chỉ có thể được sử dụng để tải các tệp jar. Chẳng hạn, nó không thể được sử dụng để tra cứu log4j3.xml. Tốt cho tôi.
Tuntable

34

Chạy một tệp jar và chỉ định một đường dẫn lớp như sau:

java -cp <jar_name.jar:libs/*> com.test.App

jar_name.jar là tên đầy đủ của JAR bạn muốn thực hiện

libs/* là một con đường dẫn đến các JAR phụ thuộc của bạn

com.test.Applà tên đủ điều kiện của lớp từ JAR có main(String[])phương thức

Jar và jar phụ thuộc phải có quyền thực thi.


10

Bạn có thể thực hiện những điều này trong unix shell:

java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

Bạn có thể làm những điều này trong windows powershell:

java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main

4

Ngoài ra, sử dụng tệp kê khai để chỉ định đường dẫn lớp và lớp chính nếu bạn muốn, vì vậy bạn không cần sử dụng -cphoặc chỉ định lớp chính. Trong trường hợp của bạn, nó sẽ chứa những dòng như thế này:

Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar

Thật không may, bạn cần phải đánh vần từng jar trong tệp kê khai (không phải là vấn đề lớn như bạn chỉ làm một lần và bạn có thể sử dụng tập lệnh để tạo tệp hoặc sử dụng công cụ xây dựng như ANT hoặc Maven hoặc Gradle). Và tham chiếu phải là một thư mục tương đối hoặc tuyệt đối đến nơi bạn chạy java -jar MyJar.jar.

Sau đó, thực hiện nó với

java -jar MyJar.jar

Tôi nghĩ rằng Class-Path cần phải tham chiếu đến các tệp bên trong jar bên ngoài. Tôi không thể làm cho điều này hoạt động nói chung, để tham khảo các tệp cấu hình bên ngoài MyJar.jar.
Tuntable

0

Bạn có thể thực hiện Runtime.getRuntime.exec (lệnh) để khởi chạy lại jar bao gồm classpath với args.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.