how to put dependency in maven not in WEB-INF/lib - maven-2

Is there a way to put dependency of a war not in WEB-INF/lib but in out custom folder?
I'm using Maven 2
Hi, what i need is that from list of dependencies of a war only one artifact should be placed not in WEB-INF/lib but in WEB-INF/bundles/ and others dependencies should be places in WEB-INF/lib
thx
THX to everybody, i can't update to Maven 2.1 so i did it through maven-antrun plugin )

I think what you need to do is make the dependency provided and copy it using mvn copy-dependencies. Here is an example that does that with apache commons / lang:
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copydep</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<inherited>false</inherited>
<configuration>
<includeArtifactIds>commons-lang</includeArtifactIds>
<outputDirectory>$project.build.directory/${project.build.finalName}/web-inf/bundles</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
($project.build.directory/${project.build.finalName} is the work folder that is used to assemble the war)

Maven war plugin supports extensive customization. Not clear from your question, what exactly you want, but this page should hopefully help.

Where do you want to put these libraries? You have to be carefull, as the war structure defines the WEB-INF/lib as the directory for third-parties libraries. All *.jar files located in this directory will be loaded in the Classpath by the container (such as Tomcat).
Changing this directory can be harmful for your application!
That's why I am not aware of a configuration parameter for the Maven WAR Plugin that allow you to change this WEB-INF/lib directory.
If you really know what you are doing, you can try to create your own WAR using an assembly.

Related

How to exclude jars from maven dependency when packaging?

I'm trying to package a jboss AS7.5 module (RedHat EAP 6.4) that includes a valve. That valve requires a binding to the AuthenticatorBase that comes with the tomcat-catalina-x.y.z.jar, which does not (to my knowledge) come as a downloadable module in its own right. So, I need to build that jar into my module, using the maven plugin for packaging with dependencies.
Problem is, the GAV for the dependency, org.apache.tomcat:tomcat-catalina:x.y.z, includes libraries that ARE included in AS, namely the servlet libraries. If I package the catalina dependency, using the maven plugin that does that, I get a bunch of unnecessary jars that break my module at runtime.
Is there a way to
only package the jar(s) I want?
find a different dependency that includes just the tomcat valve (i.e., the jar containing org.apache.catalina.authenticator.AuthenticatorBase) binding?
or, preferably, is there a module that already exists for exactly this purpose, one that I can reference as a module dependency in my module.xml file?
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat-catalina.version}</version>
</dependency>
...
</dependencies>
includes jars: tomcat-catalina, tomcat-servlet, tomcat-juli, tomcat-annotations, etc.
<build>
<plugins>
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default. -->
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
How to get only tomcat-catalina.jar in my packaged module?

how to control the pom.xml inside jar built by maven?

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)

Maven does not resolve a local Grails plug-in

