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.");
}