Maven copy project output into other project resources - maven-2

There are two projects:
1) applet project that outputs jar file
2) web app project that should host the jar file.
After (1) finished building, the applet jar file should be copied into the webapp folder of (2). The purpose is that (2) will host the applet (1) on the Internet.
A lot of examples explain how to use another project as a library dependency. Other examples, show how to use ant plugin to copy files. I am unsure on how to properly set this up, so that 'mvn install' on the parent project will do the copying at the right time.

I would declare the applet as a dependency of the webapp, copy it to the webapp just before packaging using the Dependency plugin and its copy goal. The whole solution might looks like this:
<project>
...
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>my-applet</artifactId>
<version>${project.version}</version>
<scope>provided</scope> <!-- we don't want the applet in WEB-INF/classes -->
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>my-applet</artifactId>
<version>${project.version}</version>
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
<destFileName>the-applet.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
</project>
Declaring the applet as dependency is for the reactor build order (but I'm not 100% sure it is required).

Related

Referring exploded war dependency in maven antrun plugin

I have a dependency declared as follows
<dependency>
<groupId>com.abc.webapp</groupId>
<artifactId>mywebapp</artifactId>
<version>1.3.2</version>
<type>war</type>
</dependency>
This war file which is part of an ear is exploded in the target directly and I need to copy a file(version.properties) to the WEB-INF/classes folder of this exploded war directory (target/mywebapp-1.3.2.war/). How can I refer to this folder in the antrun plugin without any hardcoding? Thanks in advance.
I'm going to cheat a bit and ask that you declare the dependency like this, with references to properties:
<dependency>
<groupId>${war.groupId}</groupId>
<artifactId>${war.artifactId}</artifactId>
<version>${war.version}</version>
<type>war</type>
</dependency>
and the properties would look something like this in your pom.
<properties>
<war.groupId>com.abc.webapp</war.groupId>
<war.artifactId>mywebapp</war.artifactId>
<war.version>1.3.2</war.version>
</properties>
Now, you still need to change the war GAV if required, but you only need to do it once, and the <dependency> and copy will both refer to the same thing.
Then maybe you could also use the maven-resouces-plugin and its copy-resource goal.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/${war.artifactId}-${war.version}.war/WEB-INF/classes</outputDirectory>
<resources>
<resource>
<directory>where_version.properties_is</directory>
<includes>
<include>version.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

yui compressor maven: A required class is missing: org.mozilla.javascript.ErrorReporter

I am not able to use yui-compressor maven plugin in my web app. When I run maven I get following error
[INFO] Internal error in the plugin manager executing goal 'net.sf.alchim:yuicompressor-maven-plugin:0.7.1:compress': Unable to load the mojo 'net.sf.alchim:
yuicompressor-maven-plugin:0.7.1:compress'
in the plugin 'net.sf.alchim:yuicompressor-maven-plugin'. A required class is missing: org.mozilla.javascript.ErrorReporter
Later I found that rhino js plugin contains this class org.mozilla.javascript.ErrorReporter. So I included this plugin in dependency tag but still I am getting the same error.
Has anyone came across such error.
--> updating main question to add the pom plugin details
<plugin>
<groupId>net.sf.alchim</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jslint</goal>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<failOnWarning>true</failOnWarning>
<nosuffix>true</nosuffix>
<aggregations>
<aggregation>
<!-- remove files after aggregation (default: false) -->
<removeIncluded>false</removeIncluded>
<!-- insert new line after each concatenation (default: false) -->
<insertNewLine>false</insertNewLine>
<output>${project.basedir}/${webcontent.dir}/js/compressedAll.js</output>
<!-- files to include, path relative to output's directory or absolute path-->
<!--inputDir>base directory for non absolute includes, default to parent dir of output</inputDir-->
<includes>
<include>**/autocomplete.js</include>
<include>**/calendar.js</include>
<include>**/dialogs.js</include>
<include>**/download.js</include>
<include>**/folding.js</include>
<include>**/jquery-1.4.2.min.js</include>
<include>**/jquery.bgiframe.min.js</include>
<include>**/jquery.loadmask.js</include>
<include>**/jquery.printelement-1.1.js</include>
<include>**/jquery.tablesorter.mod.js</include>
<include>**/jquery.tablesorter.pager.js</include>
<include>**/jquery.validate.js</include>
<include>**/jquery-ui-1.8.custom.min.js</include>
<include>**/languageDropdown.js</include>
<include>**/messages.js</include>
<include>**/print.js</include>
<include>**/tables.js</include>
<include>**/tabs.js</include>
<include>**/uwTooltip.js</include>
</includes>
<!-- files to exclude, path relative to output's directory-->
</aggregation>
</aggregations>
</configuration>
<dependencies>
<dependency>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
<scope>compile</scope>
<version>1.6R5</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0.7</version>
<scope>provided</scope>
</dependency><dependency>
<groupId>net.sf.retrotranslator</groupId>
<artifactId>retrotranslator-runtime</artifactId>
<version>1.2.9</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
Could you try the latest version (1.1)?
The 0.7.1 version doesn't even seem to be on the official repository. Maybe a dependency resolution problem?
See the topic Yui compressor StringIndexOutOfBoundsException on jboss
The only way to use yuicompressor on web app is to manually merge it with rhino dependency. Otherwise, the app to run would require specifying required sequence of jars in classloader loading sequence (youcompressor must go before rhino).
I struggled with the ErrorReporter class missing too. I solved it by building a jar-with-dependencies which I then turned around to use in my web app,
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
Once I did that, everything worked. In my jar I could see that the org.mozilla.javascript.ErrorReporter.class was in there and Maven would then compile for me.

How to make jetty-maven-plugin deploy a war that is retrieved from a repository?

I'm setting up an integration test module for a good sized web project. The integration test module is separated from the web project itself, and it has it's own pom.
The idea is to use the maven-soapui-plugin to send requests and verify the response. Setting up the soapui-plugin is no hassle. However, I'm having trouble with figuring out how I can tell the jetty-maven-plugin to deploy a war from a remote repository.
If I have understood correctly, the jetty-maven-plugin has a property called '<webApp>/<webApp>' which lets me specify the war file to deploy. The problem is that the war file is not present in the module itself.
I have heard that I can use the maven assembly plugin to retrieve the war from a repository via the projects artifactId, but I am yet to figure out how I would go about doing so.
Here's a summary of what I want:
Retrieve a specific war from a repository or the like, in example via its artifactId.
Deploy this war to the jetty-maven-plugin (goal deploy-war?)
get maven-soapui-plugin to run tests and report the results back in the integration-test phase.
I am pretty sure I've got step 3 covered, but I am very unsure how to achieve step 1 and 2.
Any help is greatly appreciated
It is maybe possible to use dependency:copy to retrieve the war, unpack it and to get the whole thing working with the maven jetty plugin, but this would be hacky and kinda ugly. A cleaner solution would be to use the Maven Cargo plugin and this is my suggestion. Below, a sample POM showing how to retrieve a WAR artifact using its coordinates and how to deploy it on an embedded Jetty container using Cargo:
<dependencies>
<dependency>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<version>war version</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<!-- Container configuration -->
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
<!-- Configuration to use with the container or the deployer -->
<configuration>
<deployables>
<deployable>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<properties>
<context>war context</context>
</properties>
</deployable>
</deployables>
</configuration>
<!-- Don't wait, execute the tests after the container is started -->
<wait>false</wait>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
Finally, just bind the soapui plugin on the integration-test phase.
I'm doing the same thing, John, but I took a different approach with the Jetty plugin. I think the end result is the same. I'm developing an integration-test suite to run against several web service WARs. I'm using dependency:copy in the package phase and then a list of <contextHandler/>s configured for maven-jetty-plugin:
<project>
…
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-wars</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/wars-to-be-tested</outputDirectory>
<stripVersion>true</stripVersion>
<artifactItems>
…
<artifactItem>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>version</version>
<type>war</type>
</artifactItem>
…
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.1.3.v20100526</version>
<configuration>
…
<contextHandlers>
…
<contextHandler implementation="org.mortbay.jetty.plugin.JettyWebAppContext">
<war>${project.build.directory}/wars-to-be-tested/artifactId.war</war>
<contextPath>/context</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I would prefer to declare the various wars as dependencies and then use dependency:copy-dependencies to set up the wars-to-be-tested directory; this would allow the Maven reactor to figure out that it needs to build my integration-test module after the wars it'll be testing. The problem I ran into was that the Jetty plugin thought that I wanted to "overlay" all of the wars that were listed as dependencies (a concept that I'd never even heard of until I saw it happen); I don't know if allowing that to happen would have hurt anything, but I didn't like it, so I went with the dependency:copy method.
This is just an alternative to using Cargo. I'll be looking into that myself, but I just wanted to provide another way of doing it.

