Difficulty deploying second artifact with Maven - maven

A mavenized version of an old project of mine creates two Jar files, one for command line and one for GUI use. As it currently stands, it deploys only the primary artifact to the local repository. The jars are created by having two executions for maven-jar-plugin, and both get created in the target directory. What happens is the GUI file overwrites the primary one, with the wrong name:
[INFO] Installing /Users/gmcgath/DevProjects/git/jhove/target/jhove-GUI-1.12.0-SNAPSHOT.jar to /Users/gmcgath/.m2/repository/edu/harvard/hul/ois/jhove/1.12.0-SNAPSHOT/jhove-1.12.0-SNAPSHOT.jar
I'm trying to use the build-helper plugin to get the GUI jar deployed to the repository, using the following:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.artifactId}-GUI-${project.version}</file>
<type>jar</type>
<classifier>gui</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
Maven runs to completion without any errors, but doesn't copy the jar properly. The log tells me it's trying to copy the GUI jar from the project-level directory instead of the target to the correct destination. The GUI file is still overwriting the primary jar.
[INFO] Installing /Users/gmcgath/DevProjects/git/jhove/jhove-GUI-1.12.0-SNAPSHOT to /Users/gmcgath/.m2/repository/edu/harvard/hul/ois/jhove/1.12.0-SNAPSHOT/jhove-1.12.0-SNAPSHOT-gui.jar
(The "harvard" part is historical. Keeping this open-source project was part of my severance package. :)
So I'm doing something basically wrong. How can I fix this? Should I be using the assembly plugin instead, even though it looks more complicated?
Update: Partially fixed. The file element in the artifact needs to be
<file>${project.build.directory}/${project.artifactId}-GUI-${project.version}.jar</file>
I'm still looking for the fix to get the primary artifact copied correctly.

OK, here's my fix. The first part, as indicated above, was to get the directory and extension right in the build-helper artifact. It should have been
<file>${project.build.directory}/${project.artifactId}-GUI-${project.version}.jar</file>
The other issue was in a part of the pom.xml that I didn't post. The two executions lacked a classifier element, and so looked like this:
<executions>
<execution>
<!-- console app - don't change id, will cause build problems -->
<id>default-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<classifier>cmd</classifier>
<archive>
<manifest>
<mainClass>Jhove</mainClass>
</manifest>
</archive>
</configuration>
</execution>
<execution>
<id>gui-app-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<classifier>gui</classifier>
<archive>
<manifest>
<mainClass>JhoveView</mainClass>
</manifest>
</archive>
<finalName>${project.artifactId}-GUI-${project.version}</finalName>
</configuration>
</execution>
</executions>
Everything looks OK now.

Related

Simple Java Mail dependencies not in the jar file

I used simplejavamail in my maven project. The program can send out the email if I run it from Intellij IDE. But when I create a jar file, and run it from the jar file, then I got class not found for all the simplejavamail classes. And I open the jar, I find out that they are not included in the jar. But all the other dependency classes are there. Any one have meet this issue before?
parts of my pom.xml
<dependency>
<groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId>
<version>6.4.3</version>
</dependency>
<build>
<finalName>my-project-name</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I'm having the same problem. It appears that the dependencies (Ex. Email, Mailer, EmailBuilder, etc) appear in the org.simplejavamail.api repository. I'll update you if I find a working solution with v6.4.3 but I have a feeling we may need to include additional dependencies.
Edit: To at least patch your problem,
<dependency>
<groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId>
<version>5.5.1</version>
</dependency>
The 5.5.1 version still has the classes in the jar. You can reference this for yourself here:
https://www.javadoc.io/doc/org.simplejavamail/simple-java-mail/5.5.1/index.html
Then click on the different versions to see what classes exist.
I think something went wrong in their builds since v6.
Let me know if this helps!

how to generate additional jar which having correct and complete manifest file for Bamboo deployment?

Basically, I want to generate a jar file named <project.name>.jar in addition to default jar file(which in my case is something like <project.name> + <project.version>.jar). NOTICE : This <project.name>.jar is all the same to default jar but the name.
And this additional jar should have a manifest file like below which is the manifest file of default generated jar
anifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: XXX
Start-Class: com.XXXX.XXX.Application
Spring-Boot-Version: 1.3.1.RELEASE
Created-By: Apache Maven
Build-Jdk: 1.8.0_74
Main-Class: org.springframework.boot.loader.JarLauncher
I am adding additional block in my as follows
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
....
<execution>
<id>copy-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</execution>
<execution>
</plugin>
But in my case, the manifest file generated in my addition jar don't have following impart fields:
Start-Class
Main-Class
...
So it couldn't be deployed.
I know the requirement sounds weird, but the question is clear, how to make maven generate a jar which having a correct and complete manifest file for deployment?
//The complete plugin part
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals><goal>test-jar</goal></goals>
</execution>
<execution>
<id>copy-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<finalName>${project.artifactId}</finalName>
</configuration>
</execution>
<execution>
<id>dto-jar</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<finalName>${project.artifactId}-dto</finalName>
<includes>
<include>**/dto/*</include>
<include>**/dto</include>
<include>**/exceptions/*</include>
<include>**/exceptions</include>
<include>**/utils/*</include>
<include>**/utils</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Concerning your maven-jar-plugin section:
You are having three executions: one for the test-jar goal, two for the jar goal
one of them re-using the default execution id (default-jar) to specify the finalName entry, but not specifying any manifest configuration. According to this configuration, your manifest file should also be empty then, not coherent with the description provided by your question then.
the additional jar goal execution has a further configuration with customizated option, nothing wrong here, except that you except to have a properly filled manifest file as part of it, while (again) there is no configuration for it.
A possible explanation would be that your pom also provides a pluginManagement section, with further configuration for the maven-jar-plugin, or a parent pom at its top which would then specify a further configuration for the same.
To double check this, you could run
mvn help:effective-pom -Doutput=eff-pom.xml
And check the content of the generated eff-pom.xml file. That would be the single source of truth for your case.
Looking at your manifest entry:
Spring-Boot-Version: 1.3.1.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
It makes quite clear that you are working on a Spring Boot project, normally having a Spring Boot parent pom which already configures the required manifest file. However, it makes use of a fat-jar (jar with dependencies or uber jar), not built via the maven-jar-plugin but via the maven-assembly-plugin.
As an example:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.JarLauncher</mainClass>
</manifest>
<manifestEntries>
<Start-Class>org.springframework.boot.load.it.jar.EmbeddedJarStarter</Start-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Hence you should not look at the Jar Plugin solution, but rather add a further Assembly Plugin execution for the same.
Just quick share of some other aspects of this problem. actually pom file should never be in charge of deployment business(even though It could, but very likely bring into more issues in the future). This part should be fully managed by bamboo deploy script. That is what I eventually did.

