จะตรวจสอบเวอร์ชันของไฟล์ jar ได้อย่างไร?


92

ฉันกำลังทำงานกับแอปพลิเคชันภาษาโปแลนด์ J2ME เพียงแค่ปรับปรุง ฉันพบปัญหาในการรับไฟล์ jar เวอร์ชันที่แน่นอน มีวิธีใดในการค้นหาเวอร์ชันของไฟล์ jar สำหรับการนำเข้าที่ทำในคลาสหรือไม่ ฉันหมายถึงถ้าคุณมีบางอย่างให้นำเข้า xyz; เราสามารถทราบเวอร์ชันของ jar xy package ได้หรือไม่?

คำตอบ:


79

ขยายไฟล์ JAR และค้นหาไฟล์ manifest ( META-INF\MANIFEST.MF) ไฟล์รายการของไฟล์ JAR อาจมีหมายเลขเวอร์ชัน (แต่ไม่ได้ระบุเวอร์ชันเสมอไป)


อย่างที่ฉันบอกว่าฉันกำลังปรับปรุงแอปพลิเคชันฉันได้ดาวน์โหลดไฟล์ jar และฉันรู้เวอร์ชันของไฟล์ jar แต่ฉันต้องการทราบรุ่นของขวดที่เป็นของแพคเกจฉันหวังว่าคุณจะได้รับมัน
Ritesh Mengji

เพื่ออธิบายเพิ่มเติมฉันมีการนำเข้า xyz ฉันรู้ว่า xy เป็นของ a-4.1.jar แต่แอปพลิเคชันที่ฉันใช้งานได้รับการพัฒนามานานแล้วและฉันไม่ได้ใช้ไฟล์ a.jar เวอร์ชันใดฉัน กำลังกังวลเกี่ยวกับรุ่นเพราะบางส่วนของชั้นเรียนที่ได้รับการตัดค่าเสื่อมราคาจากขวดรุ่นเก่า (ผมรู้สึก) เพราะถึงแม้ว่าผมมีขวดในห้องสมุดผมพบการนำเข้าไม่สามารถแก้ไขได้
Ritesh Mengji

ดังนั้นถ้าคุณรู้เวอร์ชันของ jar ที่พวกเขาใช้ในขณะสร้างแอปพลิเคชันคุณจะใช้ jar เวอร์ชันเดียวกันเพื่อเรียกใช้แอปพลิเคชันด้วยหรือไม่?
วิเวก

1
หากนั่นคือความต้องการของคุณฉันกลัวว่าคุณจะต้องสร้างแอปพลิเคชันใหม่โดยไม่รวมขวดโหลที่เลิกใช้แล้ว เนื่องจากการค้นหาหมายเลขเวอร์ชันที่เชื่อมโยงกับ jar ที่กำหนดเป็นเหมือนฟังก์ชันหนึ่งต่อหนึ่ง หมายเลขเวอร์ชันเดียวสำหรับไฟล์ jar หนึ่งไฟล์ แต่การค้นหาว่าใช้ jar เวอร์ชันใดในช่วงเวลาของการพัฒนาแอปพลิเคชันนั้นฟังดูเป็นไปไม่ได้อย่างมากสำหรับฉันเว้นแต่ผู้พัฒนาจะแนบขวดที่จำเป็นกับแอปพลิเคชัน
Vivek

1
เวอร์ชันการบันทึกใน MANIFEST.MF ดูเหมือนจะเป็นทางเลือก ไม่มีเวอร์ชันที่บันทึกไว้ในsqljdbc42.jarไฟล์ต่างๆที่ฉันเคยใช้กับ Cognos แต่ Cognos สามารถรายงานเวอร์ชัน (4.2.6420.100) ได้ จะได้รับเวอร์ชันนี้มาจากที่ใดหากไม่ได้บันทึกไว้ในไฟล์ Manifest
Nick.McD mermaid

54

คุณต้องเปิดเครื่องรูดและตรวจสอบMETA-INF/MANIFEST.MFไฟล์เช่น

unzip -p file.jar | head

หรือเฉพาะเจาะจงมากขึ้น:

unzip -p file.jar META-INF/MANIFEST.MF

27

เพียงเพื่อขยายคำตอบด้านบนภายในไฟล์ META-INF / MANIFEST.MF ใน JAR คุณจะเห็นบรรทัด: Manifest-Version: 1.0 ←นี่ไม่ใช่หมายเลขเวอร์ชัน jar!

