2012-07-15 23 views
7

Trước hết, tôi đã đọc qua nhiều S.O. câu hỏi liên quan đến chủ đề này và tôi đã thử những điều được đề xuất trong đó.Làm thế nào các nguồn lực trong một jar được biên dịch được truy cập?

Đây là tình huống của tôi. Tôi đang viết một ứng dụng Java bằng cách sử dụng khung Xử lý và tôi đang ở giai đoạn cuối cùng mà tôi cần bắt đầu suy nghĩ về việc đóng gói ứng dụng. Một tệp jar có thể thực thi được từ dòng lệnh là những gì tôi đang cố gắng xây dựng bằng cách sử dụng tính năng Xuất khẩu trong Eclipse.

Cấu trúc của dự án của tôi trông như thế này:

src/ 
    multiple packages/ 
libs/ 
    jar files and natives 
data/ 
    fonts and images 
config/ 
    json files 

Khi tôi xuất file jar và uzip jar để kiểm tra nội dung của nó, tôi thấy rằng nội dung của các dirs đã được đổ ở cấp cao nhất của .jar.

nào trông như thế này:

.jar 
    packages 
    jar files 
    fonts 
    json files 

Vì vậy, khi tôi cố gắng để tải một tập tin cấu hình với một cái gì đó như:

BufferedReader reader = new BufferedReader(new FileReader(path)); 

mọi thứ hoạt động chỉ nộp khi tôi chạy ứng dụng trong Eclipse. Nhưng tệp jar ném một số FileNotFoundException.

Nhiều câu hỏi tôi đã thấy trên S.O. liên quan đến các vấn đề như thế này, khuyên bạn nên sử dụng class.getClass().getResource() hoặc class.getResourceAsStream(). Tôi đã thử cả hai đường dẫn tương đối sử dụng và chỉ tên tập tin như trong:

class.getResource('config.json'); 
class.getResources('cfg/config.json'); 
class.getResourceAsStream('../../config.json'); 

Tất cả những phương pháp này trả về null, khi chạy từ một trong hai Eclipse hoặc jar sử dụng:

java -jar myjarfile.jar 

Tôi cũng mở để sử dụng tệp Ant. Trong thực tế, bây giờ tôi đang sử dụng tệp Ant được tạo bởi tính năng xuất để tạo jar. Nếu có cái gì đó tôi có thể thêm vào đó để thêm các thư mục vào lọ mà sẽ là tuyệt vời quá.

Trả lời

5

Để truy cập tài nguyên trong thư mục gốc, hãy thêm / vào đường dẫn. Nếu không, bạn làm điều đó liên quan đến gói hiện tại, thường chỉ hữu ích nếu tài nguyên là vật lý bên cạnh lớp trong nguồn của bạn.

Vì vậy, hãy sử dụng class.getResourceAsStream("/config.json"); để truy cập config.json trong thư mục gốc của bình.

Cũng lưu ý rằng các lọ bên trong không được hỗ trợ trực tiếp.

+0

Cảm ơn bạn đã trả lời. Bạn có gợi ý rằng tôi sử dụng dấu gạch chéo phía trước trong một bổ sung cho getResource()? – JeremyFromEarth

+0

Điều này dường như gần hơn. Đây là đường dẫn mà trả về: jar: file:/C: /path_to_project/myjarfile.jar! /config.json Tuy nhiên, khi tôi chạy jar tôi vẫn nhận được một tập tin không ngoại lệ mặc dù đường dẫn là chính xác. Tôi cũng nên đề cập rằng nó hoạt động từ bên trong Eclipse. – JeremyFromEarth

+1

Bạn không thể sử dụng FileReaders với các tài nguyên bên trong các lọ. Bạn phải sử dụng InputStream được trả về từ getResourceAsSTream. –

1

Tệp .jar của bạn chỉ nên bao gồm các thư mục liên quan đến "gói" cho mã được biên dịch. Bạn có thể tham khảo một cấu trúc .war với/lib/WEB-INF vv và điều này là khác nhau.

Nếu cấu trúc gói của bạn là:

com.yourco.authentication 

Và lớp học của bạn tại Đăng nhập

Sau đó jar của bạn nên được

/com/ 
    /yourco/ 
    /authentication/ 
     Login.class 

sau đó bạn cần .jar trong classpath của bạn cho env để chạy qua dòng lệnh.

Tôi thấy bạn lưu ý rằng nó hoạt động trong Eclipse có khả năng có cài đặt môi trường và libs được yêu cầu nhập khẩu, v.v ... rất khó để nói chính xác. Nếu các gói/thư mục của bạn bao gồm mã java đã biên dịch, tôi không chắc liệu nó có hoạt động khi được tham chiếu từ bên ngoài hay không, do đó gợi ý bạn bắt đầu các gói của bạn trong thư mục gốc.

+0

Tôi thấy đề xuất khác với chỉnh sửa mã của bạn để tham khảo /. mà không cần thử nghiệm, nó có thể hoạt động nhưng có vẻ như bạn đang cố gắng đóng gói một ứng dụng chứ không phải là một thư viện với cấu trúc thư mục của bạn. –