Maven Jar requires two execution contexts - maven

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>

Related

Maven - How to extract a dependency inside another ZIP dependency?

I have a maven project.
Inside that project, I have a .zip dependency that carries a jar and I need to extract that jar out of the zip dependency and have maven use the jar as a dependency. I can currently download and unpack the zip but, cannot figure out a way to add the unpacked jar as a dependency for the project during the build process.
Here is what I'm currently doing for unpacking:
<dependency>
<groupId>com.bar</groupId>
<artifactId>foo</artifactId>
<version>${foo.version}</version>
<type>zip</type>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>validate</phase>
<configuration>
<includeGroupIds>com.bar</includeGroupIds>
<includeArtifactIds>foo</includeArtifactIds>
<outputDirectory>${basedir}/target</outputDirectory>
<type>jar</type>
</configuration>
</execution>
</executions>
</plugin>
I read up on some other posts that you could try adding the jar to the class path using this.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
Even doing so I was still unable to reference the packages in foo.jar in my project.
Can someone help me?
For maven to use it without subtly breaking stuff elsewhere, you must install the jar into your local repository.
I would suppose that a combination of unpacking the zip file in target/ and then invoking install:install-file on the resulting jar could do what you need. I asked some years back how to integrate that in a normal build - you might find the answer relevant. Multiple install:install-file in a single pom.xml
Let's assume that, after unpacking the zip, you have foo.jar in your module's target folder: ${project.build.directory}/foo.jar
Having this in place, you can then declare a System Dependency pointing to that jar, e.g.
<dependency>
<groupId>foo</groupId>
<artifactId>foo.jar</artifactId>
<systemPath>${project.build.directory}/foo.jar</systemPath>
</dependency>
Tip: if you dont want to delete/re-download the jar each time you do a clean (some IDE will complain the the jar is not always present) just download it once in the ${project.basedir}.
To download the jar once, you can put your "unpack" execution in a profile that gets activated only when the jar is missing.
<profiles>
<profile>
<activation>
<file>
<missing>${project.basedir}/foo.jar</missing>
</file>
</activation>
...
</profile>
</profiles>
Some time ago, I've faced the same problem. I had a zip file as my dependency, and during the build process I need to extract it and separate the content inside my generated package.
I don't know what are you using to deliver your project, but at that time I've used the maven-antrun-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>2.6</version>
</plugin>
With this, I've used the tag unzip inside my target configuration. As you can see here or here. I just don't recommend you to use the task tag as they're using, you'd better prefer the target tag.
Hope it helps you.

how to exclude jar file from getting installed using maven-install-plugin?

I have a jar file created using maven-jar-plugin.
Is there a way to skip this jar file from getting installed in repository?
Thanks in advance.
Try this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
The reason this works is that the install plugin's only job is to take your artifact(s) and install them in your local repo.
In Maven, there are main artifacts and attached artifacts. I am not sure if you can suppress installation of the main artifact and only install the attached artifact, since assemblies are not required to provide a POM.
If this is what you really want to achieve, I would suggest breaking out the assembly to a separate artifact (with <packaging>pom</packaging>), have it depend on the jar-artifact you are trying to exclude and simply install that.

Sharing variables with child maven projects

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

Why would a maven-war-plugin generate a JAR instead of a WAR?

I am following this Contract first using CXF tutorial and while the resulting pom.xml generates sources and even completes build successfully, it fails to create a WAR file.
Instead, it creates a JAR file.
My understanding is that the part in the pom.xml that's responsible for creating the WAR is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<outputDirectory>D:/path/to/profile/autodeploy</outputDirectory>
</configuration>
</plugin>
I don't see any <goal> or <execution> element there (unlike in the build-helper-maven-plugin one), but I also understand that with this plugin this is implied as even the official usage page demonstrates:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
So... what am I missing?
What could possibly explain a maven-war-plugin that behaves in unexpected way like this and produces a JAR instead of a WAR by default?
Is there a way to force it to produce a WAR?
packaging should be as below.
<packaging>war</packaging>
if it won't help then try binding your plug-in configuration with a lifecycle phase.
in your project definition , please check if packaging is missing or not , it should be some thing like this .
<groupId>some.groupid</groupId>
<artifactId>My Web Application</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<description>My First Web Application</description>
By default maven war plugin binds to package phase of the lifecycle ,so its important that we should mention the type of packaging we want once the build is done.
I would like to suggest to have a look at the Maven specs for war plugin.

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