maven-dependency-plugin:copy tries to copy classes - maven-2

I have parent pom and two module poms. In first module I want to copy second module (jar) to some folder. When I compiling project from first module pom - it works, but when I'm trying to compile from parent project pom, plugin tries to copy module classes insted of jar:
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-dependency-plugin:2.1:copy
(default) on project module1:
Error copying artifact from
/home/chardex/projects/test/module2/target/classes
to
/home/chardex/projects/test/module1/target/lib/classes:
/home/chardex/projects/test/module2/target/classes
(Is a directory) -> [Help 1]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>...</groupId>
<artifactId>module2</artifactId>
<version>...</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
Thanks.

I believe this is a bug in maven-dependency-plugin: http://jira.codehaus.org/browse/MDEP-259

While doing this in eclipse, unchecking the "Resolve workspace artifacts" got rid of the error, and I could do a clean install successfully.

Check if you are using eclipse lifecycle mapping in your pom and if so, check the plugin version. For me, it was maven-dependency-plugin 2.1 (buggy) instead of 2.0 used by command line maven.
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[2.0,2.0.8) <!-- 2.1 fails the build due to the http://jira.codehaus.org/browse/MDEP-187 -->
</versionRange>
<goals>
<goal>
copy-dependencies
</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>

Related

netbeans maven-assembly-plugin builds jar with dependencies but without project classes

In netbeans 7.2.1 i am trying to build an executable jar with dependencies using the maven assembly plugin. It worked in the past but when building the jar now it contains all dependencies except the classes from the project itself.
When running clean install assembly:single the target directory contains 2 jars, icfStatusPage-1.0-SNAPSHOT-jar-with-dependencies.jar and icfStatusPage-1.0-SNAPSHOT.jar. One contains all dependencies, the other all classes.
The build of the jar with dependencies seems to be ok. (missing pom files are manual installed artifacts).
[assembly:single]
Missing POM for cf:conn-fwk-int:jar:1.0
Missing POM for cf:conn-fwk:jar:1.0
Building jar: /Users/petervannes/NetBeansProjects2/icfStatusPage/target/icfStatusPage-1.0-SNAPSHOT-jar-with-dependencies.jar
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Plugin configuration snippet ;
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<debug>false</debug>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>nl.organization.icfstatuspage.IcfStatus</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<properties>
Have been googling and trying multiple options with no success till now.
Any help is welcome !
Cheers,
Peter
I was stuck at the same point you were and had trouble finding an answer, so even though this is an older question, since it still came up in the search when I was stuck, this is the answer. I think you need to add in the <executions> section. I know next to nothing about Maven, I'm just trying to make it work... this seemed to do the trick.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>nl.organization.icfstatuspage.IcfStatus</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
<descriptorRefs>
<descriptorRefs>jar-with-dependencies</descriptorRefs>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
I got that section from the Maven documentation on maven-assembly-plugin usage.

Maven 2 export jar to seperate directory

I need to export all the compiled class files as a jar to a directory of a local testserver. I would like to let maven do this automatically.
<!-- Build instructions -->
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>compile package</defaultGoal>
<sourceDirectory>${basedir}/src/</sourceDirectory>
<outputDirectory>/home/...</outputDirectory> <!--only class files go here, not the jar-->
<resources>
<resource>
<includes>
<include>plugin.yml</include>
</includes>
<directory>${basedir}</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
To build I first clean and then package via IntelliJ's Maven plugin. When I package I would like it to package the jarfile to my testserver so I don't have to move it over manually after every build.
Use Maven Ant plugin to custom code what you want to after a particular goal:
Using Ant with Maven
Ant Copt Task
You need to configure maven-jar-plugin and configure its outputDirectory as per your requirements, you can see the details on this link.
http://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html

Maven: add a folder or jar file into current classpath

