How to include resources from war to another maven project - maven

I have a maven project , which needs to copy webapp/WEB-INF/ resources from another maven project which is packaged as a war .
How do I do it ?
PLease suggest

As Bittrance said, you should use the maven dependency plugin.
The better way is to create project that include all your shared resources, probably a type zip, which is build up with the assembly plugin. This is the good "maven way". It's a better solution than unpacking a war.
Then, refer it
<dependency>
<groupId>com.mygroup/groupId>
<artifactId>my-dependencies</artifactId>
<version>1.0.0</version>
<type>zip</type>
</dependency>
Next, you use the maven dependency plugin to unpack your resources, in the directory of your choice (probably WEB-INF/ ?)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-cfg-test-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/WEB-INF/</outputDirectory>
<includeArtifacIds>my-resources</includeArtifacIds>
<excludeTypes>pom</excludeTypes>
<excludeTransitive>true</excludeTransitive>
</configuration>
</execution>
</executions>
</plugin>
I'm not realy sure of this code snippet (written for another purpose), but this is an example.
For more information, please follow this link : http://maven.apache.org/plugins/maven-dependency-plugin/
If you can't shared a common-project including your files, you can unpack war including only ftl (or whatever you want), but it's not a realy clean solution ;)
There is a lot of posts that deal with this subject :
Unzip dependency in maven
...
Just try with the keywords maven-dependency-plugin, unpack :)
Hope that will help you.

I can see some alternatives:
Use external references in your version control system to point all repos to the same files.
The Maven Dependency module can copy and unpack project dependencies. From there, you can use the Maven Assembly plugin (or Ant targets) to include parts of that dependency in your own installation.
At least for the FTL files, perhaps you could package them in a separate Jar file and then load them as resources through the class loader.
If the resources are filtered, you may get into problem with solution 1 if you want the filtered version and 2, 3 if you want the source version.
Hope this helps.

(This assumes your dependent project is java (jar) and not another web app, if it is a webapp I think the solution is similar).
I suggest a (slightly) different approach:
Instead of reading resources from war, add this to your war pom, to generate a jar in the artifact as well as a war:
<!-- maven war plugin config -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<configuration>
...
<attachClasses>true</attachClasses>
<classesClassifier>some-string</classesClassifier>
</configuration>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>
...
<resources>
<!-- This is for inclusion in the jar, so dependent module can load it -->
<resource>
<targetPath>some-path</targetPath>
<directory>src/main/webapp/path...</directory>
<includes>
<include>your-resource</include>
</includes>
</resource>
</resources>
And this to your consuming pom, so the generated jar will be loaded:
<dependency>
<groupId>com.company</groupId>
<artifactId>...</artifactId>
<classifier>some-string</classifier>
</dependency>
Then you will be able to load the resources the usual way (getResourceAsStream("some-path/your-resource"))

Related

Maven dependencies from parallel projects, not modules.

I have following maven projects (note : maven project, not maven modules). I know i will get questions, why not modules, but it has its own story, anyway.
myproj-common (JAR),
myproj-core (JAR),
myproj-product1-batch (EAR),
myproj-product2-batch (EAR)
myproj-core depends on myproj-common, and myproj-product1-batch depends on myproj-core.
If it is modules, i can simply create dependency. It if is standard archive, I can also create dependency and have JAR available in repository, if it is a library JAR, I can ...bla bla bla ...all standard dependency I can fix, I am not sure how to make a jar that is sitting somewhere on the disk, a dependency.
I am not able to get
C:\Documents and Settings\users\myproj-common\target\myproj-common-0.0.1-SNAPSHOT.jar
into following jar, as a dependency
C:\Documents and Settings\users\myproj-core\target\myproj-core-0.0.1-SNAPSHOT.jar
same problem for the JAR into EARs.
Any idea ? How ...hoping a small, quick and surprising fix, just not visible to me.
I don't see any reason why you shouldn't be able to use mvn install to install these jars and ears into your local repository. Then, you can just include them as dependencies anywhere you like.
I doubt that you'll be able to cleanly get maven to pull in a jar sitting anywhere on your filesystem other than your local repository.
To clarify, when you do mvn install it puts your JAR in the target folder, but it also puts it into your local repository (C:\Documents And Settings\.m2 by default in Windows). After that JAR is installed there, you can include that JAR in other projects as a maven dependency using a "dependencies" block in your pom like this:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
The dependencies mechanism is explained in the Maven Docs.
In addition, you'll need to tell maven to actually package all dependencies in the JAR. You can do that by adding this to your POM. (Also check this question How can I create an executable JAR with dependencies using Maven? for the source of this code block).
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<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>

How to get maven assembly plugin to copy artifact?

