How to copy specified files whitout folder structure using overlays? - maven-2

I would like copy just "file.xml" without folder structure using overlays like this:
<overlays>
<overlay>
<groupId>com.mygroup</groupId>
<artifactId>my_comp</artifactId>
<includes>
<include>WEB-INF/folder1/folder2/file.xml</include>
</includes>
<targetPath>WEB-INF/otherFolder</targetPath>
<type>war</type>
</overlay>
</overlays>
In other words: copy file.xml from WEB-INF/folder1/folder2/ and place to the WEB-INF/otherFolder
Any ideas?

I didn't find how to resolve the issue via overlays. So I had to use two plugins maven-dependency-plugin and maven-war-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy</id>
<phase>process-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mygroup</groupId>
<artifactId>my_comp</artifactId>
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/tmp</outputDirectory>
<includes>WEB-INF/folder1/folder2/file.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-beta-1</version>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/tmp/WEB-INF/folder1/folder2</directory>
<targetPath>WEB-INF/otherFolder</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
The first plugin attached to the process-resources phase. The second invoked on phase package when all overlays combined. Overlays are applied with a first-win strategy (hence if a file has been copied by an overlay, it won't be copied anymore) If I've copy my file.xml (via plugin) then it not be overwritten by any overlay.
It's so complicated!

To my knowledge, this is not possible with overlays, the content of the overlay is added "as is" to the targetPath (that defaults to the root structure of the webapp).
If you want to make file.xml available at another location, you'll have to tweak its location in my_comp WAR before the overlay.

Related

How can I strip the version from the output directory of maven-dependency-plugin:unpack?

I need to unpack an artifact, and I need to use it's unpacked location in several places (in multiple files). I don't want to have to update all the copies of that location every time I change versions. Is there a way I can strip the version from the output directory? It doesn't look like stripVersion is supported with the unpack mojo.
Does the plugin you are using to create the artifact provide a xyzName property? For example the jar-plugin provides the finalName and the war-plugin has the warName.
If so you can set the property to some fixed value.
Try this:
<properties>
<extracted-artifact-location>${project.build.directory}/extracted-artifact</extracted-artifact-location>
</properties>
...
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId><fixme></groupId>
<artifactId><fixme></artifactId>
<version><fixme></version>
<outputDirectory>${extracted-artifact-location}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Maven: downloading files from url

Can I download some files from http while maven lifecycle? any plugin?
If the file is a Maven dependency, you could use the Maven Dependency Plugin which has a get goal.
For any file, you could use the Antrun plugin to call Ant's Get task.
Another option would be the maven-download-plugin, it has been precisely created to facilitate this kind of things. It's not very actively developed and the documentation only mentions an artifact goal that does exactly the same thing as dependency:get but.. If you look at the sources, you'll see that is has a WGet mojo that will do the job.
Use it like this in any POM:
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<!-- the wget goal actually binds itself to this phase by default -->
<phase>process-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>http://url/to/some/file</url>
<outputFileName>foo.bar</outputFileName>
<!-- default target location, just to demonstrate the parameter -->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Key benefits of this plugin are caching of the download and checking against a signature, such as MD5.
Note that this answer has been heavily updated to reflect changes in the plugin as noted in the comments.
Seems like wagon-maven-plugin from CodeHaus allows to download files over HTTP (though this is not is original goal).
Here is an example downloading GlassFish zip before integration tests:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>download-glassfish</id>
<phase>pre-integration-test</phase>
<goals>
<goal>download-single</goal>
</goals>
<configuration>
<url>http://download.java.net</url>
<fromFile>glassfish/3.1/release/glassfish-3.1.zip</fromFile>
<toDir>${project.build.directory}/glassfish</toDir>
</configuration>
</execution>
</executions>
</plugin>
The maven-antrun-plugin is a more direct solution:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>download-files</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- download file -->
<get src="http://url/to/some/file"
dest="${project.build.directory}/downloads/"
verbose="false"
usetimestamp="true"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
I'd like to add a few thing about the download-maven-plugin:
Project is now hosted on GitHub https://github.com/maven-download-plugin/maven-download-plugin
Its releases are available on Maven Central, and the SNAPSHOTs are available on the oss.sonatype.org snapshot repository
Compared to other suggestions mentioned here, the download-maven-plugin adds the following interesting feature: caching of files (to avoid always redownloading big files) and signature verification to make sure download got the right bits.
If available, wget can be used directly with exec-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>wget</executable>
<arguments>
<argument>http://example.com/file.zip</argument>
<argument>destination.zip</argument>
</arguments>
</configuration>
</plugin>
You can use the download-single goal in the wagon plugin. Here is an example to download an HTML page (notice that the URL have to be split in a "directory" url and a "file name")
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals><goal>download-single</goal></goals>
<configuration>
<url>http://www.mojohaus.org/wagon-maven-plugin</url>
<fromFile>download-single-mojo.html</fromFile>
<toFile>[my dir]/mojo-help.html</toFile>
</configuration>
</execution>
</executions>
</plugin>

Maven - Add directory to classpath while executing tests

The Junits I have in my project need to load property files from the classpath. How can I specify the directory of those property files so that Maven will set that in the classpath before running the tests?
You can also add new test resource folders.
<build>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
<testResource>
<directory>${project.basedir}/src/test/something_else</directory>
</testResource>
</testResources>
</build>
The first path, src/test/resources, is the default. Assuming you still want the default path to be used, make sure it's included. (The testResources tag overwrites your defaults, so if you don't include the default path explicitly, it will stop being used.)
You can use the build-helper-maven-plugin to specify additional test-resource directories as follows. Using the configuration below, the contents of the test-resources directory will be copied to the target/test-classes directory during the generate-test-sources phase:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>add-test-resource</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>path/to/additional/test/resources</directory>
<excludes>
<exclude>**/folder-to-exclude/**</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
If you just want to put your property files someplace on disk and don't want to copy those property files to target/test-classes during the build, you can do it this way
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>/add/this/to/path</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
Why not just use test/resources and place your properties in the classpath from that point. They'll only be there for the test phase.
If you have multiple resource environment you can use maven profile and put your various resources according to the profile you are testing.
test/resources/uat
test/resources/prod
test/resources/dev
But usualy if you need that you are making integration test then you don't need the build-helper-maven-plugin.
The maven-resources-plugin has a copy-resources goal that will allow you to copy resources. For example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>additional-resources</id>
<phase>process-test-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/conf</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
This will copy the contents of the conf folder in the base of your project to the target/test-classes folder (unless you modified project.build.testOutputDirectory) which will be added to the classpath during your unit tests.

Overlay BIRT runtime into correct WAR locations

I'm trying to get Maven to assemble a WAR with the BIRT runtime in a useful location within the WAR.
The BIRT runtime is in the pom.xml as
<dependency>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<version>2.3.2</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
The desired outcome of overlaying this is something like
ReportEngine/lib/* -> WEB-INF/lib
ReportEngine/configuration/* -> WEB-INF/platform/configuration
ReportEngine/plugins/* -> WEB-INF/platform/plugins
My overlay configuration looks like
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<overlays>
<overlay>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<type>zip</type>
<includes>
<include>ReportEngine/lib/*</include>
</includes>
<targetPath>WEB-INF/lib</targetPath>
</overlay>
<overlay>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<type>zip</type>
<includes>
<include>ReportEngine/configuration/*</include>
<include>ReportEngine/plugins/*</include>
</includes>
<targetPath>WEB-INF/platform</targetPath>
</overlay>
</overlays>
</configuration>
</plugin>
Of course, when running mvn war:exploded I'm seeing
ReportEngine/lib/* -> WEB-INF/lib/ReportEngine/lib/
ReportEngine/configuration/* -> WEB-INF/platform/configuration/ReportEngine/lib/
ReportEngine/plugins/* -> WEB-INF/platform/plugins/ReportEngine/lib/
This relates, same sort of problem, no answer
http://www.coderanch.com/t/447258/Ant-Maven-Other-Build-Tools/Maven-war-dependencies-moving-files
Bonus points for pointing out how I can tidy this up a bit by having it all work from within WEB-INF/birt-runtime
Edit:
The reason for the locations specified above are that they match those indicated in http://wiki.eclipse.org/Servlet_Example_%28BIRT%29_2.1 and when I fritz with the Tomcat installation to mimic this, it all seems to work. It would be ideal if I could simply overlay the zip into WEB-INF/birt-runtime and then set the engine config appropriately, but I've not found that to work as yet.
Eg:
engineConfig = new EngineConfig();
engineConfig.setEngineHome("WEB-INF/birt-runtime");
engineConfig.setPlatformContext(new PlatformServletContext(servletContext));
Update: On rereading the question I realise I missed out the sub-directories from my test project, so of course it worked for me, sorry for that.
As far as I know there exists no mechanism in either the war overlay or the dependency-plugin to unpack sub-folders of artifacts to a directory and exclude the parent elements of the path, both are going to give you the full relative path.
You can however use the unpack goal to unpack the archive to a temporary folder, then use the antrun-plugin to copy the required subfolders to their final resting places.
The following configuration would do just that (I've not yet tested this so apologies if there are any omissions, see the documentation for exact details). Note the executions are in the same phase, but as long as the dependency-plugin is configured before the antrun-plugin it would be executed first. Note, the prepare-package is new for Maven 2.1, if you're on an older version you'd need to use another phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-lib</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<version>2.3.2</version>
<type>jar</type>
<overWrite>false</overWrite>
</artifactItem>
</artifactItems>
<!--unpack all three folders to the temporary location-->
<includes>ReportEngine/lib/*,ReportEngine/configuration/*,ReportEngine/plugins/*</includes>
<outputDirectory>${project.build.directory}/temp-unpack</outputDirectory>
<overWriteReleases>false</overWriteReleases>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<configuration>
<tasks>
<!--now copy the configuration and plugin sub-folders to WEB-INf/platform-->
<copy todir="${project.build.directory}/WEB-INF/platform">
<fileset dir="${project.build.directory}/temp-unpack/ReportEngine/configuration"/>
<fileset dir="${project.build.directory}/temp-unpack/ReportEngine/plugins"/>
</copy>
<!--copy the lib sub-folder to WEB-INf/lib-->
<copy todir="${project.build.directory}/WEB-INF/lib">
<fileset dir="${project.build.directory}/temp-unpack/ReportEngine/lib"/>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Not really answering my own question, responding to Rich Seller above :)
Trying to get this to work with mvn dependency:unpack, the docs say to take it out of the executions node. Not sure if that is the cause of the result, but this ends up with
WEB-INF/lib/ReportEngine/lib
WEB-INF/platform/ReportEngine/configuration
WEB-INF/platform/ReportEngine/plugins
basically the same as my initial war-plugin attempt.
I don't see anything in the docs for depedency-unpack to assist. I'll try again tmrw.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<version>2.3.2</version>
<type>zip</type>
<overWrite>false</overWrite>
<!--may not be needed, need to check-->
<outputDirectory>${project.build.directory}/WEB-INF/lib</outputDirectory>
<includes>ReportEngine/lib/*</includes>
</artifactItem>
<artifactItem>
<groupId>org.eclipse.birt</groupId>
<artifactId>report-engine</artifactId>
<version>2.3.2</version>
<type>zip</type>
<overWrite>false</overWrite>
<!--may not be needed, need to check-->
<outputDirectory>${project.build.directory}/WEB-INF/platform</outputDirectory>
<includes>ReportEngine/configuration/*,ReportEngine/plugins/*</includes>
</artifactItem>
</artifactItems>
</configuration>
</plugin>

Can maven sign not only produced jar, but also dependencies

I managed to create main jar, copy dependencies to a single directory, the only step left is to sign all jars.
I can sign my own produced jar as a part of jar:sign, but how do i sign dependencies?
Thanks
Here are a couple of options:
Use the Maven ant task to run jarsigner from the JDK against all the dependencies.
Use the webstart plugin which can sign all your JARs, even if you aren't using it for the purpose of JNLP-izing your app. I'm using it to actually JNLPize one app.
Look at what the webstart plugin source is doing to iterate over all dependencies and sign them and start a new Maven Plugin/Mojo that does the same thing, sans JNLP.
Onejar your app and its dependencies and just sign that.
add to plug-in config <archiveDirectory>target</archiveDirectory>
If you are using maven-jar-plugin, you can specify which single jar to sign using the "jarPath" setting. The following configuration causes the jar-with-dependencies file to be signed instead of the dependency-less jar file:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>sign</goal>
</goals>
</execution>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- NOTE: The secret key is in shared version control. The
password is in shared version control. This IS NOT
SECURE. It's intended to help avoid accidentally
loading the wrong class, nothing more. -->
<jarPath>${project.build.directory}/${project.build.FinalName}-${project.packaging}-with-dependencies.${project.packaging}</jarPath>
<keystore>${basedir}/keystore</keystore>
<alias>SharedSecret</alias>
<storepass>FOO</storepass>
</configuration>
</plugin>
If you want to sign both, I don't know how to do that with maven-jar-plugin, so you may need to look into the other options mentioned above.
One can also create a single JAR using the maven-assembly-plugin.
Together with the other suggestion by Eric Anderson (of signing another JAR) one can then sign this assembled JAR (instead of the original JAR). Note that the order of the plugin definitions matters here.
It is assumed that sign.keystore.file etc are set elsewhere (e.g. in a profile).
<build>
<plugins>
<!-- It seems that maven-assembly-plugin must be declared before the maven-jar-plugin,
so that it is executed first in the package phase,
and then the signing of the packaged jar can succeed. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifestEntries>
<!-- ... -->
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<jarPath>${project.build.directory}/${project.build.FinalName}-${project.packaging}-with-dependencies.${project.packaging}</jarPath>
<keystore>${sign.keystore.file}</keystore>
<type>${sign.keystore.type}</type>
<storepass>${sign.keystore.storepass}</storepass>
<alias>${sign.keystore.alias}</alias>
<verify>true</verify>
<verbose>false</verbose>
<removeExistingSignatures>true</removeExistingSignatures>
</configuration>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<!-- <addClasspath>true</addClasspath> -->
</manifest>
<manifestEntries>
<!-- ... -->
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>