maven2 use libs in a specific folder during compilation - maven-2

In my project structure there is a folder called /libs which contains all necessary libraries, that my project need during compilation. Is it possible that I told maven2 during the process of compilation to use these libraries instead of dependencies or smth. else?
So I call mvn compile war:war and after that my .war contains the libraries out of the /libs folder.
BR,
mybecks

I suppose you are looking for System Dependencies like
<project>
...
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>2.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/foo-bar-2.0.0.jar</systemPath>
</dependency>
</dependencies>
...
</project>
System dependencies will not be copied into the war file - maybe you can achiev this by putting them into src/main/webapp/WEB-INF/lib directory instead of ${project.basedir}/libs.
DISCLAIMER: I just tried to answer the question and do not recommend the solution for all dependencies.

Related

How to bundle JNLP API with Maven Project

I have a project where I need the JNLP API. I did not find an artifact for that on Maven Central, so I added an external Repository which offers that to my pom. That repository went offline this weekend. This is the second time something like this happened to me.
I know this is pretty much what Maven is not about, but really I just want that tiny jnlp-api-1.5.0.jar file to be
In my SCM (I don't want to roll my own Maven repository for just one dependency).
In the compile scope when the project builds.
Which knobs do I have to turn to accomplish this?
As of JDK 7.0, the JNLP API is being provided by the javaws.jar file in your JRE's lib directory, i.e., ${java.home}/lib/javaws.jar. It is possible to use the maven dependency scope system.
<project>
...
<dependencies>
<dependency>
<groupId>javax.jnlp</groupId>
<artifactId>jnlp-api</artifactId>
<version>7.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/javaws.jar</systemPath>
</dependency>
</dependencies>
...
</project>
You can put the JAR in your local repository using the install-file goal of the maven-install-plugin and reference it as you normally would in your POM. The command would be:
mvn install:install-file -Dfile=/path/to/jnlp-api-1.5.0.jar -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=1.5.0 -Dpackaging=<packaging>
Place this command in a script and check it into your SCM. That way, you (and anyone else working on this project) can install it easily to the local repo.

Using Maven, how can I assemble several modules into one artifact?

We have a mother-ship project with several modules:
foo
+ foo-core
+ foo-resource
+ foo-util
+ foo-whatever
I want to allow developers to include the core, resource, and util modules as dependencies (excluding the -whatever module). I know that I can specify that they include each dependency, but it would be nice to allow for them to just specify something like
<artifactId>foo-sdk</artifactId>
And get everything that they need to develop a foo. This has the added advantage that it gives us the power to add (or remove) what goes into the sdk.
It would be best if foo-sdk was not just a jar with the other jars jammed in it. I'd rather it be a pom that simply points to the other artifacts.
I feel like I've seen this done before but can't find instructions to do it. I checked out Maven Assembly Plugin but it doesn't look like this is its intended use.
You can group dependencies in a project with a packaging of type pom. From the Maven book:
3.6.1. Grouping Dependencies
If you have a set of dependencies
which are logically grouped together.
You can create a project with pom
packaging that groups dependencies
together. For example, let's assume
that your application uses Hibernate,
a popular Object-Relational mapping
framework. Every project which uses
Hibernate might also have a dependency
on the Spring Framework and a MySQL
JDBC driver. Instead of having to
include these dependencies in every
project that uses Hibernate, Spring,
and MySQL you could create a special
POM that does nothing more than
declare a set of common dependencies.
You could create a project called
persistence-deps (short for
Persistence Dependencies), and have
every project that needs to do
persistence depend on this convenience
project:
Example 3.11. Consolidating Dependencies in a Single POM Project
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernateVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernateAnnotationsVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate3</artifactId>
<version>${springVersion}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysqlVersion}</version>
</dependency>
</dependencies>
<properties>
<mysqlVersion>(5.1,)</mysqlVersion>
<springVersion>(2.0.6,)</springVersion>
<hibernateVersion>3.2.5.ga</hibernateVersion>
<hibernateAnnotationsVersion>3.3.0.ga</hibernateAnnotationsVersion>
</properties>
</project>
If you create this project in a
directory named persistence-deps, all
you need to do is create this
pom.xml and run mvn install. Since
the packaging type is pom, this POM
is installed in your local repository.
You can now add this project as a
dependency and all of its dependencies
will be added as transitive
dependencies to your project. When you
declare a dependency on this
persistence-deps project, don't
forget to specify the dependency type
as pom.
Example 3.12. Declaring a Dependency on a POM
<project>
<description>This is a project requiring JDBC</description>
...
<dependencies>
...
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
If you later decide to switch to a
different JDBC driver (for example,
JTDS), just replace the dependencies
in the persistence-deps project to use
net.sourceforge.jtds:jtds instead of
mysql:mysql-java-connector and update
the version number. All projects
depending on persistence-deps will use
JTDS if they decide to update to the
newer version. Consolidating related
dependencies is a good way to cut down
on the length of pom.xml files that
start having to depend on a large
number of dependencies. If you need to
share a large number of dependencies
between projects, you could also just
establish parent-child relationships
between projects and refactor all
common dependencies to the parent
project, but the disadvantage of the
parent-child approach is that a
project can have only one parent.
Sometimes it makes more sense to group
similar dependencies together and
reference a pom dependency. This way,
your project can reference as many of
these consolidated dependency POMs as
it needs. Note
Maven uses the depth of a dependency
in the tree when resolving conflicts
using a nearest-wins approach. Using
the dependency grouping technique
above pushes those dependencies one
level down in the tree. Keep this in
mind when choosing between grouping in
a pom or using dependencyManagement
in a parent POM
Wouldn't this just be another sub-module foo-sdk with packaging pom and dependencies on foo-{core,resource,util}?

