combination of shade, proguard and appassembler maven plugins - maven

I'm trying to build and obfuscate a multi module project using maven. I use the shade plugin to create a fat jar containing all of my own class files(every module) so that I could obfuscate the fat jar using proguard-maven-plugin and then create executable build output using appassembler plugin. everything works except that the other module dependencies also appear in the appassembler repo dir, which is wrong because the obfuscated classes already exist in the shaded jar.
I've tried defining the other module dependencies as provided and then adding the dependencies for the shade plugin, but the shade plugin seems to ignore them.
this is the relevant part of pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<outputFile>${project.build.directory}/${project.build.finalName}-shaded.${project.packaging}</outputFile>
<artifactSet>
<includes>
<include>${project.groupId}:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-a</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-b</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.13</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<injar>${project.build.finalName}-shaded.${project.packaging}</injar>
<outjar>${project.build.finalName}.${project.packaging}</outjar>
<proguardInclude>proguard.pro</proguardInclude>
<maxMemory>1024m</maxMemory>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<programs>
<program>
<mainClass>my.package.Application</mainClass>
</program>
</programs>
<useWildcardClassPath>true</useWildcardClassPath>
<repositoryLayout>flat</repositoryLayout>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Any ideas are welcome.

I found a solution which is not as convenient as I'd like but its better than removing the other module jars manually. I used assembly plugin to exclude the jars from the build distribution zip.
pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<outputFile>${project.build.directory}/${project.build.finalName}-shaded.${project.packaging}</outputFile>
<artifactSet>
<includes>
<include>${project.groupId}:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.13</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<injar>${project.build.finalName}-shaded.${project.packaging}</injar>
<outjar>${project.build.finalName}.${project.packaging}</outjar>
<proguardInclude>proguard.pro</proguardInclude>
<maxMemory>1024m</maxMemory>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<programs>
<program>
<mainClass>my.package.Application</mainClass>
</program>
</programs>
<useWildcardClassPath>true</useWildcardClassPath>
<repositoryLayout>flat</repositoryLayout>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
descriptor.xml:
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>distribution</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/appassembler</directory>
<excludes>
<exclude>**/module-a-${project.version}.${project.packaging}</exclude>
<exclude>**/module-b-${project.version}.${project.packaging}</exclude>
</excludes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>

I think your issue comes from the fact that the shaded jar and the appassembler are ran during the same phase, package.
I think you should try to modify the phase of the appassembler plugin to:
<phase>post-package</phase>

Related

Using Maven to build c++ in eclipse

