Sharing variables with child maven projects - maven

I have a parent pom.xml which builds a series of modules. As part of the parent pom.xml I read a configuration and put a number of variables into the build environment:
BUILD_DATE=2014/07/24 15\:37\:06
BUILD_NUMBER=78
VERSION=GGY1.6
I wish to place this information into the manifest jar file. I am doing this as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<finalName>atf</finalName>
<archive>
<manifestEntries>
<Built-Date>${maven.build.timestamp}</Built-Date>
<Version>${VERSION}B${BUILD_NUMBER}</Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
I am not sure which section of the pom.xml this should go into. I have put it in the build phase, and in some modules this works out ok, but in others it comes out in the manifest as:
Created-By: Apache Maven 3.0.5
Built-Date: 28/07/2014-16:00
Version: ${VERSION}B${BUILD_NUMBER}
Archiver-Version: Plexus Archiver
Is there a specific place in the pom.xml I need to put the maven-jar-plugin in order for it to pick up variables created by the parent?

I think the missing piece in the modules pom.xml files was this:
<plugin><groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
</plugin>
Any module pom which had this piece added, populated the manifest correctly... along with the maven-jar-plugin snippet. It looks like both are needed in order to access the values set by the parent pom.xml

Related

Maven: Three Jars in one project. Trying to use an assembly, but not getting pom.xml and pom.properties embedded in the jars

I have a project that produces three different jar files:
Server.jar: This contains all classes and resources. A standard jar
Client.jar: This contains only a few external classes and no resources.
ServerSDK.jar: This contains all the classes, resources, test classes, and other configuration files.
I've decided to do all three jars in a single project, so a change in any of the sources spawns a Jenkins build and deploys all three at once. I build the Server.jar as my standard pom.xml jar. Then, I use assemblies to build the Client.jar and the ServerSDK.jar.
I have the assemblies that build the other two jars, and everything is 99% of the way I like it, but there is bit of munging I'd like to do.
We add a few entries in our MANIFEST.MF file to incorporate the Jenkins build information and project information.
In a standard Maven jar, the pom.xml and pom.properties are embedded in the META-INF directory.
The first one I have managed to do via the <assembly> configuration in my maven-assembly-plugin. The second one I can't seem to get to work even though I have <addMavenDescriptor> set to true in my <assembly> configuration.
Here's my maven-assembly-plugin section in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<manifestSections>
<manifestSection>
<name>Build-Information</name>
<manifestEntries>
<Project-Name>${env.JOB_NAME}</Project-Name>
<Build-Number>${env.BUILD_NUMBER}</Build-Number>
<SVN-Revision>${env.SVN_REVISION}</SVN-Revision>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>Module-Information</name>
<manifestEntries>
<Group-ID>${project.groupId}</Group-ID>
<Artifact-ID>${project.artifactId}</Artifact-ID>
<Version>${project.version}</Version>
</manifestEntries>
</manifestSection>
</manifestSections>
</archive>
</configuration>
<executions>
<execution>
<id>Client</id>
<configuration>
<finalName>Client</finalName>
<appendAssemblyId>true</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/client.xml</descriptor>
</descriptors>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
The <manifestSections> work just fine, but the <addMavenDescriptor> doesn't seem to be working although I've explicitly set it to true.
According to the documentation on the maven-archiver-plugin:
Whether the created archive will contain these two Maven files:
The pom file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.xml
A pom.properties file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.properties
The default value is true.
According the maven-assembly-plugin page:
<archive>
This is a set of instructions to the archive builder, especially for building .jar files. It enables you to specify a Manifest file for the jar, in addition to other options. See Maven Archiver Reference
Is there something simple I'm missing here?
The Maven Assembly Plugin actually ignores the addMavenDescriptor parameter, and will never include the Maven descriptor in the resulting assembly. This can be seen in the source code: only the META-INF/MANIFEST.MF file is possibly added to the JAR archive.
I couldn't find an existing JIRA issue about this, so I went ahead and created MASSEMBLY-835 to track this.
A work-around for now would be to add the files yourself in the assembly descriptor:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>client</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>pom.xml</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
</file>
<file>
<source>${project.build.directory}/maven-archiver/pom.properties</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
</file>
</files>
<!-- rest of your configuration -->
</assembly>
This adds a <files> configuration that adds the pom.xml and the generated pom.properties into the target directory.
Note that the pom.properties is generated by the Maven Archiver component during the default package goal into the target/maven-archiver directory; therefore, in order for it to be present when making your assembly, the Assembly Plugin has to be bound to the phase package (or later in the lifecycle), and the current Maven project needs to be of packaging JAR / WAR / EAR / EJB / RAR... but not POM which doesn't package an archive. The primary artifact of the Maven project also needs to be built (if you skip the generation of the primary JAR of a JAR project, the pom.properties won't be generated).
This works in a large majority of cases. But if you want a bullet-proof solution, you can just create the file yourself. Create a pom.properties somewhere in your project (example, base directory) with the following content:
#Generated by Apache Maven ${maven.version}
version=${project.version}
groupId=${project.groupId}
artifactId=${project.artifactId}
and in the previous assembly descriptor, have instead:
<file>
<source>pom.properties</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
<filtered>true</filtered>
</file>
This would correctly replace the placeholders inside the pom.properties that was created, and mimic what Maven Archiver would do.

