Adding more stuff to META-INF/MANIFEST.MF in jars created by Pants

530 views
Skip to first unread message

Eric Zundel Ayers

unread,
Mar 30, 2015, 6:16:58 PM3/30/15
to pants-devel

We have some code that reads some information that I believe comes out of Manifest.MF, specifically, the Implementation-Version: field

Here is a manifest generated by our Maven builder:

Manifest-Version: 1.0
Implementation-Title: foo-service
Implementation-Version: 4adca25a3e0a8faf686833e8cd4879e9607f4f8d
Archiver-Version: Plexus Archiver
Built-By: zundel
Implementation-Build: 4adca25a3e0a8faf686833e8cd4879e9607f4f8d
Implementation-Vendor-Id: com.example.foo
Created-By: Apache Maven 3.1.1
Build-Jdk: 1.8.0_25
Main-Class: com.example.foo.FooService

Here are the fields that current come out of the pants build:

Manifest-Version: 1.0
Created-By: com.twitter.common.jar.tool.JarBuilder
Main-Class: com.squareup.pants.SpyPantsApp

I am shaving some yaks right now on my way to updating jar_task.py to be able to set more of these fields.

I think I could meet my need by just hard coding the setting of Implementation-Build to be the git sha but I was wondering if anyone wanted more flexibility than this. One thought I had was to be
able to configure the manifest in a jvm_binary() target using a new attribute that takes a dictionary.

