ant war plugin trying to exclude folders - maven

Hi I am using ant war plugin and trying to exclude a folder from teh war. however this is not being excluded.
Here is the structure
XYZ
src
main
webapp
web-inf
web.xml
common
api
a.js
b.js
My build.xml for target = production looks like this, i am try to exclude teh common folder. However I see that it is not excluding it at all
<target name="production" depends="moveresources"
description="Building the Production Directory Content">
<echo message="Creating -> ${workingDirectory}"/>
<war destfile="${workingDirectory}/horizonadmin.war" webxml="${srcDirectory}/WEB-INF/web.xml">
<fileset dir="${webappsrc}"/>
<lib dir="${srcDirectory}/WEB-INF/lib"/>
<classes dir="${srcDirectory}/WEB-INF/classes"/>
<exclude name="common/api/*.js/>
</war>
<echo message="Done Creating -> ${workingDirectory}"/>
</target>
in my pom.xml i have referenced the folder as
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>production</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="unpackfolder" value="${unpack.folder}"/>
<property name="webappsrc" value="src/main/webapp"/>
<property name="srcDirectory" value="${project.basedir}/target"/>
<property name="workingDirectory" value="${PUBLISH_DIR}/production"/>
<ant antfile="${project.basedir}/build.xml" target="production"/>
</target>
</configuration>
</execution>
How can i exclude these js files in my war file? for production mode . I plan to exclude these js files and include a minified js file. any pointers

Include the <exclude> in the <fileset>:
<fileset dir="${webappsrc}">
<exclude name="common/api/*.js" />
</fileset>

The exclude you add directly inside the task not nested into one of the filesets applies to the implicit fileset the task forms when you use the basedir attribute. Without any basedir it doesn't do anything. This may not be mentioned inside the war doc, but inside the linked jar page.
You have to place the exclude inside the fileset that pulls in the files you don't want. lib and classes are filesets with different names (they really only are zipfilesets with hard-coded prefix attributes).

Related

Best practice in deploying a parent pom with "supporting files" (ie an external ant file)

I have a parent pom, deployed to my local artifactory server. This is a parent to several War projects. It uses maven ant run plugin and runs Ant targets defined in an external file called pombuild.xml like this:
<execution>
<id>compile</id>
<phase>deploy</phase>
<configuration>
<target if="project.is.war">
<property name="compile_classpath" refid="maven.compile.classpath"/>
<ant antfile="${ant.file}" target="compileJsp"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
The ant.file property is defined as
<ant.file>${user.home}/.m2/repository/${pom.parent.groupId}/${pom.parent.artifactId}/${pom.parent.version}/pombuild.xml</ant.file>
So I am looking for a way to have maven automatically download pombuild.xml at the same location as the parent pom.
The question is : Is this possible? And if so, is this best practice? Should I be doing it differently?
Some may say that my problem has been answered here but this is not exactly what I want.

Axis wsdl2java maven plugin with xmlbeans doesn't include resources folder