Maven Jar requires two execution contexts

I need to be able to allow my maven package to be executed in two contexts.
User needs to execute jar from the command line to generate a licence key from an AWT dialog that appears when the user executes java -jar myjar.jar
myjar needs to also download all its transitive dependencies (in the "normal" maven way) when a client project references myjar as a dependency.
Scenario 1 requires the AWT forms jar to be packaged so that the AWT dialog pops up.
Scenario 2 requires all the other dependencies to be downloaded as the client project builds.
How do I package this to keep it as small as possible?
I've tried the jar-plugin, the shade-plugin and the assembly-plugin independently without much luck.
JAR-PLUGIN:
Placing the forms-1.2.1.jar in the lib/ directory and adding it to the classpath doesn't work because java -jar myjar.jar will not load it at the commandline
SHADE-PLUGIN:
Downloads the internet. How to exclude some dependencies?
ASSEMBLY-PLUGIN:
Downloads the internet. How to exclude some dependencies?
Is there a way to package the transitive dependencies of forms-1.2.1.jar (for scenario 1) but exclude all other dependencies at packaging time so they are downloaded at client project build time (for scenario 2).
Can the jar-plugin or assembly-plugin do this?
What you think about the following:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default.
-->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
[...]
</project>
That will produce a jar file which contains all dependencies and make it possible to call it from command line, but to get it working correctly you need a supplemental part:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.2</version>
<configuration>
[...]
<archive>
<manifest>
<mainClass>org.sample.App</mainClass>
</manifest>
</archive>
</configuration>
[...]
</plugin>
[...]
</project>

Jenkins maven plugin alters manifest

I am using Jenkins ver. 1.521 and standard maven plugin (ver 1.519) to build maven2 projects.
In manifest I can see entries I didn't configure in any of pom files:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: jenkins
Build-Jdk: 1.6.0_45
Hudson-Build-Number: ...
Hudson-Project: ...
Hudson-Version: ...
Jenkins-Build-Number: ..
Jenkins-Project: ...
Jenkins-Version: ...
Where can I configure these entries?
I don't know of any default behavior like that. Typically this is configured in the build section of your pom. Are you sure it isn't coming from an ancestor pom somewhere?
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Build-Job>${JOB_NAME}</Build-Job>
<Build-Id>${BUILD_ID}</Build-Id>
<Build-Number>${BUILD_NUMBER}</Build-Number>
<Build-Repository-Rev>${SVN_REVISION}</Build-Repository-Rev>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
In this example the child XML elements of manifestEntries are created based on the element names. Their can come from Maven properties, e.g. maven.build.timestamp, or environment variables, e.g. JOB_NAME. The environment variables JOB_NAME, BUILD_ID, etc are set by Jenkins when it executes the job.
Actually, I have found them hardcoded in source of maven plugin for jenkins, which is a sad thing.

Maven: How to relase an artifact without any project specific settings like parent pom or scm?

i have the task to build an artifact of an application that should be shipped to a customer. The artifact is a client-jar that can be used to access an ejb-application on a server.
As it is build out of a multi-module project, the artifact's pom contains the reference to a parent pom and scm information that should not be shipped to the customer.
Is there a maven way to remove those information or, in case of the parent pom, to resolve the parent pom and include its data in the client-jar's pom directly.
The customers will not have access to our intern maven repository.
You can remove all information from META-INF, see:
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
</plugins>
And you can use maven assembly plugin (or shade) to build jar file with all dependencies.

How to add libs to Classpath in my manifest file via maven?

I using Maven 3 + hudson + artifacotory
I used the following
<artifactId>maven-war-plugin</artifactId> <addClasspath>true</addClasspath> <classpathPrefix>WEB-INF/lib/</classpathPrefix> </manifest>
and I got the result as.....
WEB-INF/lib/gwt-servlet-2.4.0.jar WEB-INF/lib/gwt-user-2.4
.0.jar WEB-INF/lib/validation-api-1.0.0.GA.jar WEB-INF/lib/validation
-api-1.0.0.GA-sources.jar WEB-INF/lib/log4j-1.2.16.jar WEB-INF/lib/co
mmons-lang-2.6.jar
I am find well and good.
My one more requirement is,
I need to add/append two more libs with the above manifest file. see below
/u01/app/TimesTen/tt1121/lib/orai18n.jar /u01/app/TimesTen/tt1121/lib/ttjdbc5.jar
So how can add/append this is to my Manifest, so that above 3 will be included?
maven war plugin as well as maven jar plugin use maven archiver which in turn allows you to specify your own manifest file. According to the documentation,
The content of your own manifest file will be merged with the entries
generated by Maven Archiver.
Cut/pasting the relevant pom snippet from the above link for ready reference
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
...
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
...
</project>
So you could add the additional entries in this custom MANIFEST.MF and use it in conjunction with the maven war plugin.

Resources