Copy dependencies maven war - maven-2

When I try to use the plugin "maven-war-plugin", it copies all libraries to / WEB-INF/lib, how to copy to another directory? Example: "/ libtest"

I'm not sure to understand why you need to do this but I see two points here:
Avoiding dependencies to get copied into WEB-INF/lib (if not, then just skip the part related to 1.)
Getting them copied to another directory.
For 1. I'm assuming you need the dependencies (because you want to compile against them) but if you don't want the Maven War Plugin to copy them in WEB-INF/lib, you'll have to play with their scope, for example by declaring them as provided.
For 2. the Maven Dependency Plugin will be helpful here and I think you could use dependency:copy-dependencies, for example during the pre-package phase. Use it like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>pre-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- configure the plugin here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
And configure the outputDirectory (and other parameters you could need).

Use the maven-dependency-plugin.

Related

Maven - Replace a file in a Jar

I want to replace a file in an existing jar/zip file while doing a Maven build. What is the easiest way to achieve this?
My favorite for this sort of tasks is maven-antrun-plugin which brings you complete ant functionality.
You can use it like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>repack</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- note that here we reference previously declared dependency -->
<unzip src="${org.apache:common-util:jar}" dest="${project.build.directory}/tmp"/>
<!-- now do what you need to any of unpacked files under target/tmp/ -->
<zip basedir="${project.build.directory}/tmp" destfile="${project.build.directory}/common-util-modified.jar"/>
<!-- now the modified jar is available -->
</target>
</configuration>
</execution>
</executions>
</plugin>
But remember - never modify any files in your local repository - in this example pointed to by ${org.apache:common-util:jar}. Doing so would affect your further builds of all your projects on the same computer (= against the same local repo).
Such builds are also irreproducible (or hard to reproduce) on other machines.
I don't think there is a dedicated plugin to do this but I would imagine you can use the exec plugin and information from Updating .class file in jar to accomplish this.

How can I add a specific jar only in a specific folder with Maven?

i have a maven project using the maven soapui plugin.
Unfortunately this one in my case need an external jar for jdbc for
some groovy scripts.
And according to their documentation, you have to add a repertory called "ext".
And after a dig in their code, this path is hardcoded in their plugin source.
You cant specify it.
So i have to add it directly to a subdirectory of MyProject :
Myproject/ext/postgresql.X.X.jar
I dont want to commit a jar in my project.
Is there a way to tell to maven to pickup a specific jar& add it to a specific directory ?
Thanks in advance for your answer.
You could use maven-dependency-plugin configured in your pom file to copy the artifact into that location during the generate-resources phase, something like this:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy-postgresql-artifact</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/ext</outputDirectory>
<!-- if you need to rename the jar -->
<destFileName>postgresql.X.X.jar</destFileName>
<artifactItems>
<artifactItem>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>X.X</version>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Maven2: How do I generate a file that contains the names of the project's dependencies?

I would like to place the names of the dependencies in a text file that is distributed inside a package that is built with Maven.
I am planning to use the maven assembly plugin to generate the tarball package, and use filtering to put the names in the text file.
The only problem is, I don't know how to reference the dependencies in the first place.
You don't need to use filtering for that, use the Maven Dependency plugin and its a dependency:tree goal to display the dependency tree for this project. Set an output file with the... outputFile optional parameter. So the configuration might look like:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>tree</id>
<phase>prepare-package</phase>
<goals>
<goal>tree</goal>
</goals>
<configuration>
<outputFile>${project.build.outputDirectory}/dep.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Running the package phase would generate the dependency tree in target/classes/dep.txt and package it in the artifact. Adapt it to suit your needs.
You can use the maven-dependency-plugin dependency:tree to output the tree of dependencies into a file.
mvn dependency:resolve seems to be what you are looking for. Put following plugin configuration to your POM file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>list-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<outputFile>dependencies.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
It will produce file dependencies.txt with content similar to:
The following files have been resolved:
am:amagent:jar:1.0:system
am:amclientsdk:jar:1.0:system
aopalliance:aopalliance:jar:1.0:compile
asm:asm:jar:2.2.3:compile
com.sun.jdmk:jmxtools:jar:1.2.1:compile
com.sun.jmx:jmxri:jar:1.2.1:compile
com.sun.xml.bind:jaxb-impl:jar:2.1.12:compile
com.sun.xml.fastinfoset:FastInfoset:jar:1.2.2:compile
com.sun.xml.messaging.saaj:saaj-impl:jar:1.3.2:compile
commons-lang:commons-lang:jar:2.3:compile
commons-logging:commons-logging:jar:1.1:compile
dom4j:dom4j:jar:1.6.1:compile
javax.activation:activation:jar:1.1:provided
javax.jms:jms:jar:1.1:compile
javax.mail:mail:jar:1.4:compile
javax.xml.bind:jaxb-api:jar:2.1:compile
javax.xml.soap:saaj-api:jar:1.3:compile
junit:junit:jar:4.4:test
log4j:log4j:jar:1.2.15:compile

Maven-2: avoid default packaging?