Activate profile in depended-on POM?

My company writes companion products for project management software that uses that software's Java API. They release new API versions with new releases of their products, and also point releases for bug fixes etc. We need to support clients using various versions of their software (and by extension, their API). In order to do this without unnecessary code duplication, we have defined profiles in our products that include the necessary dependencies for each API version.
I have a war project built using this technique with the "api70" profile activated, and another project that depends on that war project with a type of pom, in order to pull in the war's dependencies. The problem is that when building this second project, the profile-specific dependencies are not being included, even though I'm defining -Papi70 on the maven command line when building the depending project.
Is there any way to get this to work?
In the war project:
<!-- API 7.0 profile. -->
<profile>
<id>api70</id>
<dependencies>
<dependency>
<groupId>com.bigcompany</groupId>
<artifactId>integrationlibrary</artifactId>
<version>7.0-a</version>
</dependency>
</dependencies>
<properties>
<apiversion>api70</apiversion>
</properties>
</profile>
In the depending project:
<!-- Depend on war as type=pom for dependency mediation. -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>warproject</artifactId>
<version>${warVersion}</version>
<type>pom</type>
</dependency>
Command line used for building depending project:
mvn -P api70 clean package
The resulting build does not include integrationlibrary or any of its transitive dependencies.
I think that your problem doesn't apply to profiles at all. It's about how transitive dependencies work for war packaging. By design they doesn't work :) War archive contain its dependencies in WEB-INF/lib folder or if it is packaged in ear it can share libraries with ear libs. More of the problem you can read on this wiki article. It's about Skinny Wars but topic relates also your problem.
For you interesting is also this JIRA issue.
Quick but not elegant solution is to change packaging form war to pom (or create duplicate pom with pom packaging).
Why don't you create an api70-deps pom project and let your war and dependant project both pull that in, profile activated or otherwise?
This approach works wonders for me... my poms become so much more tidier.

maven-jar-plugin and transitive dependencies

I'm using both the assembly and jar plugins to deploy my application. I'm also using the jar plugin to help me generate the classpath in the manifest file using
<addClasspath>true</addClasspath>
While that seems to work, the problem comes when I try executing the jar (it has a proper main class specified) - it will fail to locate a library that's actually a transitive dependency. So my project A depends on project B, and project B depends on jar C. The assembly plugin will correctly zip up A, B, and C, but the jar plugin did not include C in the manifest, causing a ClassNotFoundException.
I don't see any options in maven-jar-plugin that lets me specify that transitive dependencies are required.
Am I doing it the right way? Anyone else managed to get transitive dependencies generated into the manifest? Maybe I'm doing something wrongly or out of order. Any help appreciated.
i tried to solve the mentioned problem. in my case it worked (maven-jar-plugin v2.2).
i've got a parent project called jarloading that has 3 childs:
main: with dependency to a
a: with dependency to b
b: with dependency to a
after calling
mvn package
publishing it using a deploy script containing
rm -r ~/Desktop/jarloading-bin
mkdir ~/Desktop/jarloading-bin
cp a/target/a-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp b/target/b-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp main/target/main-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
changing to directory
cd ~/Desktop/jarloading-bin
and running
java -jar main-0.0.1-SNAPSHOT.jar
it worked fine.
but actually the point is, how the classpath is listed in manifest file:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: rschmid
Build-Jdk: 1.6.0_07
Main-Class: Main
Class-Path: a-0.0.1-SNAPSHOT.jar b-0.0.1-SNAPSHOT.jar
pom.xml of main project:
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<mainClass>Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>a</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of a project:
...
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of b project contains nothing really special.
and attached source code and binaries:
source code
binaries
I couldn't get the maven-jar-plugin to work, I had to use the maven-assembly-plugin.
Examples:
Brian Fox's Blog (this is the one I followed)
Maven Assembly Plugin Usage Guide
similar example by Scott Leberknight
I kinda managed to resolve by... not actually resolving it. I checked closer and still don't know why some transitive dependencies aren't getting picked up - it seems to skip of them and they end up not getting generated into the MANIFEST.
I dug around a bit and played with the maven-dependency-plugin. Surprisingly, configuring <attach>true</attach> and tying it to the assembly:assembly phase solved the classpath issue.

Maven - add dependency on artifact source

I have two maven modules, one that ends up as a jar, and one war that depends on that jar.
I want the jar module to package it's source code together with the compiled classes in the jar, so that the second module is able to access it. I have tried using the maven-source-plugin, but I am confused as to how to add a dependency on the output of that. It seems that the dependency by default goes to the compiled jar, and not the source-code jar (ending with "-source.jar") that maven-source-plugin creates.
How do I add the "-source.jar" as a dependency, while still preserving the dependency on the compiled sources?
I've not tried this, but I think you need to create two profiles in your project. One which builds the main jar. The other which builds the sources jar. Unfortunately, I'm not exactly sure how you would build that profile. I couldn't find a good example of it so far.
(Accoding to the comments, you don't actually need a profile. You can just use the sources-plugin which will deploy the sources and make them available via the sources classifier)
In theory, you'd use the 2nd profile to attach the sources to the project. This creates a 2nd entry in your repository for the sources using that classifier. Once you install/deploy the sources to your repository, you should be able to include the sources as a dependency by using the classifier tag on the dependency to specify the sources directly.
So you'd have something like this in your webapp POM:
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>myJar</artifactId>
<version>4.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>myGroup</groupId>
<artifactId>myJar</artifactId>
<version>4.0</version>
<type>jar</type>
<classifier>sources</classifier>
</dependency>
</dependencies>
Did you try adding the src directory as a resource directory in the build section? That should copy the source into the jar on build.