I am using maven-compile plugin to compile classes. Now I would like to add one jar file into the current classpath. That file stays in another location (let's say c:/jars/abc.jar . I prefer to leave this file here). How can I do that?
If I use classpath in the argument:
<configuration>
<compilerArguments>
<classpath>c:/jars/abc.jar</classpath>
</compilerArguments>
</configuration>
it will not work because it will override the current classpath (that includes all the dependencies)
This might have been asked before. See Can I add jars to maven 2 build classpath without installing them?
In a nutshell: include your jar as dependency with system scope. This requires specifying the absolute path to the jar.
See also http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
The classpath setting of the compiler plugin are two args. Changed it like this and it worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>-cp</arg>
<arg>${cp}:${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
</plugin>
I used the gmavenplus-plugin to read the path and create the property 'cp':
<plugin>
<!--
Use Groovy to read classpath and store into
file named value of property <cpfile>
In second step use Groovy to read the contents of
the file into a new property named <cp>
In the compiler plugin this is used to create a
valid classpath
-->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.0</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<!-- any version of Groovy \>= 1.5.0 should work here -->
<version>3.0.6</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<executions>
<execution>
<id>read-classpath</id>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<scripts>
<script><![CDATA[
def file = new File(project.properties.cpfile)
/* create a new property named 'cp'*/
project.properties.cp = file.getText()
println '<<< Retrieving classpath into new property named <cp> >>>'
println 'cp = ' + project.properties.cp
]]></script>
</scripts>
</configuration>
</plugin>
From docs and example it is not clear that classpath manipulation is not allowed.
<configuration>
<compilerArgs>
<arg>classpath=${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
But see Java docs (also https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/tooldocs/solaris/javac.html)
-classpath path Specifies the path javac uses to look up classes needed to run javac or being referenced by other classes you are
compiling. Overrides the default or the CLASSPATH environment variable
if it is set.
Maybe it is possible to get current classpath and extend it,
see in maven, how output the classpath being used?
<properties>
<cpfile>cp.txt</cpfile>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>${cpfile}</outputFile>
</configuration>
</execution>
</executions>
</plugin>
Read file (Read a file into a Maven property)
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
def file = new File(project.properties.cpfile)
project.properties.cp = file.getText()
</source>
</configuration>
</execution>
</executions>
</plugin>
and finally
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>classpath=${cp}:${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
</plugin>
We mixed two of the answers found here to solve a similar problem. Our project needs a JAR only in compile stage, but add a local dependency, using system scope, it is unuseful because Maven refuse the artifact publication with an error related to a missing dependency.
The snippets used are the following:
<properties>
<classpathfile>${basedir}/classpathfile.classpath</classpathfile>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>${classpathfile}</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
def file = new File(project.properties.classpathfile)
project.properties.originalClassPath = file.getText()
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerArgs>
<arg>-cp</arg>
<arg>${originalClassPath}${path.separator}${basedir}/../../../bin/POM_RUNTIME_PLACEHOLDER/ExtraJar.jar</arg>
</compilerArgs>
</configuration>
</plugin>
Maven is able to compile and successfully deploy the artifacts.
If anyone is interested the full POM is available in GitHub under project NuReflector, defaultPOM.template under src/NuReflector.

How to get Maven to run war:exploded but not war:war

I have a Maven pom that uses <packaging>war</packaging>. But actually, I don't want build the war-file, I just want all the dependent jars collected and a full deployment directory created.
So I'm running the war:exploded goal to generate the deploy directory:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<webappDirectory>target/${env}/deploy</webappDirectory>
<archiveClasses>true</archiveClasses>
</configuration>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
The trouble is, the war file still gets built. Is there a simple way of having <packaging>war</packaging> execute the war:exploded goal instead of the war:war goal?
Or is there another simple way to do this?
The solution is quite simple. You need to override the default execution of the war plugin to disable it and add your own execution (for exploded):
<pluginManagement>
<plugins>
<plugin><!-- don't pack the war -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
According builtin lifecycle bindings for war packaging in package phase war:war mojo is called.
You can call previous 'prepare-package' phase - all actions will be performed and after that call mojo war:exploded
mvn prepare-package war:exploded
The results will be the same as yours but no war created.
I would like to upgrade onto #Michael Wyraz answer and just include install skip settings in case if someone executes mvn clean install build on top level of multimodule project and one of sub-module is web application.
This stands inside war module:
<profiles>
<profile>
<id>war_explode</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
Without install skip build fails as it tries to install war into .m2 folder. Error message looks like this:
[INFO] --- maven-install-plugin:2.4:install (default-install) # *** ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project ***: The packaging for this project did not assign a file to the build artifact -> [Help 1]
Executing mvn clean install -P war_explode with this settings (enclosed in maven profile named war_explode) it finishes build without error.
The only way I can think of to do what you want is to set use pom packaging (or create a custom packaging) and bind the required goals from the war packaging to the relevant phases of the lifecycle. If you go for pom packaging you can use define the war:war execution in a profile to allow you to package it, but you'll need to use the build-helper-maven-plugin attach-artifact goal to attach the war to the pom.
Note with this approach if you want to use any other war-specific processing it may cause you problems.
The lifecycle bindings for war packaging are listed in the Introduction to The Build Lifecycle (see the "Default Lifecycle Bindings - Packaging ejb / ejb3 / jar / par / rar / war" section).
To bind the relevant plugin executions to the pom packaging you would do as follows:
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compile-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-test-resources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goal>
</execution>
</executions>
</plugin>
<!-- package not wanted, install and deploy already defined for pom packaging-->
<!--define war:war execution in a profile in case it is needed-->
As far as I know (I'm still new to maven) this is not possible. The only default lifecycle you can skip is 'test'. In order to get to the deploy you have to package. You can read all about the default lifecycle order of execution here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference

Maven in multimodule web project: how to put sibling modules output to WEB-INF/classes and not into WEB-INF/lib as JARs?

I have a multi-module Maven project.
By default when I build a web module, all sibling modules of type JAR it depends on are copied to WEB-INF/lib folder. I want output of sibling modules to be placed in WEB-INF/classes folder without packaging to JAR.
More general question may be: how to keep sibling modules' configuration files out of JARs so that they can be edited after deployment easily?
You could use an overlay, although that requires that the sibling be of type war rather than jar. There's also using the dependency plugin to unpack the jar, but it will only unpack the version in your local repository, not the one you just packaged.
As for your 'more general' question, there's the excludes tag for the jar plugin.
In case if somebody is interested, I found this solution. I had exactly the same issue.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/MYPACKAGE_TO_EXCLUDE.jar</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-MYPACKAGE_TO_EXCLUDE</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>MYPACKAGE_TO_EXCLUDE</artifactId>
<version>${project.version}</version>
<type>jar</type>
<outputDirectory>${project.build.directory}/classes
</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>