I have a Maven assembly script that copies resources to build our app. I need to copy some war files from separate, external projects into a /webapps directory in the output. Can't seem to find the magic commands to do it.
I tried adding a dependencySet to the assembly with <include com.mygroup:mywarfile>. This works if I add 'mywarfile' as a war dependency in the project with a scope of compile or runtime. Unfortunately, my project produces a war, and the maven-war-plugin includes the external mywarfile as an overlay, which I don't want.
If I set the scope of the external war dependency to provided or test, the assembly fails with the warning:
[WARNING] The following patterns were never triggered in this artifact inclusion filter:
'com.mygroup:mywarfile'
All I want to do is have the assembly copy an artifact from my local repo to the assembly output. How to do it without messing up other parts of the project?
The maven-assembly-plugin is not intended for copying. The better way to copy dependencies is the maven-dependency-plugin which can copy dependencies etc. If you a talking about deployment into Tomcat etc. than you should take a deeper look into carg2-maven-plugin or the tomcat-maven-plugin which seemed to be more appropriate for that task.
I haven't tried this, but you could try using the exclude feature of overlay configuration of maven war plugin to exclude contents of the dependant war file from being included in your war project. Modified snippet from the Overlay documentation,
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<overlays>
<overlay>
<groupId>com.example.projects</groupId>
<artifactId>warToBeExcluded</artifactId>
<excludes>
<exclude>*</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
...

how to add external jar to maven webapp project

I have a Spring roo project (basically a maven project). I want to add dropbox sdk to the project, problem is it's not in maven. I added the following files
<dependency>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/dropbox-java-sdk-1.3.1.jar</systemPath>
</dependency>
It solved the compile error, but when i run the project, in Spring Tool Suite, the jar files are not added to war lib folder. How do I make maven add my external jar files to my the war lib folder?
I don't want to install the jar in maven since, I have to install it in all the machines that uses the project
I finally found a neat solution, which is a lot easier to implement. You add an in-project repository inside the java project and link to it in the pom.
You add an in-project repository in maven like this:
<repository>
<id>in-project</id>
<name>In Project Repo</name>
<url>file://${project.basedir}/libs</url>
</repository>
Then create a folder structure in the root folder of your project that looks something like this
/groupId/artifactId/version/artifactId-version.jar
and add the dependency as you would normally do.
This approach has the least amount of code and work required, and if that library ever gets add into a maven repository you can always remove your in-project repository.
There is a much easier solution, which is set webResource in the plugin. By the solution, you can add any files of your local disk to the war! A sample is as below,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>api</warName>
<webResources>
<resource>
<directory>libs/</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
The best way to resolve this issue is to add these local jar files to WEB-INF/lib folder. You will find all these jars packaged in your final war file then.
I don't recommend this approach, but you could add some POM configuration to install the 3rd-party dependency in a separate profile:
<profiles>
<profile>
<id>install-dependencies</id>
<build>
<plugins>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>install-dropbox-sdk</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
<file>src/main/lib/dropbox-java-sdk-1.3.1.jar</file>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.dropbox</groupId>
<artifactId>dropbox-sdk</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</profile>
</profiles>
There are two profiles here: install-dependencies and build. The first installs the dropbox-sdk dependency into your Maven repository and needs to be run once on every machine as follows:
mvn -Pinstall-dependencies validate
The second is enabled by default, and adds the Dropbox SDK as a dependency.
To be honest though, this isn't much better than running
mvn install:install-file -Dfile=src/main/lib/dropbox-java-sdk-1.3.1.jar -DgroupId=com.dropbox -DartifactId=dropbox-sdk -Dversion=1.3.1 -Dpackaging=jar
on every machine.
The other downside of this approach is that you'll have to add all dependencies of the dropbox-sdk to your build as well- whereas if it is done properly by adding the JAR and a POM to a repository server, then Maven will calculate the transitive dependencies properly.
I recommend creating a "third party" repository in a Maven repository server such as Nexus or Artifactory, and uploading the jar to there. Even though that means putting the jar into Maven, at least with a repository server it is available to anyone who will be building your application.
change the lib path to :
src/main/webapp/WEB-INF/lib
in pom.xml:
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/xxxx.jar</systemPath>
The steps described in this site are pretty simple, and they work well enough:
https://mythinkpond.com/2010/10/02/adding-custom-jars-under-web-inflib-in-a-maven-project/
Create a “lib” folder under your project like this: “\src\main\webapp\WEB-INF\lib”
Copy needed “jars” etc that you want included inside your WAR bundle folder.
Invoke your maven build as you normally do. I use “mvn install”, which creates builds the war file.
I know I am really late but I was wondering on why you would not put in the jar in the local repo in the .m2 file and add a reference to the pom from there ?

Exclude all the jar's from webapp/WEB-INF/lib