My goal is to take a Grails web application and build it into a Web ARchive (WAR file) using Maven, and the key is that it must populate the "plugins" folder without live access to the internet. An "out of the box" Grails webapp will already have the plugins folder populated with JAR files, but the maven build script should take care of populating it, just like it does for any traditional WAR projects (such as WEB-INF/lib/ if it's empty)
This is an error when executing mvn grails:run-app with Grails 1.1 using Maven 2.0.10 and org.grails:grails-maven-plugin:1.0. (This "hibernate-1.1" plugin is needed to do GORM.)
[INFO] [grails:run-app]
Running pre-compiled script
Environment set to development
Plugin [hibernate-1.1] not installed, resolving..
Reading remote plugin list ...
Error reading remote plugin list [svn.codehaus.org], building locally...
Unable to list plugins, please check you have a valid internet connection: svn.codehaus.org
Reading remote plugin list ...
Error reading remote plugin list [plugins.grails.org], building locally...
Unable to list plugins, please check you have a valid internet connection: plugins.grails.org
Plugin 'hibernate' was not found in repository. If it is not stored in a configured repository you will need to install it manually. Type 'grails list-plugins' to find out what plugins are available.
The build machine does not have access to the internet and must use an internal/enterprise repository, so this error is just saying that maven can't find the required artifact anywhere. That dependency is already included with the stock Grails software that's installed locally, so I just need to figure out how to get my POM file to unpackage that ZIP file into my webapp's "plugins" folder.
I've tried installing the plugin manually to my local repository and making it an explicit dependency in POM.xml, but it's still not being recognized. Maybe you can't pull down grails plugins like you would a standard maven reference?
mvn install:install-file -DgroupId=org.grails -DartifactId=grails-hibernate -Dversion=1.1 -Dpackaging=zip -Dfile=%GRAILS_HOME%/plugins/grails-hibernate-1.1.zip
I can manually setup the Grails webapp from the command-line, which creates that local ./plugins folder properly. This is a step in the right direction, so maybe the question is: how can I incorporate this goal into my POM?
mvn grails:install-plugin -DpluginUrl=%GRAILS_HOME%/plugins/grails-hibernate-1.1.zip
Here is a copy of my POM.xml file, which was generated using an archetype.
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.samples</groupId>
<artifactId>sample-grails</artifactId>
<packaging>war</packaging>
<name>Sample Grails webapp</name>
<properties>
<sourceComplianceLevel>1.5</sourceComplianceLevel>
</properties>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.grails</groupId>
<artifactId>grails-crud</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.grails</groupId>
<artifactId>grails-gorm</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>oscache</artifactId>
<version>2.4</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--
<dependency>
<groupId>org.grails</groupId>
<artifactId>grails-hibernate</artifactId>
<version>1.1</version>
<type>zip</type>
</dependency>
-->
</dependencies>
<build>
<pluginManagement />
<plugins>
<plugin>
<groupId>org.grails</groupId>
<artifactId>grails-maven-plugin</artifactId>
<version>1.0</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>init</goal>
<goal>maven-clean</goal>
<goal>validate</goal>
<goal>config-directories</goal>
<goal>maven-compile</goal>
<goal>maven-test</goal>
<goal>maven-war</goal>
<goal>maven-functional-test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${sourceComplianceLevel}</source>
<target>${sourceComplianceLevel}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is a tricky problem. I was going to suggest using Grails 1.3, which allows you to pull Grails plugins from Maven-compatible repositories, but I don't think this helps with Maven (at the moment).
So, I'm going to suggest something I haven't tried myself, but may work. I have some confidence because I wrote the relevant code in the Grails Maven plugin ;) No guarantees though.
With that out of the way, let's get started. First, you need to grab the code for the relevant Grails plugins. For example, you can get Hibernate from here:
http://svn.codehaus.org/grails/trunk/grails-plugins/grails-hibernate/tags/RELEASE_1_1/
You just need a copy of the code, so a read-only checkout will be fine.
Once you have the code, run mvn grails:create-pom -DgroupId=org.grails.plugins from the root of the plugin project. This will generate a POM. Next, you will need to edit the POM and change the packaging to "grails-plugin". You should also be able to remove the <executions> block from the Grails Plugin configuration.
The POM will now allow you to build and package the Hibernate plugin, but you still have to deploy it. So add your local repository to the POM's distribution management and run mvn deploy. Once that's done, you should be able to add the plugin as a standard dependency in your application's POM.
It's hard work, but at least you should only have to do it once per version of the plugin!
I was able to come up with a workaround just to get up and running.
This requires Grails be installed locally and that GRAILS_HOME be set. It will clear out and then populate the project's "plugins" folder during the maven "validate" phase. (Insert this into the POM above.)
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- clear out this project's plugins folder if it exists, otherwise you will get prompted to upgrade it after re-building -->
<delete dir="${basedir}/plugins/" includeemptydirs="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.grails</groupId>
<artifactId>grails-maven-plugin</artifactId>
<version>1.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>create plugins folder</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginUrl>${env.GRAILS_HOME}/plugins/grails-hibernate-1.1.zip</pluginUrl>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

Maven 2 assembly with dependencies: jar under scope "system" not included