My Project consists of multiple Java-Projects, one Java-JNI-C++ Project as a Bridge and one pure C++ Project keeping an algorithm library. I managed to write Maven build configurations for all 3 project kinds. So when I'm calling them on the commandline (Windows 7, 64bit) everything works great.
I do not use any make files or something like this. I use exec-maven-plugin to call my mingw 64bit installation without cygwin (and I also didn't at least knowingly install msys). So 2 pure commandline g++ commands each for the JNA and Library Project.
What I need now for a smooth development workflow is to be able to build and debug the this projects from within Eclipse but using the maven build scripts, since I don't want to put work into my poms and additionally configure the eclipse builder. This should be consistent! Furthermore should the error parsing in Eclipse be konsistent with the output of the maven build.
For my Java projects this works greatly out of the box. Eclipse picks up the maven config and CLEAN and BUILD produces exactly what it should. (Though I see that the Java Builder is still active in the project's properties. Why??). But I cannot get it to work with the CDT.
When I disable the C++ Builder Eclipse just builds with maven (what I want), but the clean commands do not work correctly. Also I get errors marked which are not errors by the compiler. Of course this should be consistent.
Are there tutorials for this use case?
I did not find information on that subject. I'm not sure if I'm generally going into a wrong direction missing best practices or something?!
Since this is my first s.o. question, please feel free to give me also feedback on my question. What I can provide I will ;-)
Some Information:
System Windows 7, 64bit
Eclipse Juno, m2e
Library POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>mylib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MyLib</name>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<versionRange>[1.1.1,)</versionRange>
<goals>
<goal>exec</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>compile-Windows_x64</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>g++</executable>
<workingDirectory>target/cpp/Windows_x64</workingDirectory>
<arguments>
<argument>-Wall</argument>
<argument>-m64</argument>
<argument>-c</argument>
<argument>-DAPI_EXPORT</argument>
<argument>-g3</argument>
<argument>-std=c++0x</argument>
<argument>../../../src/main/cpp/*.cpp</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>link-Windows_x64</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>g++</executable>
<workingDirectory>target</workingDirectory>
<arguments>
<argument>-shared</argument>
<argument>-s</argument>
<argument>-m64</argument>
<argument>-oMyLib_Windows_x64.dll</argument>
<argument>cpp/Windows_x64/*.o</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-resources</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.0</version>
<executions>
<execution>
<id>default-site</id>
<phase>none</phase>
</execution>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
JNI POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>myprog</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MyProg</name>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<versionRange>[1.1,)</versionRange>
<goals>
<goal>copy</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<versionRange>[1.1.1,)</versionRange>
<goals>
<goal>exec</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>get-library-headers</id>
<goals>
<goal>copy</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<fileset>
<directory>../MyLib/target/mylib-0.0.1-SNAPSHOT-dll.zip</directory>
<includes>
<include>headers/*</include>
</includes>
<outputDirectory>${project.build.directory}/myLib</outputDirectory>
</fileset>
</configuration>
</execution>
<execution>
<id>get-library</id>
<goals>
<goal>copy</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<fileset>
<directory>../MyLib/target/mylib-0.0.1-SNAPSHOT-dll.zip</directory>
<includes>
<include>*.dll</include>
</includes>
<outputDirectory>${project.build.directory}</outputDirectory>
</fileset>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>compile-Windows_x64</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>g++</executable>
<workingDirectory>target/cpp/Windows_x64</workingDirectory>
<arguments>
<argument>-Wall</argument>
<argument>-m64</argument>
<argument>-c</argument>
<argument>-g3</argument>
<argument>-std=c++0x</argument>
<argument>-I../../myLib/headers</argument>
<argument>../../../src/main/cpp/*.cpp</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>link-Windows_x64</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>g++</executable>
<workingDirectory>target</workingDirectory>
<arguments>
<argument>-m64</argument>
<argument>-s</argument>
<argument>-oMyProg_Windows_x64.exe</argument>
<argument>cpp/Windows_x64/*.o</argument>
<argument>MyLib_Windows_x64.dll</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-resources</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Thankx
Eclipse does not use the Maven build. Instead it configures the JDT according to your POM. This is done through an M2E (Maven to Eclipse) connector. If you want the same to work for CDT, then you would need an M2E connector for that. I'm not aware of an existing one, so you would have to write an Eclipse plugin for that. See http://wiki.eclipse.org/M2E/Extension_Development for details on how to do that.
Of course, you could also use "execute" instead of "ignore" in your lifecycleMapping in the pom. But that would probably make for a pretty slow build, because the whole build would be triggered on each change. And still this wouldn't "magically" make the errors from Maven appear in your files.

unpack dependency and repack classes using maven?

I am trying to unpack a maven artifact A and repack it into a new jar file in the maven project B.
Unpacking class files from artifact A into:
<my.classes.folder>${project.build.directory}/staging</my.classes.folder>
works fine using this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.test</groupId>
<artifactId>mvn-sample</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${my.classes.folder}</outputDirectory>
<includes>**/*.class,**/*.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
In the same pom I now want to generate an additional jar containing the classes just unpacked:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesdirectory>${my.classes.folder}</classesdirectory>
<classifier>sample</classifier>
</configuration>
</execution>
</executions>
</plugin>
A new jar is created but it does not contain the classes from the:
${my.classes.folder}
its simply a copy of the default project jar. Any ideas?
I have tried to follow this guide:
http://jkrishnaraotech.blogspot.dk/2011/06/unpack-remove-some-classes-and-repack.html
but its not working.
I would suggest you to use the maven-shade-plugin instead.
That will make the unpack-repack in the same invocation.
You could do something like this for example:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>com.test:mvn-sample:1.0.0-SNAPSHOT</artifact>
<includes>
<include>**/*.class</include>
<include>**/*.xml</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
In the sample you have <classesdirectory>, the docs have the element as <classesDirectory>. Case sensitivity matters, I think.

yuicompressor maven plugin and maven-war-plugin

I've been struggling with getting this plugin to play nicely with the maven-war-plugin for a couple of hours now and I thought it was time to ask for help. I have the plugin defined as follows:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<id>compressyui</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<nosuffix>true</nosuffix>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
<jswarn>false</jswarn>
</configuration>
</execution>
</executions>
</plugin>
If I remove nosuffix=true then I can see the compressed/minified -min.js files get into the war as expected, but with this flag on they are being overwritten by the maven-war-plugin (I'm assuming) when it builds the war file. I really need the file names to remain the same though ... does anyone have an idea of what I need to change in order to use the same filenames and still get the minified versions into the final war?
OK. I finally figured this out. You need to define a <webappDirectory> in the yuicompressor plugin that can then be referenced as a <resource> in the maven-war-plugin. In the example below I'm using <directory>${project.build.directory}/min</directory>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<id>compressyui</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<nosuffix>true</nosuffix>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
<webappDirectory>${project.build.directory}/min</webappDirectory>
<jswarn>false</jswarn>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
<configuration>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
<encoding>UTF-8</encoding>
<webResources>
<resource>
<directory>${project.build.directory}/min</directory>
</resource>
</webResources>
</configuration>
</plugin>
Just configure 'warSourceExcludes' on the WAR plugin.
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceExcludes>**/*.css,**/*.js</warSourceExcludes>
</configuration>
</plugin>
I would like to add the configuration which worked for me:
First, to fix m2e complaining about the 'Plugin execution not covered by lifecycle' I added the following in the parent pom taken from this post:
<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>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>compress</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Then in the war pom I put:
<build>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<linebreakpos>300</linebreakpos>
<excludes>
<exclude>**/*-min.js</exclude>
<exclude>**/*.min.js</exclude>
<exclude>**/*-min.css</exclude>
<exclude>**/*.min.css</exclude>
</excludes>
<nosuffix>true</nosuffix>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceExcludes>**/*.css,**/*.js</warSourceExcludes>
</configuration>
</plugin>
</plugins>
</build>
This generates the minified css and js files in the project build target directory while excluding the original files.
I hope this saves someone time.
this is my configuration, and it works fine in my maven web project:
<!-- js/css compress -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<excludes>
<exclude>**/*-min.js</exclude>
<exclude>**/*.min.js</exclude>
<exclude>**/*-min.css</exclude>
<exclude>**/*.min.css</exclude>
</excludes>
<jswarn>false</jswarn>
<nosuffix>true</nosuffix>
</configuration>
<executions>
<execution>
<id>compress_js_css</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- war -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/${project.build.finalName}/resources</directory>
<targetPath>/resources</targetPath>
<filtering>false</filtering>
</resource>
</webResources>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
The approach I use is a bit different.
First, I've configured my IDE to run mvn process-resources before the compilation/packaging. This way the files are created before the war is assembled.
It is very important to set <nosuffix>false</nosuffix> and <outputDirectory>${basedir}/src/main/resources/</outputDirectory> so the files can be created in the same directory without replacing your original source files.
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<preProcessAggregates>false</preProcessAggregates>
<excludes>
<exclude>**/*-min.js</exclude>
<exclude>**/*.min.js</exclude>
<exclude>**/*-min.css</exclude>
<exclude>**/*.min.css</exclude>
</excludes>
<jswarn>false</jswarn>
<nosuffix>false</nosuffix> <!-- VERY IMPORTANT WILL REPLACE YOUR FILES IF YOU SET nosuffix TO TRUE OR DONT SET IT AT ALL -->
<outputDirectory>${basedir}/src/main/resources/</outputDirectory> <!-- by default the plugin will copy the minimized version to target directory -->
<failOnWarning>false</failOnWarning>
</configuration>
<executions>
<execution>
<id>compress_js_css</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
</plugin>
As Jakob Kruse say, you must deal with the *.js, but no *.min.js, so my configurations is below, please notice the use of %regex[] :
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>compressyui</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<nosuffix>true</nosuffix>
<warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
<webappDirectory>${project.build.directory}/min</webappDirectory>
<jswarn>false</jswarn>
<excludes>
<exclude>**/*-min.js</exclude>
<exclude>**/*.min.js</exclude>
<exclude>**/*-min.css</exclude>
<exclude>**/*.min.css</exclude>
<exclude>**/jquery.window.js</exclude>
......
<exclude>**/compile.js</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<packagingExcludes>servlet-api*.jar,target/test-classes/*</packagingExcludes>
<warSourceExcludes>test/**,%regex[.*(!min).js],%regex[.*(!min).css]</warSourceExcludes>
<webResources>
<resource>
<directory>${project.build.directory}/min</directory>
</resource>
</webResources>
</configuration>
</plugin>
Without pom.xml change
mvn net.alchim31.maven:yuicompressor-maven-plugin:compress
To force compress every js and css files and fail if warning
mvn net.alchim31.maven:yuicompressor-maven-plugin:compress \
-Dmaven.yuicompressor.force=true \
-Dmaven.yuicompressor.failOnWarning=true \
For more options:
http://davidb.github.io/yuicompressor-maven-plugin/usage_compress.html

How to place the output jar into another folder with maven?

I'd like to place my output jar and jar-with-dependencies into another folder (not in target/ but in ../libs/).
How can I do that?
You can use the outputDirectory parameter of the maven-jar-plugin for this purpose:
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<outputDirectory>../libs</outputDirectory>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
But as cdegroot wrote, you should probably better not fight the maven way.
If you want to copy the artifact into a directory outside your project, solutions might be:
maven-jar-plugin and configure outputDirectory
maven-antrun-plugin and copy task
copy-maven-plugin by Evgeny Goldin
Example for the copy-maven-plugin is:
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>0.2.5</version>
<executions>
<execution>
<id>deploy-to-local-directory</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<skipIdentical>false</skipIdentical>
<failIfNotFound>false</failIfNotFound>
<resources>
<resource>
<description>Copy artifact to another directory</description>
<targetPath>/your/local/path</targetPath>
<directory>${project.build.directory}</directory>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Another way would be maven-resources-plugin (find the current version here):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-files-on-build</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/[TO-DIR]</outputDirectory>
<resources>
<resource>
<directory>[FROM-DIR]</directory>
<!--<include>*.[MIME-TYPE]</include>-->
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I would do it this way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<copy file="target/${project.artifactId}-exec.jar" tofile="../../docker/${project.artifactId}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This technique worked well for me:
http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</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>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
I specially like the solution using maven-resources-plugin (see here) because is already included in maven, so no extra download is needed, and also is very configurable to do the copy at a specific phase of your project (see here to learn & understand about phases). And the best part of this approach is that it won't mess up any previous processes or build you had before :)
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>/dir/where/you/want/to/put/jar</outputDirectory>
<resources>
<resource>
<directory>/dir/where/you/have/the/jar</directory>
<filtering>false</filtering>
<includes>
<include>file-you-want-to.jar</include>
<include>another-file-you-want-to.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
Of course you can also use interpolated variables like ${baseDir} and other good stuff like that all over your XML. And you could use wild cards as they explain here
Maven dependency plugin is perfectly capable of copying all dependencies and just built artifact in a custom location. Following example will copy all runtime dependencies and a built artifact in a two execution phases.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
<execution>
<id>copy-artifact</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
While documentation of dependency plugin states in its documentation that in order to copy built artifact you have to use any phase after the package phase, that is not true if you are building jars. In that situation you can use package phase. At least in 3.3.0 version of plugin.

multiple assemble results

I need to keep a status created during an artifact proceeding. So I've got the idea to bundle these state into an own zip and unpacking it in the prepare phase. Additional shall be the real result deployed as well. This result is a bundle to created files, valuable within a next artifact.
I'm trying create two result zips, but during deploy the second assembly name is ignored and always myArtifact-version.zip is deployed.
Whats wrong?
Thanks in advance,
Sven
my pom looks like:
<project ...>
<artifactId>myArtifact</artifactId>
<groupId>de.myGroup</groupId>
<packaging>pom</packaging>
...
<dependencies>
<dependency>
<groupId>de.myGroup</groupId>
<artifactId>gen-status</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/config</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
... proceeding generation
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>results</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assemble/bundle-gen-results.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>status</id>
<phase>package</phase>
<goals><goal>single</goal></goals>
<configuration>
<descriptors>
<descriptor>src/assemble/bundle-gen-status.xml</descriptor>
</descriptors>
<finalName>gen-status-${project.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</build>
</project>
The assemblies are:
gen-results.xml:
<assembly ... >
<id></id>
<formats><format>zip</format></formats>
<baseDirectory></baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/export</directory>
<includes>
<include>something.*/**/*.*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
bundle-gen-status.xml
<assembly ... >
<id></id>
<formats><format>zip</format></formats>
<baseDirectory></baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/config</directory>
<includes>
<include>status.file</include>
</includes>
<outputDirectory>classes/scripts</outputDirectory>
</fileSet>
</fileSets>
</assembly>
You can use the attach-artifact goal of build helper maven plugin to achieve this.
This allows me attaching the status file only to the current artifact. But then I'm getting a dependency cycle, when trying to add the status artifact.
<project ...>
<artifactId>myArtifact</artifactId>
<groupId>de.myGroup</groupId>
<packaging>pom</packaging>
...
<dependencies>
<dependency>
<groupId>de.myGroup</groupId>
<artifactId>myArtifact</artifactId>
<classifier>status</classifier>
<version>${project.version}</version>
</dependency>
</dependencies>
...
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/config</outputDirectory>
<includeClassifiers>status</includeClassifiers>
</configuration>
</execution>
</executions>
</plugin>
...
exec
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>status</id>
<phase>package</phase>
<goals><goal>attach-artifact</goal></goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/config/status.file</file>
<type>file</type>
<classifier>status</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>

Resources