2016-07-05 217 views
4

當我準備用於部署的程序時,我將它打包到JAR中,以及Eclipse jar jar-in-jar類裝入器。當我的程序從JAR運行時,我需要知道程序包的版本,但我無法以簡單和「誠實」的方式從jar的清單中獲得它。 清單如下:如何使用Package類的getImplementationVersion()方法從JAR的清單中獲取包版本

Manifest-Version: 1.0 
Created-By: 1.8.0_73-b02 (Oracle Corporation) 
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader 
Rsrc-Main-Class: com.domain.sp2.controller.Controller 
Rsrc-Class-Path: ./ jar-in-jar-loader.zip javahelp-2.0.05.jar json-simple-1.1.1.jar 
Class-Path: . 

Name: com/domain/sp2/controller/ 
Implementation-Version: 19 

爲了獲得包的實現版本,我嘗試用最簡單和直接的方式:

package com.domain.sp2.controller; 
public class Controller { 
... 
    public static String getBuildNumber() throws IOException { 
    Package pckg = Controller.class.getPackage(); 
    pr(pckg.getName()); // prints "com.domain.sp2.controller", as expected 
    return pckg.getImplementationVersion(); // returns null 
    } 
... 
} 

根據http://docs.oracle.com/javase/tutorial/deployment/jar/packageman.htmlhttp://docs.oracle.com/javase/8/docs/api/java/lang/Package.html#getImplementationVersion--(和其他來源)它應該返回「19」,但它返回null。對於JRE庫的包,它會返回正確的值。也許我錯過了關於如何在清單中命名軟件包的細節,或者原因與JarRsrcLoader有關 - 可能需要一些特殊的語法來解決軟件包。我也試過".com/domain/...","/com/domain/..."".../controller",甚至"rsrc:./com/domain..."作爲清單中的包名稱 - 都沒有成功。我可以使用其他方式,例如將清單加載爲流並使用Manifest類進行解析,但是我想了解使用方法的正確方法是什麼。

+0

這有一個答案[here](http://stackoverflow.com/questions/33553570/how-to-read-meta-data-from-manifest-file)已經 – SomeDude

+0

是的,我敢肯定。我在JAR中看到了它在正確的位置(.META-INF /)贏得了一個開放的目光,我可以通過編程方式閱讀它(包括Implementaion-Version)。我只是不想加載清單並解析它,當getImplementationVersion()存在時。 –

+0

@svasa,這不是我的問題的答案。我沒有問清楚如何閱讀清單。我的問題是「如何使用getImplementationVersion()方法」。我應該更清楚地表達這個問題。我會編輯它。 –

回答

3

你可以閱讀從類加載器清單文件並獲得您需要如下價值:

URLClassLoader cl = (URLClassLoader) YOUR_CLASS.class.getClassLoader(); 
try { 
    URL url = cl.findResource("META-INF/MANIFEST.MF"); 
    Manifest manifest = new Manifest(url.openStream()); 
    Attributes mainAttributes = manifest.getMainAttributes(); 
    String implVersion = mainAttributes.getValue("Implementation-Version"); 

    System.out.println(implVersion); 
} catch (IOException E) { 
     // handle 
} 
+0

是的,我可以閱讀清單(正如我在問題中提到的),但**我想知道關於getImplementationVersion()**方法。爲什麼它不能爲我正常工作?儘管如此,謝謝你的迴應。 –

1

解決了!至少對我來說:)你需要確定,所涉及的軟件包只能在一個JAR中找到,並且JAR具有正確的清單。

有意義,因爲您查詢某個版本的軟件包以及JVM應該返回什麼,如果該軟件包存在於所有具有不同或部分未設置的實現版本的許多JAR中?

+0

但是我不明白我的JAR /代碼有什麼問題。該包只在一個罐子裏(對我來說這是一個JAR)。清單看起來不錯,至少我沒有看到任何不好的地方(它在原文中被引用)。儘管如此,'getName()'返回正確的名稱,'getImplementationVersion()'返回'null'。 Java 7和8,x32和x64,Windows。 –

1

我在eclipse中遇到了同樣的問題。 問題來自Eclipse jar jar-in-jar類加載器。簡單地說,不要在jar方法中使用包中的外部庫來生成jar,而是使用解壓縮外部庫到你的jar而不是方法,它應該可以工作。