My project uses many assemblies, hence I'm interested only in the assemblies.
On executing mvn install apart from the assemblies, I'm getting the default packaged .jar.
How can I avoid this?
I have a pom.xml similar to the one you have provided.
On executing mvn install, I'm getting App1.jar, App2.jar, and snapshot jar containing all contents
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>assemblyone</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App1</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/report.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>assemblytwo</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App2</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/src.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I avoid this snapshot (not sure of the exact term) jar and ensure that only assemblies are created?
I can read your question two ways, I've outlined answers for both below. If neither is correct, can you modify your question with a bit more explanation please.
1) Do you mean you have a project with default (jar) packaging, and you want to avoid the creation of the jar when no assembly is defined? If this is the case, what is the build achieving if no assembly is defined?
2) Do you instead mean that you are running mvn assembly:assembly to generate the assembly and want to know how to get that assembly when running the install goal?
For option 2, you can bind the assembly-plugin to a lifecycle phase to ensure it is always run, if you specify that <appendAssemblyId> should be false, then the assembly will replace the default jar.
For example, this configuration will invoke the assembly plugin during the packaging phase and replace the default jar:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
For option 1, this is actually quite tricky to do. The best I can think of is to specify that the project has pom packaging and configure the project with the executions normally bound to the jar lifecycle in a profile. The lifecycle bindings you'd need to configure are listed in the introduction to the build lifecycle
I'm not sure that you can really do that in a really simple way.
A solution is to call the clean plugin once the build is achieved, by doing that:
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>auto-clean</id>
<phase>package</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
This way, the JAR created in the target/ directory will be deleted at the end of the Maven2 execution.
However, you will have to define another directory to store the assemblies created by Maven2. Otherwise, it will be deleted by the call of the clean plugin... If you want to store them in the directory assemblies-target/, you can add that in the pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
...
<!-- Copy the ZIP in target/ of the ROOT directory. -->
<outputDirectory>assemblies-target</outputDirectory>
</configuration>
...
I think it would be much more clear if you showed us your whole POM and the artifacts that are being built. I can only guess as to what the problem is because your terminology is not what I am familiar with. This is my guess as to the problem: you have a POM configured to generated two assembly JARs, but you get a third JAR for the POM itself. In other words, if your POM's artifactId is MyApp, you are getting a MyApp-1.0.0.jar or similar in addition to the two JARs you actually want.
If that is the case, the problem boils down to that you are using Maven to create multiple artifacts from a single module. Maven is designed to produce only one primary artifact from each module. What I would do is change your POM to have a packaging type of "pom" and give it two modules in a <modules> section named App1 and App2. Create sub-directories under your module, one for each App. Give them each a POM configured for a single assembly, with a packaging type of "jar". Move the code/files/etc. as appropriate into each sub-module so there aren't any remaining in the parent module.
With Maven, if you find yourself generating two artifacts from one module (which you are), you should first consider that you are probably violating a Maven best-practice and rearrange things so you only produce one artifact per module.
Please let me know if this doesn't make sense and I will try to clarify.

Can I set the project version with a buildnumber-maven-plugin?

I'm trying to add the svn.revision to project version as a build number and can't seem to do so. My jar has the correct name durin packaging, but its installed in the my local repository it is as if ${buildNumber} is/was undefined when the version was set.
I get foo-1.0.0-SNAPSHOT-${buildNumber} instead of foo-1.0.0-SNAPSHOT-304
Any idea what I'm doing wrong or is adding a revision to the project version a bad idea? Thanks for the help.
<project>
...
<version>1.0.0-${release.identifier}-${buildNumber}</version>
<properties>
<release.identifier>SNAPSHOT</release.identifier>
</properties>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<executions>
<execution>
<id>useLastCommittedRevision</id>
<goals>
<goal>create</goal>
</goals>
<configuration>
<useLastCommittedRevision>true</useLastCommittedRevision>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</project>
The problem has two parts:
You're trying to set the buildNumber into the version before it is resolved so it will always be ${buildNumber} rather than the resolved value.
Instead of trying to dynamically change the version, you should set the buildNumber into the finalName element in the build. This will create the artifacts with the intended name in the local repository.
The install plugin will ignore the finalName and deploy it as 1.0.0-SNAPSHOT regardless, I don't know of a way to address that. The buildNumber is added to the Manifest if you configure the plugin as below.
So your configuration would be something like:
<version>1.0.0-${release.identifier}</version>
...
<build>
<finalName>${project.artifactId}-${project.version}-${buildNumber}</finalName>
...
</build>
I would avoid using build numbers on SNAPSHOT projects.
Maven provides the SNAPSHOT keyword to signify a volatile project in active development. So if you reference a project with a SNAPSHOT dependency version, Maven will automatically check for updates and keep your dependencies in sync.
If you then add a build number to the end of that version, you will have to manually update the dependencies, so you lose any benefit of having the SNAPSHOT suffix.
I personally avoid using build numbers where possible anyway. If I have to update a project, I just bump the version number, or use a suffix like beta-2 or RC2. If you need to track the revision in the SNAPSHOT, I'd recommend adding it to the Manifest so you can check where the build originated, but use the standard SNAPSHOT suffix to allow Maven to resolve the versions normally. The configuration below shows how to add the revision to the Manifest.
As far as your configuration is concerned, it looks OK to me assuming your SCM url is set up correctly. If you have no SCM configuration in your POM that may be the problem.
Can you run with -X and check for any output from the plugin indicating why it isn't setting the property?
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>0.9.4</version>
<executions>
<execution>
<id>useLastCommittedRevision</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
Add this after the buildnumber-maven-plugin:
<plugin>
<groupId>io.github.michaldo</groupId>
<artifactId>nashorn-maven-plugin</artifactId>
<version>0.0.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>eval</goal>
</goals>
<configuration>
<script>
$project.artifact.version = "${buildNumber}";
</script>
</configuration>
</execution>
</executions>
</plugin>
And the buildNumber will be recognized by packaging and deploy.