Question

I want to add versioning information (and possibly some other metadata about the jar) to a jar of a library I created. However, I am not sure what attribute to use. I found that the specification as well the documentation explain that there can be a Specification-Version and an Implementation-Version (and a title and vendor for both). But neither properly explains what the difference between Specification and Implementation is.

I also looked at different examples.

  • The one from the documentation uses a human readable name for the Specification-Title and a package name for the Implementation-Title. A dot-separated version number is used for the Specification-Version while a simple build number is used for the Implementation-Version.
  • The gradle tutorial seems to just use an Implementation-Version and a human-readable string for the Implementation-Title
  • In another question I found an example in which there were several Implementation-Versions for different packages.

What exactly is the difference between the Specification and Implementation Metadata here? How should these different attributes (especially the version numbers) be used? How does it make sense that the vendor of the specification and the implementation are different?

Does it even play a role what I put in there?

Was it helpful?

Solution

The meaning of each is explained in the documentation of java.lang.Package.

The Specification-Version must consist of sequences of ASCII digits, separated by ASCII periods. No other characters are allowed, periods cannot be at the start or end of the value, and consecutive periods are not allowed.

The Implementation-Version is a free-form string. It can have any format.

Specification-Version is always associated with a package. If you specify it for the entire manifest instead of for a specific package, it applies to all packages in the .jar file.

The Specification-Version is used by a number of Java technologies as a means of resolving dependencies. If some program says it needs, say, version 2.1 or later of the JMF library, some Java environments will analyze the numbers in the Specification-Version of each manifest with a matching Specification-Title, and will make sure that the correct version (and no other version) is available in the classpath at runtime.

In fact, the Package.isCompatibleWith method does that very check. You can even use it to check for a minimum Java version:

if (System.class.getPackage().isCompatibleWith("1.6")) {
    System.out.println("Running in Java 1.6 or later.");
}

Update

The above will not work in a Java 9 modular application. From the documentation for java.lang.Package:

A Package automatically defined for classes in a named module has the following properties:

• The specification and implementation titles, versions, and vendors are unspecified.

A Package automatically defined for classes in an unnamed module has the following properties:

• The specification and implementation titles, versions, and vendors are unspecified.

Java 9 programs running as modules should use ModuleDescriptor.version() instead. Note that the ModuleDescriptor.Version class is Comparable:

Module libraryModule = SomeLibraryClass.class.getModule();
Optional<ModuleDescriptor.Version> libraryVersion =
    libraryModule.getDescriptor().version();

ModuleDescriptor.Version minimumRequiredVersion =
    ModuleDescriptor.Version.parse("2.0");

if (libraryVersion.isPresent() &&
    minimumRequiredVersion.compareTo(libraryVersion.get()) >= 0) {

    System.out.println(libraryModule + " is version " +
        minimumRequiredVersion + " or later.");
}

OTHER TIPS

Well, the specification is your contract, e.g.:

  • a standard such as JAXB, JDBC or one of the various Java EE standards (e.g. EJB 2.x, EJB 3.0, EJB 3.1)
  • the API to your library, framework or service

The implementation is, well, the implementation of that specification.

And while the API of the specification (and thus the specification version) might not change, the implementation version might change as you're fixing bugs etc.

Consider the servlet-api.jar manifest from Apache Tomcat:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.4
Created-By: 1.7.0_40-b43 (Oracle Corporation)
X-Compile-Source-JDK: 1.7
X-Compile-Target-JDK: 1.7

Name: javax/servlet/
Specification-Title: Java API for Servlets
Specification-Version: 3.1
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: javax.servlet
Implementation-Version: 3.1.FR
Implementation-Vendor: Apache Software Foundation

Apache are one of several implementators of the Servlet 3.1 specification defined by the JCP (founded by Sun.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top