How to get maven assembly plugin to copy artifact? - maven

I have a Maven assembly script that copies resources to build our app. I need to copy some war files from separate, external projects into a /webapps directory in the output. Can't seem to find the magic commands to do it.
I tried adding a dependencySet to the assembly with <include com.mygroup:mywarfile>. This works if I add 'mywarfile' as a war dependency in the project with a scope of compile or runtime. Unfortunately, my project produces a war, and the maven-war-plugin includes the external mywarfile as an overlay, which I don't want.
If I set the scope of the external war dependency to provided or test, the assembly fails with the warning:
[WARNING] The following patterns were never triggered in this artifact inclusion filter:
'com.mygroup:mywarfile'
All I want to do is have the assembly copy an artifact from my local repo to the assembly output. How to do it without messing up other parts of the project?

The maven-assembly-plugin is not intended for copying. The better way to copy dependencies is the maven-dependency-plugin which can copy dependencies etc. If you a talking about deployment into Tomcat etc. than you should take a deeper look into carg2-maven-plugin or the tomcat-maven-plugin which seemed to be more appropriate for that task.

I haven't tried this, but you could try using the exclude feature of overlay configuration of maven war plugin to exclude contents of the dependant war file from being included in your war project. Modified snippet from the Overlay documentation,
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<overlays>
<overlay>
<groupId>com.example.projects</groupId>
<artifactId>warToBeExcluded</artifactId>
<excludes>
<exclude>*</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
...

Related

How can I force maven WAR plugin to leave the version number out of dependency file names?

I'm facing the same issue described here: How can I force maven to leave the version number out of dependency file names? but with the WAR plugin. Looked around but didn't find any solution.
You can define file name mappings with the maven-war-plugin. This is done with the outputFileNameMapping of the plugin configuration:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<outputFileNameMapping>#{artifactId}#.#{extension}#</outputFileNameMapping>
</configuration>
</plugin>
With this configuration, each dependency in WEB-INF/lib will be stripped of their version.

IntelliJ: Copy war file after build

I'm using IntelliJ + Maven to generate war files.
The war is always generated in ProjectDirectory/target/projectname-version.war
After the build process is done, I want to copy the generated war file into a different location (something like cp output X:/remote/tomcat_webapps/projectname.war).
I already tried to configure the directory where maven builds the project (within the pom.xml). However, maven always deletes the containing folder and all its contents, so that is not an option.
How can I automatically copy the generated war file into a different location?
you can modify the maven war plugin in your pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<outputDirectory>X:/remote/tomcat_webapps</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
I'm not quite sure, if it is the outputDirectory or should it be webappDirectory, like in the documentation
https://maven.apache.org/plugins/maven-war-plugin/usage.html

How to include resources from war to another maven project

I have a maven project , which needs to copy webapp/WEB-INF/ resources from another maven project which is packaged as a war .
How do I do it ?
PLease suggest
As Bittrance said, you should use the maven dependency plugin.
The better way is to create project that include all your shared resources, probably a type zip, which is build up with the assembly plugin. This is the good "maven way". It's a better solution than unpacking a war.
Then, refer it
<dependency>
<groupId>com.mygroup/groupId>
<artifactId>my-dependencies</artifactId>
<version>1.0.0</version>
<type>zip</type>
</dependency>
Next, you use the maven dependency plugin to unpack your resources, in the directory of your choice (probably WEB-INF/ ?)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-cfg-test-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/WEB-INF/</outputDirectory>
<includeArtifacIds>my-resources</includeArtifacIds>
<excludeTypes>pom</excludeTypes>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
I'm not realy sure of this code snippet (written for another purpose), but this is an example.
For more information, please follow this link : http://maven.apache.org/plugins/maven-dependency-plugin/
If you can't shared a common-project including your files, you can unpack war including only ftl (or whatever you want), but it's not a realy clean solution ;)
There is a lot of posts that deal with this subject :
Unzip dependency in maven
...
Just try with the keywords maven-dependency-plugin, unpack :)
Hope that will help you.
I can see some alternatives:
Use external references in your version control system to point all repos to the same files.
The Maven Dependency module can copy and unpack project dependencies. From there, you can use the Maven Assembly plugin (or Ant targets) to include parts of that dependency in your own installation.
At least for the FTL files, perhaps you could package them in a separate Jar file and then load them as resources through the class loader.
If the resources are filtered, you may get into problem with solution 1 if you want the filtered version and 2, 3 if you want the source version.
Hope this helps.
(This assumes your dependent project is java (jar) and not another web app, if it is a webapp I think the solution is similar).
I suggest a (slightly) different approach:
Instead of reading resources from war, add this to your war pom, to generate a jar in the artifact as well as a war:
<!-- maven war plugin config -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<configuration>
...
<attachClasses>true</attachClasses>
<classesClassifier>some-string</classesClassifier>
</configuration>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>
...
<resources>
<!-- This is for inclusion in the jar, so dependent module can load it -->
<resource>
<targetPath>some-path</targetPath>
<directory>src/main/webapp/path...</directory>
<includes>
<include>your-resource</include>
</includes>
</resource>
</resources>
And this to your consuming pom, so the generated jar will be loaded:
<dependency>
<groupId>com.company</groupId>
<artifactId>...</artifactId>
<classifier>some-string</classifier>
</dependency>
Then you will be able to load the resources the usual way (getResourceAsStream("some-path/your-resource"))

Exclude all the jar's from webapp/WEB-INF/lib

