28

I'm wondering if it is possible to retrieve, in runtime, a version number of a jar from which the class comes from?

I know its possible to find jar from which the class comes from:

MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();

but what about a version?

(assuming its not in the file name:) )

Ashot Karakhanyan
  • 2,804
  • 3
  • 23
  • 28
zibi
  • 3,183
  • 3
  • 27
  • 47
  • 1
    Jars don't have versions. –  Feb 12 '14 at 09:52
  • yes, you are right, version belong to library version but in slang it's 'take jar version x.y.z' – 1ac0 Feb 12 '14 at 09:55
  • 4
    s.getClass().getPackage().getImplementationVersion() - could be null in Java 8. – Iakov Senatov Nov 09 '18 at 08:12
  • to include implementation version in manifest, you have to modify the configuration element of the maven-jar-plugin and set addDefaultImplementationEntries and addDefaultSpecificationEntries to true. This will fix s.getClass().getPackage().getImplementationVersion() become null – Isuru Hemantha Jul 31 '23 at 03:06

3 Answers3

29

Try this, it may be helpful:

String s = new String();
System.out.println(s.getClass().getPackage().getSpecificationVersion());
System.out.println(s.getClass().getPackage().getImplementationVersion());

Output:

1.7
1.7.0_25
Idos
  • 15,053
  • 14
  • 60
  • 75
Shekhar Khairnar
  • 2,643
  • 3
  • 26
  • 44
26
import javax.mail.internet.InternetAddress;

/**
Display package name and version information for javax.mail.internet.
*/
public final class ReadVersion {
  public static void main(String... aArgs){
    ReadVersion readVersion = new ReadVersion();
    readVersion.readVersionInfoInManifest();
  }

  public void readVersionInfoInManifest(){
    InternetAddress object = new InternetAddress();
    Package objPackage = object.getClass().getPackage();
    //examine the package object 
    String name = objPackage.getSpecificationTitle();
    String version = objPackage.getSpecificationVersion();
    //some jars may use 'Implementation Version' entries in the manifest instead
    System.out.println("Package name: " + name);
    System.out.println("Package version: " + version);
  }
}
1ac0
  • 2,875
  • 3
  • 33
  • 47
  • If you're using maven to build the JAR, `objPackage.getSpecificationVersion()` might give 'null' as the version. to fix that, refer: https://stackoverflow.com/questions/2712970/get-maven-artifact-version-at-runtime – Isuru Hemantha Jul 31 '23 at 03:08
6

Be careful using getPackage().getImplementationVersion/getSpecificationVersion()

getSpecificationVersion returns specVersion from Manifest. Manifest is a property of a jar and is used in sun.misc.URLClassPath as

  public Manifest getManifest() throws IOException {
                    SharedSecrets.javaUtilJarAccess().ensureInitialization(JarLoader.this.jar);
                    return JarLoader.this.jar.getManifest();
                }

So in case somebody use your library as dependency for fat jar, it returns the version of Manifest for fat jar.

olga
  • 61
  • 1
  • 1
  • 2
    You have just highlighted an important reason not to make fat jars: it wipes out individual libraries’ manifest information. – VGR Nov 20 '19 at 14:57