2013-10-13 13 views
5

vì vậy tôi đang cố gắng xem liệu một .jar có hợp lệ hay không, bằng cách kiểm tra một số giá trị trong tệp mainfest. Cách tốt nhất để đọc và phân tích cú pháp tệp bằng java là gì? Tôi nghĩ đến việc sử dụng lệnh này để trích xuất các tập tinSử dụng Java để đọc tệp kê khai .jar

jar -xvf anyjar.jar META-INF/MANIFEST.MF 

Nhưng tôi có thể chỉ cần làm điều gì đó như:

File manifest = Command.exec("jar -xvf anyjar.jar META-INF/MAINFEST.MF"); 

Sau đó, sử dụng một số độc giả đệm hoặc một cái gì đó để phân tích các dòng của tập tin?

Nhờ sự giúp đỡ ...

+0

có thể trùng lặp của http://stackoverflow.com/questions/2198525/can-values-defined-in-manifest-mf-be-accessed-programmatically/2198542 –

Trả lời

8

Vấn đề với việc sử dụng các công cụ jar là nó đòi hỏi đầy đủ JDK được cài đặt. Nhiều người dùng Java sẽ chỉ cài đặt JRE, không bao gồm jar.

Ngoài ra, jar sẽ phải nằm trên PATH của người dùng.

Vì vậy, thay vào đó tôi sẽ khuyên bạn nên sử dụng API thích hợp, như thế này:

Manifest m = new JarFile("anyjar.jar").getManifest(); 

Đó thực sự cần được dễ dàng hơn!

+0

Oh wow có ý nghĩa hơn. Chờ đợi vì vậy tôi cũng đang sử dụng một Command.exec ("mã chiết xuất jar"). Có cách nào dễ dàng hơn để làm điều đó không. – Kyle

+0

Có. Nhưng phải có một câu hỏi về điều đó trên Stackoverflow. –

+0

Cho đến nay tôi sẽ có thể tìm thấy là sử dụng dấu nhắc lệnh nhưng liên kết này có vẻ như nó sẽ làm việc nhưng có vẻ lol phức tạp. Tại sao nó không đơn giản như jarfile.run() hay gì đó. http://www.programcreek.com/2012/08/unzip-a-jar-file-in-java-program/ – Kyle

4

Lớp gói tại java.lang.Package có các phương pháp để thực hiện những gì bạn muốn. Dưới đây là một cách dễ dàng để có được nội dung biểu hiện sử dụng mã java của bạn:

String t = this.getClass().getPackage().getImplementationTitle(); 
String v = this.getClass().getPackage().getImplementationVersion(); 

tôi đặt này thành một phương pháp tĩnh trong một phương pháp hữu ích class.The chia sẻ chấp nhận một đối tượng lớp xử lý như một tham số. Bằng cách này, bất kỳ lớp nào trong hệ thống của chúng tôi đều có thể nhận được thông tin biểu hiện của riêng họ khi họ cần. Rõ ràng là phương pháp có thể dễ dàng sửa đổi để trả lại một mảng hoặc hashmap của các giá trị.

gọi phương pháp:

String ver = GeneralUtils.checkImplVersion(this); 

phương pháp trong một tập tin gọi là GeneralUtils.java:

public static String checkImplVersion(Object classHandle) 
{ 
    String v = classHandle.getClass().getPackage().getImplementationVersion(); 
    return v; 
} 

Và để có được biểu hiện các lĩnh vực-giá trị khác hơn là những người bạn có thể nhận được thông qua gói class (ví dụ Build-Date của riêng bạn), bạn có được Attibutes chính và làm việc thông qua những người đó, yêu cầu một người cụ thể mà bạn muốn. Mã sau đây là một mod nhỏ từ một câu hỏi tương tự tôi tìm thấy, có lẽ ở đây trên SO. (Tôi muốn ghi nhận nó nhưng tôi đã mất nó - xin lỗi.)

đặt điều này trong một khối try-catch, chuyển trong một classHandle ("this" hoặc MyClass.class) vào phương thức. "ClassHandle" là loại Class:

String buildDateToReturn = null; 
    try 
    { 
    String path = classHandle.getProtectionDomain().getCodeSource().getLocation().getPath(); 
    JarFile jar = new JarFile(path); // or can give a File handle 
    Manifest mf = jar.getManifest(); 
    final Attributes mattr = mf.getMainAttributes(); 
    LOGGER.trace(" --- getBuildDate: " 
      +"\n\t path:  "+ path 
      +"\n\t jar:  "+ jar.getName() 
      +"\n\t manifest: "+ mf.getClass().getSimpleName() 
      ); 

    for (Object key : mattr.keySet()) 
    { 
     String val = mattr.getValue((Name)key); 
     if (key != null && (key.toString()).contains("Build-Date")) 
     { 
      buildDateToReturn = val; 
     } 
    } 
    } 
    catch (IOException e) 
    { ... } 

    return buildDateToReturn; 
+0

Đối với các phương thức Gói, chúng phải được xác định trong Tệp kê khai sử dụng tên chính xác (.e.g. "Phiên bản thực hiện"), được tìm thấy trong lớp java.util.jar.Attributes.Name. Đây không phải là tài liệu đặc biệt tốt. –

0

Cách đơn giản nhất là sử dụng JarURLConnection lớp:

String className = getClass().getSimpleName() + ".class"; 
String classPath = getClass().getResource(className).toString(); 
if (!classPath.startsWith("jar")) { 
    return DEFAULT_PROPERTY_VALUE; 
} 

URL url = new URL(classPath); 
JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); 
Manifest manifest = jarConnection.getManifest(); 
Attributes attributes = manifest.getMainAttributes(); 
return attributes.getValue(PROPERTY_NAME); 

Bởi vì trong một số trường hợp ...class.getProtectionDomain().getCodeSource().getLocation(); cho con đường với vfs:/, vì vậy đây cần được xử lý bổ sung.

Hoặc, với ProtectionDomain:

File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()); 
if (file.isFile()) { 
    JarFile jarFile = new JarFile(file); 
    Manifest manifest = jarFile.getManifest(); 
    Attributes attributes = manifest.getMainAttributes(); 
    return attributes.getValue(PROPERTY_NAME); 
} 
Các vấn đề liên quan