Remove file from dependency jar using maven - maven-2

I am trying to remove a file from a dependency jar that I am including in my war file in maven. I am deploying the war to JBoss 5.1 and the jar in question contains a persistence.xml file that I don't want.
Here's what is going on:
my-webapp.war
|
`-- WEB-INF
|
`-- lib
|
`-- dependency.jar
|
`-- META-INF
|
`-- persistence.xml
When I am building my war, I want to remove persistence.xml Any one have any idea if this can be done easily?

You can achieve this with the TrueZIP Maven Plugin.
This should work for your use case:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>remove-a-file-in-sub-archive</id>
<goals>
<goal>remove</goal>
</goals>
<phase>package</phase>
<configuration>
<fileset>
<directory>target/my-webapp.war/WEB-INF/lib/dependency.jar/META-INF</directory>
<includes>
<include>persistence.xml</include>
</includes>
</fileset>
</configuration>
</execution>
</executions>
</plugin>
Also see the examples.

Not available out of the box AFAIK, you'll have to use the Maven AntRun plugin after package to do a few dirty things:
unzip the war in a temp directory
unzip the dependency in another temp directory
delete the file from the dependency
zip the temp directory of the dependency back into a jar
move the dependency back in the temp directory of the war
zip the temp directory of the webapp back into a war
delete the temp directory of the dependency
delete the temp directory of the webapp
The following resources might help
ant task to remove files from a jar
RE: Removing a file from .jar file
Now, if the problem is that JBoss is deploying the persistence unit defined in the persistence.xml (and you don't want that), there might be a better solution. It seems that you can declare files to ignore in a jboss-ignore.txt file, for example:
WEB-INF/lib/dependency.jar/META-INF/persistence.xml
The feature is there, but I've never used it.
See
Excluding persistence.xml from deployment
JBoss5 custom metadata files

I guess you would have to use the maven shade plugin (see link below)
Either build an Über-jar that includes your dependency minus the persistence-xml or just transform the dependency into something new that does not have the persistence.xml.
This should be the way to go:
http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
Sean

Related

Maven: How to add files to the root inside an EAR with maven-ear-plugin?

I need to add 2 XML files inside an EAR generated with maven-ear-plugin.
Unfortunately, I haven't seen a way to add an arbitrary file to an EAR; the documentation of the plugin which reads "The EAR plugin supports the following artifacts: ejb, war, jar, ejb-client, rar, ejb3, par, sar, wsr and har". There's nothing for adding a regular file.
org.apache.maven.plugins
maven-ear-plugin
2.3.1
foo
foo
1.4
lib
${parent.groupId}
foo-web
/foo
org.richfaces.framework
richfaces-api
commons-lang
commons-lang
Many thanks in advance.
In maven-ear-plugin 2.4.2 you can use config elements earSourceDirectory, earSourceExcludes and earSourceIncludes to declare extra files to include in the EAR.
By default you simply place those files to ${basedir}/src/main/application folder.
I had the same issue. I had the ejb.properties file under ejbs/src/main/resources and had used earSourceDirectory and earSourceIncludes to pull the file from the ejbs directory to the ear. However, it did not reliably put it in the lib directory. The EJB does not find it in .; it looks for it in the lib directory.
To fix this, I created the src/main/application/lib directory and created a link to the ejb.properties file. I then removed the earSourceDirectory and Includes properties. Now when I do a mvn clean package, it automatically pulls the properties file and puts it in the lib directory of the ear.
Sorry to be late for #wishihadabettername but I had same issue recently, more I couldn't move the files to include because they were in other folder then earSourceDirectory. I read maven-ear-plugin ear:ear documentation and thought about how to move my release folder on the root of ear.
Binds by default to the lifecycle phase: package.
and
workDirectory - Directory that resources are copied to during the build.
Default value is: ${project.build.directory}/${project.build.finalName}.
Then my submodule pom.xml looks like this:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase> <!-- before package phase -->
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- Work Directory of Ear plugin -->
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
<resources>
<resource>
<!-- my resource folder -->
<directory>release</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Hope it help people from now on

Aggregate Dependencies in a Multi-Module Maven Project

I am trying to figure out how to aggregate my maven dependencies in a multi-module project. For example, if I have:
root pom/project1
root pom/project2
and I run mvn dependency:copy-dependencies, I end up with the dependencies in:
root pom/project1/target/dependency
root pom/project2/target/dependency
What I really want is that if I run the mvn command in the root pom folder, all of the dependencies to be copied to root pom/dependency. Is there a maven property that gets me the output directory of the root pom? (similar to ${project.build.directory})? I realize that I can just copy all the dependency folders to the same place after the fact, but I was hoping for something a little cleaner.
You will have to configure the dependency plugin to copy depdendencies to a particular location. This can be done by the outputDirectory configuration property.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${outputDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
But if you trying to do this for distribution, I'd recommend you create an assembly using the maven assembly plugin
The documentation says:
The Assembly Plugin for Maven 2.0 is primarily intended to allow users to aggregate the
project output along with its dependencies, modules, site documentation, and other files
into a single distributable archive.
What I really want is that if I run the mvn command in the root pom folder, all of the dependencies to be copied to root pom/dependency. Is there a maven property that gets me the output directory of the root pom? (similar to ${project.build.directory})?
No, because modules shouldn't actually be aware of that.
I realize that I can just copy all the dependency folders to the same place after the fact, but I was hoping for something a little cleaner.
The Maven way would to use the Maven Assembly Plugin and a custom descriptor. But if you're not familiar with the Maven Assembly Plugin and its descriptor format, it won't be easy.
A less clean but easier approach would be to configure the Maven Dependency plugin to copy the dependencies into the parent project using a relative path. Something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<configuration>
<outputDirectory>../root_pom/target/dependency</outputDirectory>
</configuration>
</plugin>
But as I said, this introduces tight coupling between modules and the root project which is not good at all (and I wouldn't go further by including the goal invocation as part of the build, modules should remain independent and you should be able to build one module without "checkouting" the parent).

How to Add a File from my source tree to Maven Site

I have a Maven 2 RESTful application using Jersey/JAXB. I generate the JAXB beans from a schema file, where the schema file is in my resources directory, e.g., src/main/resources/foo.xsd.
I want to include foo.xsd file in the generated Maven site for my project, so that clients can see the XML schema when writing RESTful calls.
How can I include foo.xsd in the site?
I could have a copy of the file in src/main/site/..., and then update my site.xml to point to it (or have a .apt whose contents point to it), but I don't like that because I'm still tweaking foo.xsd, and don't want to have to remember to copy it each time I update it. And that's just bad practice.
I also tried having a .apt file that has a link to the foo.xsd which gets copied to the target/classes directory. That works until I do a site:deploy, because that only copies the target/site directory.
Thanks,
Charles
To add resources to your site, you'll have to include them in a resources directory:
.
`-- src
`-- site
`-- resources
`-- foo.xsd
To keep this file in sync with the generated one, you could simply use the maven antrun plugin to copy the generated file from src/main/resources to the above location, for example during the pre-site phase:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>pre-site</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<copy file="src/main/resources/foo.xsd" todir="src/site/resources"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
Finally, add a link to this foo.xsd in your site descriptor (the site.xml file).
Take a look at this link. It describes how to customize navigation and add resources to the Maven generated site.

How to merge module jars to a single jar in Maven2?

I have a maven2 project with several jar modules, build the project will get .jar archives for each module in the directory modules/XYZ/target/XYZ-x.x.x.jar
Now, if my project P is of version P-p.q.r, and I want to generate a single jar P-p.q.r-all.jar with all sub-modules included in, how should I do?
What you want to achive is called uber jar. This module has to have dependecies of all others submodules you want to package into one jar. If you create another submodule that will produce a desired artifact it can be built in reactor with all its dependencies but if it will be a separate project that you have to install all uber jar dependecies.
| parent
| -- submodule1
...
| -- submoduleN
| -- uberjarSubmodule
Uber jar can be done by using:
maven-shade-plugin - in your case you have to remember to exclude transitive dependecies from your modules
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:jmock</exclude>
<exclude>xml-apis:xml-apis</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
maven-assembly-plugin - in this question you'll find a detailed answer
Depends on how you are going to ship this, if your jar is a library that you want other developers to download and use via maven. You should specify these as dependencies in the projects pom.
If you are trying to ship something to an end-user who just wants to grab the binary and use your project, you could try using the assembly plugin to package your project. With this plugin you can package a jar alongside its dependencies. It won't put it all in a single jar file, but assuming you configure the users classpath correctly it shouldn't matter.

How to exclude pom.xml from Maven generated war?

Using Maven war plugin, I generate WAR which includes following directory:
META-INF
-- maven
-- com.abc.def
-- myServlet
-- pom.xml
-- pom.properties
In release, I want to exclude this maven directory. How can I do that?
I tried latest maven-war-plugin (2.1-beta-1), it has configuration "packagingExcludes", but it doesn't work as I wish.
Any suggestions?
I'm not sure but I think that the Maven Archiver (which is mainly used by plugins to handle packaging) can be configured to achieve this.
About the <addMavenDescriptor> element, the Maven Archiver Reference says:
Whether the generated archive will contain these two Maven files:
The pom file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.xml
A pom.properties file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.properties
The default value is true.
So a pom configured like this should do the trick:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
Using the standard Maven packaging you can't omit the file to my knowledge. It is possible however to use the maven-assembly-plugin to construct the war, in this case you have much finer grained control over the contents of the artifact, and can omit the pom.xml.
However I have personally found it useful to keep the pom.xml for diagnostic purposes. It can be handy to know what was used to build and assemble the war when trying to figure out what is wrong with your app.
Update: in a bizarre bit of synchronicity to Pascal's answer, I've just been reading up on the Archiver reference and it appears that this can be done by setting the addMavenDescriptor property to false. Personally I would still avoid doing this for reasons given above. But you may want to change your acceptance to Pascal's answer.
Putting a META-INF folder in a resources directory or in the root of your source directory will destroy the META-INF content created by Maven. For WAR files, putting a META-INF in your web content directory will do the same.
Adding other content to that custom META-INF will override what maven would create.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<warSourceExcludes>pom.xml</warSourceExcludes>
</configuration>
</plugin>
or
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<warSourceExcludes>here/there/everywhere/a/pom.xml</warSourceExcludes>
</configuration>
</plugin>