I am using maven-assembly plugin to create a jar of my application, including its dependencies as follows:
<assembly>
<id>macosx</id>
<formats>
<format>tar.gz</format>
<format>dir</format>
</formats>
<dependencySets>
<dependencySet>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
(I omitted some other stuff that is not related to the question)
So far this has worked fine because it creates a lib directory with all dependencies. However, I recently added a new dependency whose scope is system, and it does not copy it to the lib output directory. i must be missing something basic here, so I call for help.
The dependency that I just added is:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/external/jchart2d-3.1.0.jar</systemPath>
</dependency>
The only way I was able to include this dependency was by adding the following to the assembly element:
<files>
<file>
<source>external/jchart2d-3.1.0.jar</source>
<outputDirectory>lib</outputDirectory>
</file>
</files>
However, this forces me to change the pom and the assembly file whenever this jar is renamed, if ever. Also, it seems just wrong.
I have tried with <scope>runtime</scope> in the dependencySets and <include>sourceforge.jchart2d:jchart2d</include> with no luck.
So how do you include a system scoped jar to your assembly file in maven 2?
Thanks a lot
I'm not surprised that system scope dependencies are not added (after all, dependencies with a system scope must be explicitly provided by definition). Actually, if you really don't want to put that dependency in your local repository (for example because you want to distribute it as part of your project), this is what I would do:
I would put the dependency in a "file system repository" local to the project.
I would declare that repository in my pom.xml like this:
<repositories>
<repository>
<id>my</id>
<url>file://${basedir}/my-repo</url>
</repository>
</repositories>
I would just declare the artifact without the system scope, this is just a source of troubles:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
</dependency>
I'm not 100% sure this will suit your needs but I think it's a better solution than using the system scope.
Update: I should have mentioned that in my original answer and I'm fixing it now. To install a third party library in the file-based repository, use install:install-file with the localRepositoryPath parameter:
mvn install:install-file -Dfile=<path-to-file> \
-DgroupId=<myGroup> \
-DartifactId=<myArtifactId> \
-Dversion=<myVersion> \
-Dpackaging=<myPackaging> \
-DlocalRepositoryPath=<path-to-my-repo>
You can paste this as is in a *nix shell. On windows, remove the "\" and put everything on a single line.
Btw you can automate it and make it a part of your maven build. The following will install your jar into your local repository before compilation:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>validate</phase>
<configuration>
<file>${basedir}/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
I find easy solution in case you creating jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>dependencies/mydep</directory>
<targetPath>WEB-INF/lib</targetPath>
<filtering>true</filtering>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
You can also handle this via adding a supplemental dependencySet in your dependencySets.
<dependencySet>
<scope>system</scope>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
The best thing would be to use a Repository Manager (like Nexus, Artifactory, Archiva) and install this kind of dependency in a particular repository. After that you can use such things as a simple dependency. This will simplify your life.
Docs:
Edited: Sorry that i didn't realize alx also mentioned about the clean life cycle workaround.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>clean</phase>
<configuration>
<file>${basedir}/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
Base on the solution provided by alx, you can execute the install file step at clean phase. but since the clean phase is not in the default life cycle, you have to execute mvn clean at the first time to ensure the jar is ready in the local repo.
ex: mvn clean; mvn package
A simple solution for this is to add it into local maven repository
One way to do is via mvn install commands as suggested in previous post .
Another easy way is ,
1) In your eclipse ide right click on project select Maven option .
2) Select Install or deploy an artifact to a maven repository option and click on next.
3)Click on browse next to the Artifact file checkbox & select your jar file
4)Enter the GroupId and ArtifactId and version ensure generate pom & create checksum are checked & packaging is jar
Click on finish and that's it ! Your job is done the jar is added in your local repository which you can define in setting.xml or m2 directory
Now just add the simple maven dependency as per the GroupId,ArtifactId & jar version that you have entered as per the import and that's it your external jar will be packaged by maven.
it has worked in a easier way on my solution :
remove from your dependency :
<dependency>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
</dependency>
Then add the maven-install-plugin in the pom.xml as well.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-external</id>
<phase>clean</phase>
<configuration>
<file>${basedir}/external/tiago.medici-0.0.1.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>

Building a WAR project with unzipped JAR dependency?

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.