I'm using axis2 to re-generate the client code for an updated webservice that I need to use, for a legacy application.
Being a legacy application I would like to avoid changing the code that has been already written, and re-generate the classes as they were generated who-know-how-many years ago by the eclipse plugin, but this time using maven instead of eclipse.
So I seen that they were generated using axis2 and xmlbeans, and I produced the configuration in the maven plugin:
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.6</version>
<executions>
<execution>
<id>TheirsWs</id>
<goals>
<goal>wsdl2code</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<packageName>it.theirs.ws</packageName>
<wsdlFile>${basedir}/src/main/resources/theirWs.wsdl</wsdlFile>
<generateServerSide>false</generateServerSide>
<databindingName>xmlbeans</databindingName>
<unpackClasses>true</unpackClasses>
</configuration>
</execution>
</executions>
</plugin>
What happen now is a very nice thing.
The plugin generate a .class file in the generated-sources / axis2 / wsdl2code / resource folder, However it is not added by maven to the final package, causing a ClassNotFoundException when calling the webservice.
I solve the problem by adding the resource folder into the JAR using the maven default feature of including and excluding folder. The solution for your case will be:
<build>
<!-- This will the MAVEN to copy the entire folder, you can copy only the .class files -->
<resources>
<resource>
<directory>${project.build.directory}/generated-src/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.5.6</version>
<executions>
<execution>
<id>TheirsWs</id>
<goals>
<goal>wsdl2code</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<packageName>it.theirs.ws</packageName>
<wsdlFile>${basedir}/src/main/resources/theirWs.wsdl</wsdlFile>
<generateServerSide>false</generateServerSide>
<databindingName>xmlbeans</databindingName>
<!-- I add this line just to be easy to referenciate the souce -->
<outputDirectory>${project.build.directory}/generated-src</outputDirectory>
<unpackClasses>true</unpackClasses>
</configuration>
</execution>
</executions>
</plugin>
Had the same problem, i changed the Ant build.xml buildfile from:
<target depends="pre.compile.test" name="compile.src" if="jars.ok">
<javac debug="on" memoryMaximumSize="256m" memoryInitialSize="256m" fork="true" destdir="${classes}" srcdir="${src}">
<classpath refid="axis2.class.path"/>
</javac>
</target>
To:
<target depends="pre.compile.test" name="compile.src" if="jars.ok">
<javac debug="on" memoryMaximumSize="256m" memoryInitialSize="256m" fork="true" destdir="${classes}" srcdir="${src}">
<classpath refid="axis2.class.path"/>
</javac>
<copy todir="${classes}">
<fileset dir="${resources}"/>
</copy>
</target>
The new Copy task add all the resources to the target classes folder so the generated Jar will include them.
Hope it helps.

Maven and Ant plugin to copy resources intelligently

It's easy to use org.apache.maven.plugins:maven-antrun-plugin to copy resources and rename them but is there a way to do this intelligently with wildcards or other mecanisms to conform personnal rules ?
For example if I have those files :
${project.artifactId}-${project.version}.swf
a.swf
b.swf
...
z.swf
I would like to copy all those files inside directory and rename only ${project.artifactId}-${project.version}.swf to foo.swf. I know I can use :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy-swf-files</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="copy swf files to web project">
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.swf" tofile="${swf.output.location}/foo.swf" />
<copy file="${project.build.directory}/a.swf" tofile="${swf.output.location}/a.swf" />
<copy file="${project.build.directory}/z.swf" tofile="${swf.output.location}/z.swf" />
</target>
</configuration>
</execution>
</executions>
</plugin>
it's work but is there another convenient way to do that because if I have 1000 files to copy, it will be very boring...Thanks
Do you know Ant? All the Maven Ant plugin is doing is calling Ant with the tasks you list. You can do any Ant task including <taskdef>, etc.
What it looks like you're doing can be done with fileset:
<copy todir="${swf.output.location}">
<fileset dir="${project.build.directory}">
<include name="*.swf"/>
</fileset>
</copy>
This will copy all *.swf files located directly under in the ${project.build.directory} (and no subdirectories) to the ${swf.output.location} directory. If you want to copy the entire directory tree of *.swf files, just change the <include>:
<copy todir="${swf.output.location}">
<fileset dir="${project.build.directory}">
<include name="**/*.swf"/> <!--NOTE DIFFERENCE HERE-->
</fileset>
</copy>
If you need to munge the file names, you can use Mappers. The simplest mapper would be the flatten mapper:
<copy todir="${swf.output.location}">
<fileset dir="${project.build.directory}">
<include name="**/*.swf"/> <!--NOTE DIFFERENCE HERE-->
</fileset>
<mapper type="flatten"/>
</copy>
This will copy the entire directory tree and flatten all the files into a single directory. There are mappers that can match globs, regular expressions, and even scripting.
The <include> is a selector and not a mapper because it selects what files you want to act upon. These too can be quite complex, and you can match file based upon their names iva regular expressions, or even their contents.
I'm surprised there isn't a Maven plugin that allows you to do this.
Ok I finally used this plugin to do this :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy-swf-files</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="copy swf files to web project">
<copy todir="${swf.output.location}">
<fileset dir="${project.build.directory}" includes="*.swf">
<filename regex="^sim-flex.*"/>
</fileset>
<mapper type="regexp" from=".*" to="sim.swf"/>
</copy>
<copy todir="${swf.output.location}" >
<fileset dir="${project.build.directory}" includes="*.swf">
<not>
<filename regex="^sim-flex.*"/>
</not>
</fileset>
</copy>
</target>
</configuration>
</execution>
</executions>
</plugin>
Use maven-assembly-plugin with assembly descriptor of "dir" "formats/format", a "fileSets/fileSet" which will copy majority of swf's excluding the special swf, and a "files/file" which will copy that one swf to a file with different name.

