Reputation: 532
I'm using maven to build a Java web application which is run in Tomcat. Certain JAR files (e.g. mail-1.4.1.jar and database drivers) have been put in tomcat/lib directory and the maven dependency set to "provided". (I'm not 100% sure why, but I think it's something to do with JNDI.)
Now I have built a standalone executable Java program in the same Maven project which I am trying to execute using mvn exec:java
. Unsurprisingly it can't find mail.jar and I get the error java.lang.NoClassDefFoundError: javax/mail/Session
How do I specify javax.mail scope="runtime" for the standalone Java program whilst still being "provided" for the Tomcat app? Do I have to use Maven profiles? If so, where can I find useful documentation on how this works (are the profile's dependencies additive or do they overwrite the default ones etc?)
Upvotes: 1
Views: 659
Reputation: 532
Yes, as Raghuram suggests, creating a profile with a dependency with a different scope works.
<profiles>
<profile>
<id>standalone</id>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Elsewhere the artifact is declared with provided scope, as needed by the web app.
Run using:
mvn exec:java -Dexec.mainClass=XXX -Pstandalone
But I'm not convinced that using profiles is the right answer.
Upvotes: 0
Reputation: 5677
The Raghuram answer is correct, but I want to point out something.
As Sonatype wrote it in its blog : http://www.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/
I want to be very clear about this answer. We strongly recommend that you not configure a Maven project to create two separate JARs from a single project. It violates one of the most important core concepts of Maven: modularity.
What you are doing doesn't seem to be in "The Maven Way". When you start to be stucked with such a problem, you should always think that this is maybe not the right solution you chose.
There is a lot of topic about this kind of issue, around dealing multiple artifacts with one single pom :
Handling multiple artifacts from single maven project
Maven: Attaching multiple artifacts
...
And there is a good one about how deal with multiple environnement profile, as Raghuram suggested : Maven best practice for generating artifacts for multiple environments [prod, test, dev] with CI/Hudson support?
So, I advise you to split your project, thinking about the real realationship between them. It may probably drive you to a multimodule project like
parent
|
+--project:jar
|
+--web-app:war
...
Take a look here : http://www.sonatype.com/books/mvnex-book/reference/multimodule.html
Good luck :)
Upvotes: 2
Reputation: 52655
You can read the introduction to profiles.
The scope of the dependencies declared in the profile will override the default scope when the profile is active. So you should be able to specify <runtime>
scope for the relevant jars within your profile and have it available for your standable app.
Upvotes: 2