I have the third party jar's in my WEB project placed at /src/main/webapp/WEB-INF/lib/
I have mentioned the dependency for all the required JAR's in the pom.xml.
Now, Since the dependencies are defined in POM, the JAR's will be automatically packed in the lib folder.
I want to exclude all the JAR's in the lib.
The Dependency JAR's should be packaged inside the lib while building the WAR
I CANT DELETE THE LIB FROM WEB-INF BECAUSE ITS USED IN LOCAL DEVELOPMENT
This is what I've tried so far:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>META-INF/context.xml</packagingExcludes>
<webResources>
<resource>
<directory>src/main/webapp/WEB-INF/lib</directory>
<excludes>
<exclude>**/**</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
Any Idea?
It should be "packagingExcludes" instead of "warSourceExcludes":
<configuration>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
....
</configuration>
From http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html :
In version 2.1-alpha-1, this was incorrectly named warSourceExcludes
Try this:
<configuration>
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
....
</configuration>
However, I do agree with Jarrod that it is bad practice to store your jars in WEB-INF/lib 'manually'. I used this before to avoid that jars coming as a dependency got packaged to be able to repackage it afterwards.
you shouldn't have anything in your WEB-INF/lib directory to begin with. If you are using Eclipse, you can tell it to build its project from the pom.xml and it will know to look in ~/.m2/repository for dependencies, Intellij IDEA does this as well. Putting dependencies in WEB-INF/lib kind of defeats the purpose of using Maven for dependency management. What happens when the dependencies in the pom.xml get out of sync version wise with those in WEB-INF/lib

Maven WAR dependency

I am writing a project for acceptance testing and for various reasons this is dependent on another project which is packaged as a WAR. I have managed to unpack the WAR using the maven-dependency-plugin, but I cannot get my project to include the unpacked WEB-INF/lib/*.jar and WEB-INF/classes/* to be included on the classpath so the build fails. Is there a way to include these files into the classpath, or is there a better way of depending on a WAR?
Many thanks.
There's another option since maven-war-plugin 2.1-alpha-2. In your WAR project:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This creates a classes artifact which you can use in the acceptance tests project with:
<dependency>
<groupId>your-group-id</groupId>
<artifactId>your-artifact-id</artifactId>
<version>your-version</version>
<classifier>classes</classifier>
</dependency>
Indeed, by design, Maven doesn't resolve transitive dependencies of a war declared as dependency of a project. There is actually an issue about that, MNG-1991, but it won't be solved in Maven 2.x and I'm not sure that I don't know if overlays allow to workaround this issue. My understanding of the suggested solution is to duplicate the dependencies, for example in a project of type pom.
(EDIT: After some more digging, I found something interesting in this thread that I'm quoting below:
I have been helping out with the development of the AppFuse project over
the last month where we make heavy use of the war overlay feature in the
Maven war plugin. It is a really nifty feature!
To get max power with war overlays I have developed the Warpath plugin
that allows projects to use war artifacts as fully fledged dependencies.
In brief:
1) The contents of the /WEB-INF/classes directory in the war dependency
artifacts can be included in the project's classpath for normal compile,
etc tasks.
2) Transitive dependencies from the war dependency artifacts become
available for use by other plugins, e.g. compile and ear - so no more
having to include all the dependencies when creating skinny wars!
The plugin has now been actively used in the AppFuse project for the
last few months, and I feel it is at a point where it is both usable and
stable.
Would the war plugin team be interested in including the warpath
functionality inside the war plugin? It would seem to be the most
natural place to host it.
So, I don't have any experience with it, but the maven warpath plugin actually looks nice and simple and is available in the central repo. To use it,include the following plugin configuration element in your pom.xml file:
[...]
<build>
<plugins>
<plugin>
<groupId>org.appfuse</groupId>
<artifactId>maven-warpath-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>add-classes</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
And add the war dependencies you want included in the classpath as warpath type dependencies:
[...]
<dependencies>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>warpath</type>
</dependency>
</dependencies>
[...]
Both the war and warpath dependency types are needed: the war type is used by the Maven war plugin to do the war overlay, the warpath type is used by the Warpath plugin to determine the correct list of artifacts for inclusion in the project classpath.
I'd give it a try.)
Use overlays. First, your test project need to have also packaging war.
Declare dependency of war project you want to test:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>your-project-arftifactId</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
then configure maven-war-plugin overlay:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webresources</directory>
<filtering>true</filtering>
</resource>
</webResources>
<overlays>
<overlay/>
<overlay>
<groupId>your.group</groupId>
<artifactId>your-project-artifactId</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
In the above example in test project I overwrite webresources configuration files (like conxtext etc.).
EDIT: This solution wasn't tested with Maven 3.
Good point, Justin. That got me actually solving my problem, namely: including a war into an assembly AND including all its transitive dependencies.
I could not duplicate the war-dependency as 'jar' as you suggested since the assembly plugin would not find a jar referenced by that groupId/artefactId, but
duplicating the war-dependency as type pom
works!
The war and its transitive dependencies are not included in the assembly.
To exclude the (now also appearing) pom file I had to add an exclude element like this:
<excludes>
<exclude>*:pom</exclude>
</excludes>
into my assembly.xml file.
I think this could also be a workaround for the original question of this thread.
If you list the dependency on the war project as a jar dependency it seems to pickup the required jars/resources. I'm using Maven 2.2 + m2eclipse.

Resources