คุณต้องค้นหาImplementation-Versionว่าหากมีอยู่จะเป็นสตริงข้อความอิสระซึ่งขึ้นอยู่กับผู้เขียน JAR ว่าคุณจะพบอะไรในนั้น ดูข้อมูลเฉพาะของOracle docsและPackage Version


คำตอบนี้ (และอื่น ๆ ) กำลังพูดถึงใน Meta
Thomas Weller

17

เพียงเพื่อให้คำตอบข้างต้นสมบูรณ์

ไฟล์ Manifest อยู่ภายใน jar ที่ META-INF\MANIFEST.MF path

คุณสามารถตรวจสอบเนื้อหาของ jar ใน archiver ใดก็ได้ที่รองรับ zip


2
คำตอบนี้ (และอื่น ๆ ) มีการกล่าวถึงใน Meta
Thomas Weller

11

โถแต่ละรุ่นมีการตรวจสอบที่ไม่ซ้ำกัน คุณสามารถคำนวณ checksum สำหรับ jar ของคุณ (ที่ไม่มีข้อมูลเวอร์ชัน) และเปรียบเทียบกับ jar เวอร์ชันต่างๆ นอกจากนี้เรายังสามารถค้นหา jar โดยใช้ checksum

อ้างถึงคำถามนี้เพื่อคำนวณการตรวจสอบ: อะไรคือวิธีที่ดีที่สุดในการคำนวณการตรวจสอบสำหรับไฟล์ที่อยู่ในเครื่องของฉัน


5
ฉันเพิ่งคำนวณ jar md5 และวางลงใน google ทำงานได้ดีขอบคุณมาก!
mik01aj

8

โดยทั่วไปคุณควรใช้java.lang.Packageคลาสที่ใช้ classloader เพื่อให้ข้อมูลเกี่ยวกับคลาสของคุณ

ตัวอย่าง:

String.class.getPackage().getImplementationVersion();
Package.getPackage(this).getImplementationVersion();
Package.getPackage("java.lang.String").getImplementationVersion();

ฉันคิดว่าการบันทึกกลับเป็นที่รู้กันว่าใช้คุณลักษณะนี้เพื่อติดตามชื่อ JAR / เวอร์ชันของแต่ละคลาสใน stacktraces ที่สร้างขึ้น

โปรดดูที่http://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90779


3

โปรแกรมง่ายๆนี้จะแสดงรายการทั้งหมดสำหรับเวอร์ชั่นของ jar คือ

  • พบเวอร์ชันในไฟล์ Manifest
  • ไม่พบเวอร์ชันใน Manifest และแม้แต่จากชื่อ jar
  • ไม่พบไฟล์ Manifest

    Map<String, String> jarsWithVersionFound   = new LinkedHashMap<String, String>();
    List<String> jarsWithNoManifest     = new LinkedList<String>();
    List<String> jarsWithNoVersionFound = new LinkedList<String>();
    
    //loop through the files in lib folder
    //pick a jar one by one and getVersion()
    //print in console..save to file(?)..maybe later
    
    File[] files = new File("path_to_jar_folder").listFiles();
    
    for(File file : files)
    {
        String fileName = file.getName();
    
    
        try
        {
            String jarVersion = new Jar(file).getVersion();
    
            if(jarVersion == null)
                jarsWithNoVersionFound.add(fileName);
            else
                jarsWithVersionFound.put(fileName, jarVersion);
    
        }
        catch(Exception ex)
        {
            jarsWithNoManifest.add(fileName);
        }
    }
    
    System.out.println("******* JARs with versions found *******");
    for(Entry<String, String> jarName : jarsWithVersionFound.entrySet())
        System.out.println(jarName.getKey() + " : " + jarName.getValue());
    
    System.out.println("\n \n ******* JARs with no versions found *******");
    for(String jarName : jarsWithNoVersionFound)
        System.out.println(jarName);
    
    System.out.println("\n \n ******* JARs with no manifest found *******");
    for(String jarName : jarsWithNoManifest)
        System.out.println(jarName);
    

ใช้ jar javaxt-core ซึ่งสามารถดาวน์โหลดได้จากhttp://www.javaxt.com/downloads/


ขอบคุณสำหรับการอ้างอิงถึง javaxt ฉันเพิ่งใช้ตัวอย่างโค้ดที่ง่ายกว่าที่นั่นจากjavaxt.com/Tutorials/Jar/…
David

