maven install lifecycle does not execute validate - maven

I have to install a custom jar during build time, I don't have choice to run deploy file to upload custom jar to central nexus.
The custom jar, does not have any dependencies and is pretty simple
Here is my pom file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-asjava</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.ibm</groupId>
<artifactId>customjar1</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<file>${basedir}/lib/customjar1.jar</file>
<generatePom>true</generatePom>
</configuration>
</execution>
<execution>
<id>install-unijdbc</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.ibm</groupId>
<artifactId>customjar2</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<file>${basedir}/lib/customjar2.jar</file>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
When I run maven validate, these custom jars get installed locally fine, but I want to run install-plugin during install time, I changed phase to install and it fails with error
[WARNING] The POM for com.ibm:customjar1:jar:1.0.0 is missing, no dependency information available
[WARNING] The POM for com.ibm:customjar2:jar:1.0.0 is missing, no dependency information available
I have to always explicitly run validate before running install, I want to get around this problem. Maven documentation says all the phases before a particular gets executed as part of execution cycle, but some how it is not working for me.
Even, this article says the same thing, you need to run validate explicitly to make sure maven install work fine.

This is a bug (or not dependening on your view) that has been closed as Won't Fix:
https://issues.apache.org/jira/browse/MNG-5082
Here is the relevant comment from the bug:
all dependencies which are not part of the reactor should be available at startup of the build, which is required to make a valid buildPlan. So even though this used to work with Maven2, I think the approach of Maven3 is better, since Maven can't detect which plugins will effect the buildPlan at startup. I'd like to close this as Won't Fix.
Doing an install-file during validate means that it'll be execute during every build, installing the same file over and over again. That's also a sign that this approach can't be valid.
What you could try is to turn your project into a multi-module project. The first module simply includes the maven-install-plugin configuration - so all that module does is upload your two custom jars to the local repository. Your 2nd module would then depend on this first module. By the time the 2nd module builds the 1st module will have uploaded the custom jars meaning they should be available.

Related

Install a 3rd-party dependency with maven before dependencies are resolved

