spikemanuk
spikemanuk

Reputation: 532

Different dependency scope for webapp and standalone java app

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

Answers (3)

spikemanuk
spikemanuk

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

Jean-R&#233;my Revy
Jean-R&#233;my Revy

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

Raghuram
Raghuram

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

Related Questions