1
FYI สำหรับผู้ที่ชอบ maven เพื่อดึง javaxt-core แทนที่จะดาวน์โหลด JAR คุณสามารถใช้วิธีใดวิธีหนึ่งต่อไปนี้: gist.github.com/daluu/dda7b29cb5b6e0fbfbaec664eb759739 , gist.github.com/daluu/52af7eef52563ddf78fe
David

2

ฉันมาช้า แต่คุณสามารถลองสองวิธีต่อไปนี้

โดยใช้คลาสที่จำเป็นเหล่านี้

import java.util.jar.Attributes;
import java.util.jar.Manifest;

วิธีการเหล่านี้ช่วยให้ฉันเข้าถึงคุณลักษณะ jar ฉันชอบที่จะเข้ากันได้แบบย้อนหลังและใช้เวอร์ชันล่าสุด ก็เลยใช้ตัวนี้

public Attributes detectClassBuildInfoAttributes(Class sourceClass) throws MalformedURLException, IOException {
    String className = sourceClass.getSimpleName() + ".class";
    String classPath = sourceClass.getResource(className).toString();
    if (!classPath.startsWith("jar")) {
      // Class not from JAR
      return null;
    }
    String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + 
        "/META-INF/MANIFEST.MF";
    Manifest manifest = new Manifest(new URL(manifestPath).openStream());
    return manifest.getEntries().get("Build-Info");
}

public String retrieveClassInfoAttribute(Class sourceClass, String attributeName) throws MalformedURLException, IOException {
    Attributes version_attr = detectClassBuildInfoAttributes(sourceClass);

    String attribute = version_attr.getValue(attributeName);

    return attribute;
}

สิ่งนี้ใช้ได้ดีเมื่อคุณใช้ maven และต้องการรายละเอียด pom สำหรับคลาสที่รู้จัก หวังว่านี่จะช่วยได้


1

สำหรับ Linux ให้ลองทำตาม:

หา. - ชื่อ "YOUR_JAR_FILE.jar" -exec zipgrep "เวอร์ชันการใช้งาน:" '{}' \; | awk -F ':' '{พิมพ์ $ 2}'


1

ถ้าคุณมี WinRAR เปิดขวดด้วย WinRAR, META-INFดับเบิลคลิกเพื่อเปิดโฟลเดอร์ แยกMANIFEST.MFและCHANGESไฟล์ไปยังตำแหน่งใด ๆ (เช่นเดสก์ท็อป)

เปิดไฟล์ที่แยกออกมาในโปรแกรมแก้ไขข้อความ: คุณจะเห็น Implementation-Version หรือ release version


0

คุณสามารถกรองเวอร์ชันจากไฟล์ MANIFEST โดยใช้

unzip -p my.jar META-INF/MANIFEST.MF | grep 'Bundle-Version'


นี้ดูเหมือนว่าจะส่วนใหญ่ซ้ำกันนี้คำตอบเก่า - stackoverflow.com/a/38313502/272387 - Bundle-Versionและแสดงออกไม่ได้รับประกันว่าจะมี
Richlv

0

คิดว่าฉันจะให้คำตอบที่เร็วกว่านี้เนื่องจากคำถามนี้ยังคงมีการค้นหาค่อนข้างสูง

การตรวจสอบเวอร์ชัน CLi JAR:

เรียกใช้สิ่งต่อไปนี้บนไฟล์ CLi jar:

unzip -p jenkins-cli.jar META-INF/MANIFEST.MF

ตัวอย่างผลลัพธ์:

Manifest-Version: 1.0
Built-By: kohsuke
Jenkins-CLI-Version: 2.210  <--- Jenkins CLI Version
Created-By: Apache Maven 3.6.1
Build-Jdk: 1.8.0_144
Main-Class: hudson.cli.CLI

เวอร์ชัน CLi อยู่ในรายการด้านบน

ในการรับเวอร์ชันเซิร์ฟเวอร์ให้รันสิ่งต่อไปนี้:

java -jar ./jenkins-cli.jar -s https://<Server_URL> -auth <email>@<domain>.com:<API Token> version

(ข้างต้นจะแตกต่างกันไปขึ้นอยู่กับการดำเนินการตรวจสอบสิทธิ์ของคุณโปรดเปลี่ยนตาม)

ตัวอย่างผลลัพธ์:

Dec 23, 2019 4:42:55 PM org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar getOrCreateProvider
INFO: getOrCreateProvider(EdDSA) created instance of net.i2p.crypto.eddsa.EdDSASecurityProvider
2.210  <-- Jenkins Server Version

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.