I have the third party jar's in my WEB project placed at /src/main/webapp/WEB-INF/lib/
I have mentioned the dependency for all the required JAR's in the pom.xml.
Now, Since the dependencies are defined in POM, the JAR's will be automatically packed in the lib folder.
I want to exclude all the JAR's in the lib.
The Dependency JAR's should be packaged inside the lib while building the WAR
I CANT DELETE THE LIB FROM WEB-INF BECAUSE ITS USED IN LOCAL DEVELOPMENT
This is what I've tried so far:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>META-INF/context.xml</packagingExcludes>
<webResources>
<resource>
<directory>src/main/webapp/WEB-INF/lib</directory>
<excludes>
<exclude>**/**</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
Any Idea?
It should be "packagingExcludes" instead of "warSourceExcludes":
<configuration>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
....
</configuration>
From http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html :
In version 2.1-alpha-1, this was incorrectly named warSourceExcludes
Try this:
<configuration>
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
....
</configuration>
However, I do agree with Jarrod that it is bad practice to store your jars in WEB-INF/lib 'manually'. I used this before to avoid that jars coming as a dependency got packaged to be able to repackage it afterwards.
you shouldn't have anything in your WEB-INF/lib directory to begin with. If you are using Eclipse, you can tell it to build its project from the pom.xml and it will know to look in ~/.m2/repository for dependencies, Intellij IDEA does this as well. Putting dependencies in WEB-INF/lib kind of defeats the purpose of using Maven for dependency management. What happens when the dependencies in the pom.xml get out of sync version wise with those in WEB-INF/lib

Maven WAR dependency

I am writing a project for acceptance testing and for various reasons this is dependent on another project which is packaged as a WAR. I have managed to unpack the WAR using the maven-dependency-plugin, but I cannot get my project to include the unpacked WEB-INF/lib/*.jar and WEB-INF/classes/* to be included on the classpath so the build fails. Is there a way to include these files into the classpath, or is there a better way of depending on a WAR?
Many thanks.
There's another option since maven-war-plugin 2.1-alpha-2. In your WAR project:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This creates a classes artifact which you can use in the acceptance tests project with:
<dependency>
<groupId>your-group-id</groupId>
<artifactId>your-artifact-id</artifactId>
<version>your-version</version>
<classifier>classes</classifier>
</dependency>
Indeed, by design, Maven doesn't resolve transitive dependencies of a war declared as dependency of a project. There is actually an issue about that, MNG-1991, but it won't be solved in Maven 2.x and I'm not sure that I don't know if overlays allow to workaround this issue. My understanding of the suggested solution is to duplicate the dependencies, for example in a project of type pom.
(EDIT: After some more digging, I found something interesting in this thread that I'm quoting below:
I have been helping out with the development of the AppFuse project over
the last month where we make heavy use of the war overlay feature in the
Maven war plugin. It is a really nifty feature!
To get max power with war overlays I have developed the Warpath plugin
that allows projects to use war artifacts as fully fledged dependencies.
In brief:
1) The contents of the /WEB-INF/classes directory in the war dependency
artifacts can be included in the project's classpath for normal compile,
etc tasks.
2) Transitive dependencies from the war dependency artifacts become
available for use by other plugins, e.g. compile and ear - so no more
having to include all the dependencies when creating skinny wars!
The plugin has now been actively used in the AppFuse project for the
last few months, and I feel it is at a point where it is both usable and
stable.
Would the war plugin team be interested in including the warpath
functionality inside the war plugin? It would seem to be the most
natural place to host it.
So, I don't have any experience with it, but the maven warpath plugin actually looks nice and simple and is available in the central repo. To use it,include the following plugin configuration element in your pom.xml file:
[...]
<build>
<plugins>
<plugin>
<groupId>org.appfuse</groupId>
<artifactId>maven-warpath-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>add-classes</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
And add the war dependencies you want included in the classpath as warpath type dependencies:
[...]
<dependencies>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>warpath</type>
</dependency>
</dependencies>
[...]
Both the war and warpath dependency types are needed: the war type is used by the Maven war plugin to do the war overlay, the warpath type is used by the Warpath plugin to determine the correct list of artifacts for inclusion in the project classpath.
I'd give it a try.)
Use overlays. First, your test project need to have also packaging war.
Declare dependency of war project you want to test:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>your-project-arftifactId</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
then configure maven-war-plugin overlay:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webresources</directory>
<filtering>true</filtering>
</resource>
</webResources>
<overlays>
<overlay/>
<overlay>
<groupId>your.group</groupId>
<artifactId>your-project-artifactId</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
In the above example in test project I overwrite webresources configuration files (like conxtext etc.).
EDIT: This solution wasn't tested with Maven 3.
Good point, Justin. That got me actually solving my problem, namely: including a war into an assembly AND including all its transitive dependencies.
I could not duplicate the war-dependency as 'jar' as you suggested since the assembly plugin would not find a jar referenced by that groupId/artefactId, but
duplicating the war-dependency as type pom
works!
The war and its transitive dependencies are not included in the assembly.
To exclude the (now also appearing) pom file I had to add an exclude element like this:
<excludes>
<exclude>*:pom</exclude>
</excludes>
into my assembly.xml file.
I think this could also be a workaround for the original question of this thread.
If you list the dependency on the war project as a jar dependency it seems to pickup the required jars/resources. I'm using Maven 2.2 + m2eclipse.

Resources