In my project , there is a spring XML config that utilizes ehcache to cache method returns.
xml snippet :
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
<ehcache:config configLocation="classpath:ehcache.xml"/>
<ehcache:proxy id="explainRetriever" refId="explainRetrieverImpl">
<ehcache:caching methodName="get*" cacheName="explainCache"/>
</ehcache:proxy>
but in runtime , server complains it cannot find definitions of http://www.springmodules.org/schema/ehcache , I know I have to add "spring-modules-cache.jar" to WEB-INF/lib directory.
But my project is maintained by maven , if I add "spring-modules-cache" to the runtime dependency , it will bring a lot of dependencies to my WAR file , filling my WAR with a lot of unnecessary jars. I just need one declaration in it , not all of its dependencies ...
Is there any way to tell maven not to include its dependencies to the project ?
Or ... another way , when packaging WAR , just copy another prepared spring-modules-cache.jar to WEB-INF/lib , how to do this ? Thanks !
As mentioned, you can use the exclusions mechanism, but that basically means excluding every runtime dependency declared in the dependency's pom, which is not only a pain, but fragile, since you have to keep tracking the dependency's pom to keep your list of exclusions up to date.
An alternative is to mark the dependency as <scope>provided</scope> and then copy the dependency yourself to the war construction directory under 'target' using the dependency:copy plugin goal. By default a war is built in
${project.build.directory}/${project.build.finalName}. See the war plugin for details.
E.g.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-cache</artifactId>
<version>0.8</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
Have a look at this article - basically you need to use exclusions.
Related
I have 2 maven modules. One module builds bunch of zip files using maven-assembly-plugin. Second module needs to include some of the zip files built by the first module in its package. What is the way to do this. Thank you.
The easiest thing would be to deploy the zips to a repository. For the local repository use install:install-file and for central repositories use deploy:deploy-file.
You can declare the zips as dependencies in your second module.
So someone else mentioned to deploy it to your repository. If you're already setup to deploy built artifacts to a repository this is easy, if not, check out http://maven.apache.org/plugins/maven-deploy-plugin/
Next, you need to use a plugin to get the zip file checked out of the repository. You could use shade, or the maven-dependency-plugin. Let's assume maven-dependency-plugin http://maven.apache.org/plugins/maven-dependency-plugin/usage.html
So add this to your maven pom file in the plugins section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>process-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>my.artifact.group.id</groupId>
<artifactId>my-artifact</artifactId>
<version>My-version</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/see</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
Obviously you need to change the specifics of the artifact. That will unzip your zip file into target/see. If you want the actual zip file (which seems like what you were asking for but it's not clear), just change the goal from "unpack" to "copy-dependencies". You might also have to remove the outputDirectory or change some other bit of the configuration. Just play with it to get it where you need it, and see the page on the maven-dependency-plugin I mentioned above for more details.
Hope that helps.
When maven builds a jar it places a pom.xml at META-INF///pom.xml.
This is the original pom of the artifact.
No variables are expanded or inherited and no inherited dependencies are listed.
This makes the information of the production jar dependent on the build environment.
How can the pom inside the jar be configured ?
Best would be some configuration of the maven-jar-plugin.
I had a similar requirement, as I wanted to get all the information that belongs to the parent pom.xml. In others words, I wanted to have, in addition to the "raw" pom.xml, the effective pom inside the JAR generated.
The idea is to use the help:effective-pom plugin and goal during the generation of the JAR, and put it with the pom.xml. This is done with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>effective-pom</goal>
</goals>
<configuration>
<output>${project.build.outputDirectory}/META-INF/maven/${project.groupId}/${project.artifactId}/effective-pom.xml</output>
</configuration>
</execution>
</executions>
</plugin>
(source)
Basically, I have a multi-module project consisting of 5 different modules. One of the modules is kind of the parent module to the other 4, meaning the other 4 need to be built before the 5th, so you could say that each of the 4 modules is a dependency of the 5th. Thus, I've made dependency entries for each of the modules in the 5th module's pom.xml.
However, when I build the project, I don't want those 4 dependencies copied to the "lib" directory of the 5th module. I'd like to specify the directory into which each of them should be placed explicitly.
Is there any way to do this with Maven2?
Thanks for your help,
B.J.
I'm not sure I understood everything (from where does this lib directory come from, when do you want the copy to happen exactly?) but the Maven Dependency Plugin might help, its dependency:copy goal takes an outputDirectory per dependency. Below the sample taken from the Usage page:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>[ groupId ]</groupId>
<artifactId>[ artifactId ]</artifactId>
<version>[ version ]</version>
<type>[ packaging ]</type>
<classifier> [classifier - optional] </classifier>
<overWrite>[ true or false ]</overWrite>
<outputDirectory>[ output directory ]</outputDirectory>
<destFileName>[ filename ]</destFileName>
</artifactItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
Change the lifecycle phase binding according to your needs.
But as I said, this answer is more an hint, maybe using a custom assembly would be more appropriate. If it doesn't help, please provide more details.
My project uses many assemblies, hence I'm interested only in the assemblies.
On executing mvn install apart from the assemblies, I'm getting the default packaged .jar.
How can I avoid this?
I have a pom.xml similar to the one you have provided.
On executing mvn install, I'm getting App1.jar, App2.jar, and snapshot jar containing all contents
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>assemblyone</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App1</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/report.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>assemblytwo</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App2</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/src.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I avoid this snapshot (not sure of the exact term) jar and ensure that only assemblies are created?
I can read your question two ways, I've outlined answers for both below. If neither is correct, can you modify your question with a bit more explanation please.
1) Do you mean you have a project with default (jar) packaging, and you want to avoid the creation of the jar when no assembly is defined? If this is the case, what is the build achieving if no assembly is defined?
2) Do you instead mean that you are running mvn assembly:assembly to generate the assembly and want to know how to get that assembly when running the install goal?
For option 2, you can bind the assembly-plugin to a lifecycle phase to ensure it is always run, if you specify that <appendAssemblyId> should be false, then the assembly will replace the default jar.
For example, this configuration will invoke the assembly plugin during the packaging phase and replace the default jar:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
For option 1, this is actually quite tricky to do. The best I can think of is to specify that the project has pom packaging and configure the project with the executions normally bound to the jar lifecycle in a profile. The lifecycle bindings you'd need to configure are listed in the introduction to the build lifecycle
I'm not sure that you can really do that in a really simple way.
A solution is to call the clean plugin once the build is achieved, by doing that:
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>auto-clean</id>
<phase>package</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
This way, the JAR created in the target/ directory will be deleted at the end of the Maven2 execution.
However, you will have to define another directory to store the assemblies created by Maven2. Otherwise, it will be deleted by the call of the clean plugin... If you want to store them in the directory assemblies-target/, you can add that in the pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
...
<!-- Copy the ZIP in target/ of the ROOT directory. -->
<outputDirectory>assemblies-target</outputDirectory>
</configuration>
...
I think it would be much more clear if you showed us your whole POM and the artifacts that are being built. I can only guess as to what the problem is because your terminology is not what I am familiar with. This is my guess as to the problem: you have a POM configured to generated two assembly JARs, but you get a third JAR for the POM itself. In other words, if your POM's artifactId is MyApp, you are getting a MyApp-1.0.0.jar or similar in addition to the two JARs you actually want.
If that is the case, the problem boils down to that you are using Maven to create multiple artifacts from a single module. Maven is designed to produce only one primary artifact from each module. What I would do is change your POM to have a packaging type of "pom" and give it two modules in a <modules> section named App1 and App2. Create sub-directories under your module, one for each App. Give them each a POM configured for a single assembly, with a packaging type of "jar". Move the code/files/etc. as appropriate into each sub-module so there aren't any remaining in the parent module.
With Maven, if you find yourself generating two artifacts from one module (which you are), you should first consider that you are probably violating a Maven best-practice and rearrange things so you only produce one artifact per module.
Please let me know if this doesn't make sense and I will try to clarify.
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.