I would like to deploy a maven project that depends on a 3rd-party jar, located in a "lib/" directory that is distributed with my project source.
The usual way to do this (as explained in other answers) is to have the user install the jar into a local maven repository before building the project, by typing a command such as mvn install:install-file at the shell.
This manual solution won't do for deployment, however (because requiring users to manually install dependencies is so 1998...). So I thought I'd specify an install-file goal in my pom.xml:
<dependency>
<groupId>edu.my.id</groupId>
<artifactId>myartifact</artifactId>
<version>1.0</version>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-jar-lib</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>edu.my.id</groupId>
<artifactId>myartifact</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<file>${project.basedir}/lib/myartifact.jar</file>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
The problem is that maven attempts to resolve dependencies before install-file runs, even when I specify it to run as early as the validate phase. It thus complains that it cannot find the dependency.
This question has been asked before, and a few unpleasantly complicated solutions have been offered such as these:
Run maven-install-plugin during the clean phase and require users to run mvn clean before building the artifact.
Set up multiple modules, as described here.
Use <systemPath> to load the jar as a system library. (This doesn't meet my requirements, because I am using maven-dependency-plugin to copy dependency jars into the deployed application directory, which ignores system libraries.)
Write a custom plugin.
None of these satisfy me. This seems like a routine task any build system encounters. There must be a simpler way to install dependencies with maven.
The solution that worked for me was to use both install-file and <systemPath>.
<dependency>
<groupId>edu.my.id</groupId>
<artifactId>myartifact</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/myartifact.jar</systemPath>
</dependency>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-jar-lib</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>edu.my.id</groupId>
<artifactId>myartifact</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<file>${project.basedir}/lib/myartifact.jar</file>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
This way, when Maven compiles the project, it resolves the 3rd-party dependency as a system library. But it also installs the library into the local maven repository, so that maven-dependency-plugin's copy-dependencies goal is able to find it.

Setup Intellij to hot update jars and run Maven Appassembler

I want to setup Intellij to automatically do what I am doing from the command-line with maven repeatedly, which is to run mvn package -DskipTests to rebuild my jar and run the Appassembler Maven plugin to produce my runnable scripts. Ideally, all I want it to do is hot update the classes within the jar which I have changed.
I have figured out how to tell Intellij to create jars with the Artifact tab in Project Structure, but can I get Intellij to import this artifact information from the pom instead of me setting it up manually?
It does auto-import pom changes, but never imported this artifact info.
This would enable it to use the exact output name of what maven produces, so that whether I'm working from the command-line or IDE I can work with one set of outputs. (reason below)
Appassembler adds an additional step, which includes it copying all the dependencies into its target folder and producing the scripts. If Intellij can't trigger Appassembler, I was thinking maybe Appassembler could use symlinks instead and the when the jar as updated, my runnable app scripts would immediately be using that version. Or in the worse case, I only need to run this particular step from the command-line, the jar having already been built.
Update
In case it helps, here's how I use Appassembler in my pom.xml:
<build>
<plugins>
<plugin>
<executions>
<execution>
<id>package</id>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<programs>
<program>
<mainClass>com.foo.bar.Foobnobicator</mainClass>
<name>gofoo</name>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</build>
Thanks for the advice on the best way to achieve this.

Xcode Maven Plugin : adding extra headers

The Xcode Maven Plugin from http://sap-production.github.io/xcode-maven-plugin/site is a nice maven plugin for people who like maven and wan't to avoid some pain with xcode dependencies, framework creation and such.
It creates and installs lib and headers in the repository.
The headers are bundled in a .tar file during the process.
For some reason, I need to edit the tar file and add a few files in it before installing.
But as I'm quite the noob regarding maven, I need some help !
How can I modify on a byproduct of Maven before it is installed ? I suppose I can write some script that add some files to the .taf, but how can I be sure it's executed prior the installation ?
#Redwarp - It's been a while since this question was asked, but I'll offer up an answer.
You can configure a Maven plug-in's goal to be executed during a particular phase in the Maven build lifecycle.
Pick a phase that's executed before the install phase. Package may be the best phase for you to edit your tar file and add your required files.
The following is just a generalized example (the focus should be on phase and goal):
<project>
...
<build>
<plugins>
<plugin>
<groupId>com.sap.prd.mobile.ios.mios</groupId>
<artifactId>xcode-maven-plugin</artifactId>
<version>1.12.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>do-something</id>
<phase>package</phase>
<configuration>
...
</configuration>
<goals>
<goal>plugin-goal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Find the plug-ins that suit your needs and bind their goals to the appropriate Maven lifecycle phases...which there's a good chance that you have already figured out by this point.

Installing a file to a Maven repo on the fly

I'm running Maven 3.0.3. I have a JAR that is not part of any online repository. I keep it in lib/quickbase.jar of my project. Ideally, when building to a project, I would like to have this automatically installed to the local repo without having to run a "mvn install:install-file" first. I found this and included it in my pom.xml ...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-quickbase-jar</id>
<phase>compile</phase>
<configuration>
<file>${basedir}/lib/quickbase.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>quickbase</groupId>
<artifactId>quickbase</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
The dependency in my pom is
<dependency>
<groupId>quickbase</groupId>
<artifactId>quickbase</artifactId>
<version>1.0</version>
</dependency>
However, running Maven results in
mvn clean test
...
[ERROR] Failed to execute goal on project didoclient: Could not resolve dependencies for project org.mainco.myco:didoclient:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: quickbase:quickbase:jar:1.0,
Is it possible to have this dependency installed on the fly and if so, how can I adjust the above?
THe best solution is to install this file only once into your local repository (command line mvn install:install-file) but the best solution is to put this into a repository manager and afterwards you can use as a usual dependency.
You could try to change the lifecycle-phase for the install plugin may be generate-sources or earlier like initialize but i assume that this won't work either.

How to execute maven plugin _after_ all module builds finish

Specifically I am trying to run maven-javadoc-plugin but whenever I change the version numbers on the parent/aggregator pom and all of the children, the first time I run the build it fails because javadoc runs first and can't find any of the new version packages from the modules because they haven't been built yet.
I usually end up having to comment javadoc out for one build and then add it back in once the packages are available in nexus for the new version. However, this likely means that I've been building javadoc on one build old source jars all the time.
I've read suggestions of putting another module in that depends on the other ones but I don't think i can get a module to build the javadoc for peer modules. Having it in the parent builds all of the javadoc for all of the modules, I just need it to happen later. Thanks. Here's my javadoc plugin config.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>generate-javadoc</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
<configuration>
<aggregate>true</aggregate>
<links>
<link>http://java.sun.com/javase/6/docs/api</link>
<link>http://java.sun.com/javaee/5/docs/api</link>
</links>
<maxmemory>512</maxmemory>
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
<docletArtifact>
<groupId>org.umlgraph</groupId>
<artifactId>doclet</artifactId>
<version>5.2</version>
</docletArtifact>
<additionalparam>
-inferrel -inferdep -outputencoding utf8 -hide
java.* -collpackages
java.util.*
-qualify -postfixpackage
-nodefontsize 9 -nodefontpackagesize 7
</additionalparam>
</configuration>
</execution>
</executions>
</plugin>
One way to get around this problem is not to invoke javadoc plugin in the normal maven lifecycle phase; instead run it separately.
To be specific, remove <phase> tag from the above plugin definition.
Run mvn install javadoc:javadoc from parent.
This will build and install all the modules and the parent and then run javadoc on them.
Is your javadoc plugin declaration in the <build> part of your pom. You should consider moving it to the <reporting> part see this link.

Resources