2012-06-22 29 views
21

Tôi đã tạo một jar thực thi và sử dụng commons-cli để cung cấp cho người dùng khả năng xác định các tham số dòng lệnh khi khởi chạy máy khách. Mọi thứ đều hoạt động tốt. Tuy nhiên, khi tôi in báo cáo sử dụng cho bình, tôi muốn hiển thị thông tin sau:Lấy tên jar thực thi từ bên trong phương thức main()

usage: java -jar myprog.jar <options> <file> 
--help Display the help message 
--debug Enable debugging 
.... 

In tất cả các tùy chọn dễ dàng thực hiện với commons-cli. Tuy nhiên, đường "sử dụng" là đầu trầy xước. Tôi dường như không thể tìm ra cách để lấy tên "myprog.jar" từ args [] được chuyển tới ứng dụng.

Có cách nào dễ dàng để thực hiện việc này không? Tôi có thể sử dụng một phương pháp khá phức tạp để trở lại dấu vết từ classloader lớp của tôi và tìm ra nếu nó được chứa trong một cái lọ, nhưng điều đó có vẻ như một câu trả lời khá xấu cho những gì nên là một câu hỏi khá đơn giản.

private String getPath(Class cls) { 
    String cn = cls.getName(); 
    String rn = cn.replace('.', '/') + ".class"; 
    String path = 
      getClass().getClassLoader().getResource(rn).getPath(); 
    int ix = path.indexOf("!"); 
    if(ix >= 0) { 
     return path.substring(0, ix); 
    } else { 
     return path; 
    } 
} 
+0

đã thử http://stackoverflow.com/questions/320542/how-to-get-the-path-of-a-running-jar-file?lq=1? – Charles

+0

Tôi đã thấy liên kết đó, nhưng có vẻ như nó gần như là "hack". Tôi không thể tin rằng không có một giải pháp trực tiếp hơn. Ngoài ra, API nói rằng "getCodeSource()" có thể trả về null, nhưng không giải thích theo điều kiện nào, vì vậy tôi tự hỏi liệu đây có phải là phương pháp "không an toàn" để sử dụng hay không. –

Trả lời

33

Ở đây bạn đi:

new java.io.File(SomeClassInYourJar.class.getProtectionDomain() 
    .getCodeSource() 
    .getLocation() 
    .getPath()) 
.getName() 

Edit: tôi thấy nhận xét của bạn về getSourceCode API. Vâng, đây có lẽ là điều tốt nhất bạn có thể làm trong Java. Giới thiệu về getCodeSource() trả lại null, tôi nghĩ điều đó chủ yếu xảy ra ở các lớp học trong java.lang.* và các lớp đặc biệt khác mà vị trí nguồn là "ẩn". Nên làm việc cho các lớp học của riêng bạn mặc dù.

+0

Cảm ơn - đó là điều tương tự mà @Charles đã chỉ ra trong liên kết SO. Mối quan tâm lớn nhất của tôi như tôi đã đề cập ở trên là api cho 'getCodeSource()' chỉ ra rằng nó có thể là null, nhưng không phức tạp trong điều kiện nào. –

+0

Các vấn đề khác với điều này là nó không đưa vào tài khoản thực tế là các tập tin lớp học có thể được lồng trong kho lưu trữ. Vì vậy, tôi vẫn sẽ cần phải kiểm tra một chuỗi con '!'. Như tôi đã nói, có vẻ như một chút vụng về và khá ngạc nhiên khi Java không có giải pháp tốt hơn. –

+0

Chủ yếu là vì hiếm khi có lý do để biết tên của tệp jar bạn đang chạy. Các chức năng nên (lý tưởng) là độc lập với tên. – Charles

Các vấn đề liên quan