Use local jar as artifact in maven dependency plugin? - java

We have a maven project in which we use some artifacts that are not present in any remote repositories. They are included in our project in some directory, say /lib, as compiled .jar files. Some of these are "plain" dependencies which we can utilize from /lib using scope system + systemPath, however there is one artifact that should be used with the maven-dependency-plugin unpack goal. The relevant part of the pom.xml looks like this
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>xxx.yyy.zzz</groupId>
<artifactId>ourartifact</artifactId>
<outputDirectory>${target.directory}/somedir</outputDirectory>
<includes>
files1/**,files2/**,files3/**
</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
However this still tries to reach out to the remote repository and fetch the artifact from there, which of course does not succeed. Can we somehow achieve that this artifact is also attempted to be fetched from /lib?

Instead of fetching from /lib, and if setting up your own Nexus/Artifactory/etc... is a bit much right now, you could add the jar to your local repository. Each individual would have to do this on their own computer, but once there, it would be available to all the maven built projects on that machine, so you wouldn't have to have a /lib copy for each project. If you are compiling that jar yourself and it is a maven project, you can do "mvn install" and that will install to your local repo. Note that mvn package won't install to your local repo.
If this is a 3rd party jar, you can use mvn install:install-file to do this. To do this, follow the instructions at https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html .
Hope this helps!
Update: by local repository, I might mean differently than you referred to in your comment -- I mean the local repository on each user's computer, versus a repository server that is local to your intranet. Sorry if that caused any confusion :)

Related

Maven project packaging is war but also building/installing jar

I have a Maven 3.3 project, and the main output is a war file:
<artifactId>pro</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
I am using the maven plugin to also build a jar file, which goes into target/pro-1.0-SNAPSHOT.jar and this works.
I would like to install this jar to the local maven repo, so I'm using the maven install plugin to do this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<classifier>jar</classifier>
<packaging>jar</packaging>
<file>target/pro-1.0-SNAPSHOT.jar</file>
</configuration>
<executions>
<execution>
<id>do-jar-install</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
The whole build works fine except the jar install step is installing the war, and not the jar. How do I override this?
I'm looking here to see what I can use: http://maven.apache.org/plugins/maven-install-plugin/examples/installing-secondary-artifacts.html
Here is the log from my build:
**
Building jar: /Users/mike/code/workspace/pro/target/pro-1.0-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.5.2:install (do-jar-install) # pro
[INFO] Installing /Users/mike/code/workspace/pro/target/pro-1.0-SNAPSHOT.jar to /Users/mike/.m2/repository/net/mikeski/pro/1.0-SNAPSHOT/pro-1.0-SNAPSHOT.war
Note the last line - it's picking up the jar but installing a war
How can I fix that?
As requested, here is the jar plugin config:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>create-jar</id>
<phase>install</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
It creates a jar of the files in the project, and it's the correct jar. If I copy the war that is installed in my repo to a jar (so I just change the extension) my other project can pick it up just fine.
Your current output is the result of multiple considerations, one of them being maven-jar-plugin too permissive in version 2.4.
First of all, you need to remember that inside a Maven repository, all the artifacts share a single naming convention, which is artifactId-version(-classifier).packaging. This means that whatever the local name of the file your build is producing (let it be foo.jar), it will be installed and it will be deployed with this conventional name. All that matters when artifacts are installed are the Maven coordinates, i.e. the groupId, the artifactId, the version, the classifier and the packaging.
What is happening here is:
Your project has a packaging war. Running Maven with mvn install, the default-install phase will be invoked first and the maven-install-plugin:install goal will be run a first time, installing your WAR project. On your logs, you will find:
[INFO] --- maven-install-plugin:2.5.2:install (default-install) # test-war ---
[INFO] Installing ...\test-war\target\test-war-0.0.1-SNAPSHOT.war to ...\test-war\0.0.1-SNAPSHOT\test-war-0.0.1-SNAPSHOT.war
[INFO] Installing ...\test-war\pom.xml to ...\test-war\0.0.1-SNAPSHOT\test-war-0.0.1-SNAPSHOT.pom
Then, you are using the maven-jar-plugin:jar goal to create a JAR. This plugin creates a JAR for the current Maven project - so it will create it alright, but the Maven coordinates of this new artifact will be exactly the same as those of your WAR project (you didn't specify a classifier). Therefore, you effectively replace the file of the main artifact (which is a WAR), by a JAR file: you end up with a local file having an extension of jar (because the maven-jar-plugin created it this way) that is the file of the main artifact of a Maven project of packaging war. Quite confusing.
Remember that I said that the maven-jar-plugin was too permissive? If you update to version 3.0.2 of the plugin, you will get an error right here (MJAR-198):
You have to use a classifier to attach supplemental artifacts to the project instead of replacing them. -> [Help 1]
which summarizes what is said above.
Finally, you declared another execution of the maven-install-plugin called do-jar-install, that is supposed to install this local JAR file. And this is what it does: it installs the local JAR file inside your target folder to your local Maven repository using the coordinates of the artifact. The confusion comes from the fact that the type (packaging) of the artifact is in fact WAR, so what gets installed is a WAR file (being effectively a JAR)...
Now that we've explained the issue, the question is: what do you want to do? It looks like you want to attach to your WAR project an additional artifact composed of the classes of it. There is no need for all this configuration, you can just use the attachClasses parameter of the maven-war-plugin.
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
You received this because double invocation of plugin :
execution phase
package - default phase
If there is no strong reason and all you care is to have just one JAR as artifact from the project, use one among them.
something like :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<outputDirectory>${outputDirectory}</outputDirectory>
</configuration>
</plugin>

generate checksum and store the MD5 files is specified folder using maven

I know that the below command will generate checksum using maven,
mvn clean install -DcreateChecksum=true
Above Maven command generate the checksum and MD5 files are stored in the .m2 repository.
I want the MD5 files to be saved in the specified directory. We can provide the below plugin details in pom.xml,
<project>
...
<build>
<plugins>
<plugin>
<groupId>net.ju-n.maven.plugins</groupId>
<artifactId>checksum-maven-plugin</artifactId>
<version>1.3-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>artifacts</goal>
</goals>
</execution>
</executions>
<configuration>
<csvSummary>true</csvSummary>
<csvSummaryFile>artifacts-checksums.csv</csvSummaryFile>
<xmlSummary>true</xmlSummary>
<xmlSummaryFile>artifacts-checksums.xml</xmlSummaryFile>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
But I can't add the plugin in pom.xml. It looks like mvn clean install -DcreateChecksum=true seems to be easier for me, but it generates MD5 files in .m2 repository.
Is there any way to pass the location as Maven argument?
You are doing two different things here.
Configuring checksum-maven-plugin to calculate the checksums
Using the createChecksum attribute of the maven-install-plugin.
createChecksum, being a property of maven-install-plugin, will install the checksums inside your local repository and there's no way around that.
If you can't modify your POM, you could still call the checksum-maven-plugin. The checksums will be located inside the target folder.
mvn clean install net.ju-n.maven.plugins:checksum-maven-plugin:1.2:artifacts

maven properties-maven-plugin doesn't work when deploying artifact to Nexus

I am using properties-maven-plugin to read a external property file under root dir to maintain the version of parent module since there are quite a number of sub-modules in my project and the dependency tree is kinda deep.
It works fine when I build locally and install the artifacts into local repo but got the 401 error when I try to use "mvn clean deploy" to publish them to Nexus. I am pretty sure this is caused by the ineligible artifact name(releaseurl/{external.version}), external.version is supposed to be the property read from the external file. However, it ended up not being read and it just worked fine when I explicitly declare the version in the project.parent.version tag. Any thoughts or workaround? or even how you handle the version control when trying to use same version for parent and child in all the modules when dealing with a multi-module porject.
The maven pom for the plugin is as below, I saw some comments online regarding the phase, not sure if it will work if change initialize to something else:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>external-file.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>

Get sources of a snapshot dependency on Eclipse

Something bother me a lot...
On a big project with many dependencies, some of them are set as SNAPSHOT in Maven2.
The matter is that it seems i can't get the sources through Eclipse without loading the project or fixing the dependency to the last release.
For debugging, it's really annoying me...
EDIT
This is what i get in eclipse maven console:
26/08/10 11:31:46 CEST: Downloading http://repo-maven/archiva/repository/snapshots/com/blabla/1.1-SNAPSHOT/blabla-1.1-20100824.213711-80-javadoc.jar
26/08/10 11:31:47 CEST: Could not download sources for com.blabla:blabla:1.1-20100824.213711-80
On archiva i can see the deployed stuff i want to retrieve in eclipse...
Repository snapshots
Group ID com.blabla
Artifact ID blabla
Version 1.1-20100824.213711-80
Packaging jar
Parent com.blabla bla 1.1-SNAPSHOT (View)
Other Versions 1.1-20100824.213535-79
I can download sources of this artifact with my browser but not within Eclipse... Any idea?
The matter is that it seems I can't get the sources through Eclipse without loading the project or fixing the dependency to the last release. For debugging, it's really annoying me...
Well, these modules are probably not publishing source JARs as part of the "regular" build process (i.e. outside the release). If these modules are under your control (which is my understanding), configuring the Maven Source Plugin to produce source JARs for them and deploying them in your corporate repo should solve the problem. From the Usage page:
Installing the sources along with your artifact
There are two ways to do this. You can
either bind this plugin to a phase or
you can add it to a profile. The goals
source:jar-no-fork and
source:test-jar-no-fork are preferred
for binding the goal to the build
lifecycle.
Installing the sources using a phase binding
Here is how you would configure the
plugin in your pom.xml to run
automatically during the verify phase:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
We are using the verify phase here
because it is the phase that comes
before the install phase, thus making
sure that the sources jar has been
created before the install takes
place.
Installing the sources using a profile
If you want to install a jar of your
sources along with your artifact
during the release process, you can
add this to your pom.xml file:
<project>
...
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
</project>
Using a profile would probably be a good idea so that building source JARs will only be done by the build running at the CI server level but not on developer machines.

Can Maven collect all the dependent JARs for a project to help with application deployment?

I'm just starting to use Maven, (evaluating it, really) and I need to be able to quickly generate a JAR file for my application and a directory with all the dependencies (for example, lib) so that I can deploy those two to be run in a stand-alone manner. Generating the JAR file with the proper manifest is easy, but I do not know how to get Maven to copy the dependencies for the current project into a lib directory that I can deploy.
Since this is for a stand-alone Java applications, I am not interested in deploying to a Maven repository, that is also fairly trivial, or at least easily googleable.
I've found out how to do everything except copy the dependent JAR files into some specified directory. This is the workflow I'm looking for:
$ mvn clean
$ mvn package
$ cp -r target/{lib,myApp.jar} installLocation
Then, running myApp.jar from installLocation as a JAR file should "just work" regardless of my $CLASSPATH.
To try and pre-empt some answers:
I do have a Main-class: set, and it works fine.
I've also set the classpath in the MANIFEST.MF, and that works fine too.
I've found out how to use <classpathPrefix> and <classpathMavenRepositoryLayout> to make this work -- but only on my machine. (via: <classpathPrefix>${settings.localRepository}</classpathPrefix>)
What you want to investigate is Maven's dependency plugin. Add something similar to the following to pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<outputDirectory>
${project.build.directory}
</outputDirectory>
</configuration>
</plugin>
Then run mvn clean dependency:copy-dependencies to copy perform the copy. Combine this with the assembly plugin and you can package everything into a self contained archive for distribution.
I did not care for the Shade plugin since it rolls all the packages from all the jars together.
To include all of the external libs you can use the Dependency Plugin as mentioned above.
This example will create a "lib" directory under "target/classes" before the "package" phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/classes/lib</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeGroupIds>
junit,org.hamcrest,org.mockito,org.powermock,${project.groupId}
</excludeGroupIds>
</configuration>
</execution>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>sources</goal>
</goals>
</execution>
</executions>
<configuration>
<verbose>true</verbose>
<detail>true</detail>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
Take a look at maven's dependency plugin, specifically the copy-dependencies goal. The usage section describes how to do exactly what you want.
To do it from the command line just do:
$ mvn dependency:copy-dependencies -DoutputDirectory=OUTPUT_DIR
Yet another one is appassembler plugin
What I like about it is that it packages the app in a form ready to use (with a .bat file ans such)
It sure can. You need to use the shade plugin which can be done by adding
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3-SNAPSHOT</version>
<configuration>
<!-- put your configurations here -->
</configuration>
</plugin>
to your project.
Using maven.repo.local one can collect all jars, but, they are collected into a directory with maven hierarchy (.m2).
mvn install -Dmaven.repo.local=./pick/some/folder
You can then collect them (on Linux):
mkdir flat-repo
find ./pick/some/folder -type f -name "*.jar" | xargs -I'{}' cp '{}' flat-repo/

Categories

Resources