Modify files inside multiple zip files using Maven

Today I wanted to perform this task, and I run across some issues in the way. So I present here my problem and the solution I found. Perhaps somebody knows a simpler solution!
The problem was this: I was trying to build a distribution package of a Java project which is built with Maven2. In a previous step, several zip files all containing a file named manifest.xml in the root were generated, and I wanted to modify this XML file in all this ZIP files. This is a scheme:
package-file-1.zip
|- contents(DIR)
\- manifest.xml
package-file-2.zip
|- contents(DIR)
\- manifest.xml
This example modifies the zip files in ${zip.sourcedir} replacing the string & with & in the file manifest.xml of all this zip files and places the modified zip files in the directory target.
For that, it uses the maven-antrun-plugin including the for and var tasks from the antcontrib tasks(http://ant-contrib.sourceforge.net). This permits to unzip the contents of every zip file into a separate directory. Note also the use of the task basename to extract the name of the zip files out of their path.
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy-and-repair-zips</id>
<phase>initialize</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef resource="net/sf/antcontrib/antlib.xml" classpathref="maven.plugin.classpath"/>
<for param="filepath">
<path>
<fileset dir="${zip.sourcedir}" includes="**/*.zip"/>
</path>
<sequential>
<var name="for.filename" unset="true" />
<basename property="for.filename" file="#{filepath}" />
<unzip src="#{filepath}" dest="target/repair-temp/${for.filename}" encoding="UTF8" />
<replace file="target/repair-temp/${for.filename}/manifest.xml" token="&" value="&amp;" encoding="UTF8" />
<zip basedir="target/repair-temp/${for.filename}" destfile="target/${for.filename}" encoding="UTF8" />
</sequential>
</for>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
In order to write this solution, I got the needed knowledge from this URLs:
Modify a JAR(or ZIP) file using Ant: How do I modify a file in a jar file using ANT?
Unzip multiple files into separate directories: http://grokbase.com/t/ant.apache.org/user/2004/01/re-how-to-unzip-multiple-file-into-separate-directories/122a5ezxhh6eolf5enkrdfgryika
Use ant-contrib in Maven2: http://docs.codehaus.org/display/MAVENUSER/Antrun+Plugin
But be careful to use net/sf/antcontrib/antlib.xml instead of net/sf/antcontrib/antcontrib.properties to be able to use the for task
Use the ant-contrib var task: http://www.jguru.com/forums/view.jsp?EID=1374074
Edit
After posting the question, I was able to find a couple of questions related, that could help if one is having problems implementing a similar thing:
maven3 - maven-antrun-plugin - "failed to create task or type if"
Using antcontrib <if> task via maven-antrun-plugin

Idea to avoid that spring.handlers/spring.schemas get overwritten when merging multiple spring dependencies in a single jar

I got the error Unable to locate NamespaceHandler when using context:annotation-config running (java -jar) a jar assembled by the maven-assembly-plugin and containing my project and all its dependencies.
As other people correctly spotted on the forum.springsource.org thread (message #7/8) the problem occurs because the files META-INF/spring.handlers and META-INF/spring.schemas that are present in different jars, get overwritten when the maven-assembly-plugin repackages the jars in a single file.
Looking at the content of two spring-*.jar files you can see the files sits in the same position relatively to the classpath
$ jar tf spring-oxm-3.0.3.RELEASE.jar
META-INF/spring.handlers
META-INF/spring.schemas
org/springframework/oxm/GenericMarshaller.class
...
$ jar tf spring-context-3.0.3.RELEASE.jar
META-INF/spring.handlers
META-INF/spring.schemas
org/springframework/context/ApplicationContext.class
Isn't it is possible to put the META-INF folder in a specific package? If so the idea I'd suggest, (hope it's applicable) is to put the META-INF/spring.shemas and META-INF/spring.handlers files under the package they refer to.
$ jar tf spring-oxm-3.0.3.RELEASE.jar
org/springframework/oxm/META-INF/spring.schemas
org/springframework/oxm/META-INF/spring.handlers
org/springframework/oxm/GenericMarshaller.class
...
$ jar tf spring-context-3.0.3.RELEASE.jar
org/springframework/context/META-INF/spring.handlers
org/springframework/context/META-INF/spring.schemas
org/springframework/context/ApplicationContext.class
This way they won't conflict when merged in a single jar. What do you think about it?
I managed to get rid of the bug using the shader plugin instead of the (buggy) assembler plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>at.seresunit.lecturemanager_connector.App</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
I think I found the solution on the springsource forums.. it has been quite some time since I looked it up.. can't really remember the author. Kudos to him anyways :p
cheers
With Ant.
<!--define couple of properties to identify spring jar files-->
<property name="spring-beans-jar" value="spring-beans-4.0.5.RELEASE.jar"/>
<property name="spring-context-jar" value="spring-context-4.0.5.RELEASE.jar"/>
<!--other properties-->
<target name="dist" depends="compile" description="Prepare distribution">
<!--dump spring-context into build classes (or some place else)-->
<unjar src="${lib.dir}/${spring-context-jar}" dest="${build.classes.dir}"/>
<!--dump spring-beans on top of it overwriting META-INF/spring.* files-->
<unjar src="${lib.dir}/${spring-beans-jar}" dest="${build.classes.dir}"/>
<!--get overwritten META-INF/spring.* files of spring-context to some other place-->
<unjar src="${lib.dir}/${spring-context-jar}" dest="${build.tmp.dir}">
<patternset>
<include name="META-INF/spring.handlers"/>
<include name="META-INF/spring.schemas"/>
<include name="META-INF/spring.tooling"/>
</patternset>
</unjar>
<!--skipped spring-beans/META-INF/spring.factories as its not present in spring-context-->
<!--handled only spring-context and spring-beans as that's what I needed at this point-->
<!--append content from spring-context/META-INF/spring.* files-->
<concat destfile="${build.classes.dir}/META-INF/spring.handlers" append="true">
<filelist dir="${build.tmp.dir}" files="META-INF/spring.handlers"/>
</concat>
<concat destfile="${build.classes.dir}/META-INF/spring.schemas" append="true">
<filelist dir="${build.tmp.dir}" files="META-INF/spring.schemas"/>
</concat>
<concat destfile="${build.classes.dir}/META-INF/spring.tooling" append="true">
<filelist dir="${build.tmp.dir}" files="META-INF/spring.tooling"/>
</concat>
<jar destfile="${build.dist.dir}/application.jar">
<fileset dir="${build.classes.dir}"/>
<!--include all .jar files except already extracted ones-->
<zipgroupfileset dir="${lib.dir}" includes="*.jar"
excludes="${spring-beans-jar}, ${spring-context-jar}"/>
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>

Resources