jvm_binary(name='foo-service',
  main="com.example.foo.FooService',
  manifest={
    "Implementation-Version": '%git_sha',  # could also be '%provides_version' to read from the 'provides` version or a hard-coded string
    "Implementation-Build": 'git',
    "Created-by" : <whatever string you like>,
    "Implementation-Vendor-Id": <whatever string you like>, # or maybe `%provides_org`
    "Built-By": <way to get the user id in a BUILD file?>,
  }

Thoughts?

Stu Hood

unread,
Mar 30, 2015, 7:02:55 PM3/30/15
to Eric Zundel Ayers, pants-devel
FWIW, we have a task internally that puts this type of information in library-specific properties files on the classpath, since it doesn't really have anything to with "jars", and would get destroyed when people fatjar their app anyway.

Eric Zundel Ayers

unread,
Mar 30, 2015, 7:15:47 PM3/30/15
to Stu Hood, pants-devel
The example is a manifest from a fat jar.  That's where I want it to land, anyway.  Many of these are standard fields in the manifest specification at: http://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html


Main Attributes

Main attributes are the attributes that are present in the main section of the manifest. They fall into the following different groups:
  • general main attributes
    • Manifest-Version: Defines the manifest file version. The value is a legitimate version number, as described in the above spec.
    • Created-By: Defines the version and the vendor of the java implementation on top of which this manifest file is generated. This attribute is generated by the jar tool.
    • Signature-Version: Defines the signature version of the jar file. The value should be a valid version-number string.
    • Class-Path: The value of this attribute specifies the relative URLs of the extensions or libraries that this application or extension needs. URLs are separated by one or more spaces. The application or extension class loader uses the value of this attribute to construct its internal search path. See the Class-Path Attributesection for details.
  • attribute defined for stand-alone applications: This attribute is used by stand-alone applications that are bundled into executable jar files which can be invoked by the java runtime directly by running "java -jar x.jar".
    • Main-Class: The value of this attribute is the class name of the main application class which the launcher will load at startup time. The value must not have the .class extension appended to the class name.
  • attributes defined for applets: Deprecated: These attributes and the mechanism which implements it may be removed in a future release. These attributes are used by an applet which is bundled into JAR files to define requirements, version and location information for the extensions which this applet depends on. (seeExtension Versioning ).
    • Extension-List: This attribute indicates the extensions that are needed by the applet. Each extension listed in this attribute will have a set of additional attributes that the applet uses to specify which version and vendor of the extension it requires.
    • <extension>-Extension-Name: This attribute is the unique name of the extension. The Java Plug-in will compare the value of this attribute with the Extension-Name attribute in the manifests of installed extensions to determine if the extension is installed.
    • <extension>-Specification-Version: This attribute specifies the minimum extension specification version that is required by the applet. The Java Plug-in will compare the value of this attribute with the Specification-Version attribute of the installed extension to determine if the extension is up to date.
    • <extension>-Implementation-Version: This attritute specifies the minimum extension implementation version number that is required by the applet. The Java Plug-in will compare the value of this attribute with the Implementation-Version attribute of the installed extension to see if a more recent implementation needs to be downloaded.
    • <extension>-Implementation-Vendor-Id: This attribute can be used to identify the vendor of an extension implementation if the applet requires an implementation from a specific vendor. The Java Plug-in will compare the value of this attribute with the Implementation-Vendor-Id attribute of the installed extension.
    • <extension>-Implementation-URL: This attribute specifies a URL that can be used to obtain the most recent version of the extension if the required version is not already installed.
  • attribute defined for extension identification: This attribute is used by extensions to define their unique identity.
    • Extension-Name: This attribute specifies a name for the extension contained in the Jar file. The name should be a unique identifier such as the name of the main package comprising the extension.
  • attributes defined for extension and  package versioning  and sealing information: These attributes define features of the extension which the JAR file is a part of. The value of these attributes apply to all the packages in the JAR file, but can be overridden by per-entry attributes.
    • Implementation-Title: The value is a string that defines the title of the extension implementation.
    • Implementation-Version: The value is a string that defines the version of the extension implementation.
    • Implementation-Vendor: The value is a string that defines the organization that maintains the extension implementation.
    • Implementation-Vendor-Id: Deprecated: This attribute may be ignored in a future release. The value is a string id that uniquely defines the organization that maintains the  extension implementation.
    • Implementation-URL: Deprecated: This attribute may be ignored in a future release. This attribute defines the URL from which the extension implementation can be downloaded from.
    • Specification-Title: The value is a string that defines the title of the extension specification.
    • Specification-Version: The value is a string that defines the version of the extension specification.
    • Specification-Vendor: The value is a string that defines the organization that maintains the extension specification.
    • Sealed: This attribute defines whether this JAR file is sealed or not. The value can be either "true" or "false", case is ignored. If it is set to "true", then all the packages in the JAR file are defaulted to be sealed, unless they are defined otherwise individually.

John Sirois

unread,
Mar 30, 2015, 8:45:41 PM3/30/15
to Eric Zundel Ayers, Stu Hood, pants-devel
On Mon, Mar 30, 2015 at 5:15 PM, Eric Zundel Ayers <zun...@squareup.com> wrote:
The example is a manifest from a fat jar.  That's where I want it to land, anyway.  Many of these are standard fields in the manifest specification at: http://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html

Allowing a dict of custom manifest attributes to be specified in the BUILD makes sense to me, but on the lower JvmTarget level.  I should be able to specify these for published thin jars (JavaLibrary, ScalaLibrary) or JvmBinaries.
Baby steps are fine of course, but that seems like the logical endpoint to me.

The Twitter case Stu refers to embeds a root build.properties resource in binaries with much the same info presumably for much the same purpose (standard servers read the resource and export these "variables" on a monitoring endpoint).

Stu Hood

unread,
Mar 30, 2015, 8:53:43 PM3/30/15
to John Sirois, Eric Zundel Ayers, pants-devel
The Twitter case Stu refers to embeds a root build.properties resource in binaries with much the same info presumably for much the same purpose (standard servers read the resource and export these "variables" on a monitoring endpoint).
It additionally does it for libraries now, at a namespaced location based on the provides clause... this allows (for example), finagle to publish a jar and consume the resulting properties file regardless of who is consuming them.
Reply all
Reply to author
Forward
0 new messages