How add local dependecy in assembly JAR

I have a multimodule Maven project with several dependencies. I want to build a fat executable JAR containing them as well as my own compiled classes. I found maven-assembly-plugin to be just what I needed except one nasty problem.
Some of my dependencies are local and distributed with project sources. I use system scope for them. It looks something like this:
<dependency>
<groupId>com.intellij</groupId>
<artifactId>forms_rt</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/forms_rt.jar</systemPath>
</dependency>
The problem is that for some reason these libraries aren't unpacked and bundled with the rest of dependencies in result JAR.
I know that usage of system scope is considered bad practice, and in fact I even can find some of them (though quite outdated) in Maven repositories, but anyway it puzzles me how it can be solved with maven-assembly-plugin.
Just in case my plugin configuration looks like this:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>repoll.server.Repoll</mainClass>
</manifest>
</archive>
<finalName>${project.build.finalName}-full</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
As I understood I have to write custom descriptor, which e.g. includes and unpacks all JARs from ${project.basedir}/lib directory, but after several unsuccessful attempts I still don't know how to do so.
I've managed to find solution here. It's described in this question.
In short, the whole problem was in usage of system scope. It turned out, that such dependencies are filtered out by default, which I found out by running mvn package with debug output enabled (-X/--debug).
When local repository is defined for these JARs, distributed with project, they are unpacked by maven-assembly-plugin as exepected.

Maven issue with buildnumber:hgchangeset properties not propagating to children

I have a multi-module project which uses the buildnumber:hgchangeset plugin to generate changeSet and changeSetDate properties, which then get blatted out into the manifest for each module, like so:
pom.xml (parent):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>hgchangeset</goal>
</goals>
</execution>
</executions>
</plugin>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<ProjectVestion>${project.version}</ProjectVestion>
<ChangeSet>${changeSet}</ChangeSet>
<ChangeSetDate>${changeSetDate}</ChangeSetDate>
</manifestEntries>
</archive>
</configuration>
</plugin>
After a bit of experimentation, I discovered that having buildnumber:hgchangeset execute for each module contributed a significant amount of time to the overall build time, presumably because it's forking hg.exe every time it needs to get the changeset ID of the local repo.
I then thought it would be a good idea to set the inherited property to false on the buildnumber plugin, in order to only have it run once for the parent. Unfortunantly, doing this causes the changeSet and changeSetDate properties to not be "visible" to the child modules.
My question is: is it possible to set things up in such a way that buildnumber:hgchangeset runs only once, but the properties that it sets become visible to children modules?
I suppose alternatively I could write things out to a property file, and have each module read it back in, but this does not seem like idiomatic Maven to me.
Thanks in advance,

NetBeans - how to set default startup Maven module in multi-module maven project?

I'm looking for the way to configure Netbeans workspace for multi-module maven project to always start some module when pressing CTRL+F5 (Debug main project). Being within maven project this shortcut always starts the project whose source file is currently being open. This is annoying - to start debugger i always have to either switch to some source file from the 'main' module or find that module in project explorer (huge sub-tree) and right click -> Debug (both are regular useless waste of time )
Similar question is about re-running last unit test - i can't find shortcut for this, but i see related bug report is not addressed since Aug 2010: http://netbeans.org/bugzilla/show_bug.cgi?id=189113.
You have to put that action specified in the nbactions.xml like:
<action>
<actionName>debug</actionName>
<packagings>
<packaging>jar</packaging>
</packagings>
<goals>
<goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
</goals>
<properties>
<jpda.listen>maven</jpda.listen>
<exec.args>-classpath %classpath com.domain.package.Main start</exec.args>
<exec.executable>java</exec.executable>
<exec.workingdir>./content</exec.workingdir>
</properties>
</action>
So it will excecute the Main file in a module of your proyect.
If you want to excecute a Main java file of a dependency project you must include this plugin entry:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</plugin>
This will allow your maven project to copy all dependencies you need to your target during packaging phase. Then use this other plugin entry for making the Main class you need accessible:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.domain.package.Main</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
You may change the folder where dependency jars will be or even make it a property in the pom.xml of your parent maven project.

Resources