2013-10-13 3 views
5

을 읽을 수 있습니다. 따라서 .jar가 유효한지 확인하려면 mainfest 파일의 일부 값을 확인하십시오. java를 사용하여 파일을 읽고 파싱하는 가장 좋은 방법은 무엇입니까? 나는 파일Java를 사용하여 .jar 매니페스트 파일

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

를 추출하려면이 명령을 사용하여 생각하지만 난 그냥 같은 것을 수행 할 수 있습니다

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

그런 다음 파일의 라인을 구문 분석하는 일부 버퍼 리더 또는 무언가를 사용을? 어떤 도움

감사합니다 ...

+0

의 가능한 중복 http://stackoverflow.com/questions/2198525/can-values-defined-in-manifest-mf-be-accessed-programmatically/2198542 –

답변

8

jar 도구를 사용의 문제는 설치 될 전체 JDK를 필요로한다는 것이다. 많은 Java 사용자는 jar을 포함하지 않는 JRE 만 설치합니다.

또한 jar은 사용자의 PATH에 있어야합니다.

그래서 대신 내가 다음과 같이 적절한 API를 사용하는 것이 좋습니다 :

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

것은 실제로 쉽게해야한다고!

+0

와우, 그건 더 의미가 있습니다. 나도 Command.exec ("jar를 추출하는 코드")를 사용하고 있습니다. 그것도 쉽게 할 수있는 방법이 있습니까? – Kyle

+0

예. 그러나 이미 Stackoverflow에 관한 질문이 있어야합니다. –

+0

지금까지 명령 프롬프트를 사용하고 있지만이 링크는 작동하지만 찾을 수있었습니다. 왜 jarfile.run() 같은 것일까? http://www.programcreek.com/2012/08/unzip-a-jar-file-in-java-program/ – Kyle

4

의 패키지 클래스 java.lang.Package에는 원하는 것을 수행하는 방법이 있습니다.

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

내가 공유 유틸리티 class.The 방법에 정적 메서드에이를 넣어 매개 변수로 클래스 핸들 객체는 받아 들인다 : 여기에 귀하의 자바 코드를 사용하여 매니페스트 내용을 얻을 수있는 가장 쉬운 방법입니다. 이렇게하면 시스템의 모든 클래스가 필요할 때마다 자체적 인 정보를 얻을 수 있습니다. 당연히 메소드는 값의 배열 또는 해시 맵을 반환하도록 쉽게 수정 될 수 있습니다.

호출 방법 :

String ver = GeneralUtils.checkImplVersion(this); 

GeneralUtils.java라는 파일의 방법

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

그리고 당신이 패키지를 통해 얻을 수있는 것 이외의 매니페스트 필드 - 값을 얻을 수 클래스 (예 : 자신의 빌드 - 날짜), 당신은 주요 Attibutes를 얻고 그들을 통해 일하고, 당신이 원하는 특정 것을 요구합니다. 이 다음 코드는 내가 찾은 유사한 질문의 약간의 모드입니다. 아마도 여기에 있습니다. (나는 그것을 신용하고 싶지만 미안하다.)

이것을 try-catch 블록에 넣고 classHandle ("this"또는 MyClass.class)을 메서드에 전달한다. "classHandle는"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

패키지 메소드의 경우, java.util.jar.Attributes.Name 클래스에있는 올바른 이름 (예 : "Implementation-Version")을 사용하여 Manifest에 정의해야합니다. 이것은 특별히 잘 설명되어 있지 않습니다. –

0

가장 쉬운 방법은 JarURLConnection를 클래스를 사용하는 것입니다

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); 

경우에 ...class.getProtectionDomain().getCodeSource().getLocation();vfs:/와 경로를 제공하므로이 추가로 처리해야하기 때문에

.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); 
} 
관련 문제