Building a WAR project with unzipped JAR dependency?

I have two projects, my-lib and my-webapp. The first project is a dependency of my-webapp. Thus, when ask Maven2 to build my WAR, the my-lib JAR is added in the WEB-INF/lib/ directory of the web application.
However, I want to have the my-lib JAR unzipped directly in the WEB-INF/classes directory, exactly as if the my-lib sources were contained in the project my-webapp.
In others words, instead of having the following WAR content:
my-webapp/
...
WEB-INF/
lib/
my-lib-1.0.jar
... (others third libraries)
I want to have that:
my-webapp/
...
WEB-INF/
classes/
my-lib files
lib/
... (others third libraries)
Is there a way to configure the my-webapp or the Maven2 war plugin to achieve that?
As blaufish's answer says, you can use the maven-dependency-plugin's unpack mojo to unpack an artifact. However to avoid the jar appearing in WEB-INF/lib, you need to not specify it as a dependency, and instead configure the plugin to unpack specific artifacts.
The following configuration will unpack the contents of some.group.id:my-lib:1.0:jar into target/classes during the process-resources phase, even if the artifact is not defined as a dependency. Be careful when doing this though as there is potential to clobber your actual content, this can cause much debugging.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-my-lib</id>
<phase>process-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>some.group.id</groupId>
<artifactId>my-lib</artifactId>
<version>1.0</version>
<type>jar</type>
<overWrite>false</overWrite>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
</configuration>
</execution>
</executions>
</plugin>
You can configure the maven-dependency-plugin to just do that, unpack instead of copying a jar as explained here.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
<includes>**/*.class,**/*.xml</includes>
<excludes>**/*test.class</excludes>
</artifactItem>
</artifactItems>
<includes>**/*.java</includes>
<excludes>**/*.properties</excludes>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
The unpack mojo seems to be close to what you are aiming for. Not sure how to complete the entire flow you are proposing though.
(btw, I am doubtful if this a good idea. utility classes should go into jars, and the jars are put either in the WAR or io the EAR. Unpacking utility jars seems wrong)
I was able to use the unpack mojo as described above, plus I marked the dependency itself as "provided" (scope) to avoid duplicating the jar contents under WEB-INF/lib.
[Oops, just realized that you were using Maven. I don't delete this answer because it may come to the rescue of some Ant user. So there's no need to mod me down...]
How many times to I have to mention that Jar, War and Ear Ant tasks are subtasks of the Zip one? :-) If I remember correctly, something like this would do the trick:
<war dist="my-webapp.war">
<zipgroupfileset dir="libs" includes="*.jar" prefix="WEB-INF/classes"/>
</war>
Also worth a trial is with src="mylib.jar" but I haven't tested this option.

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>