Maven cannot exec a jar project because the mess with transitive dependency
I have 5 maven projects: simple-model
, simple-weather
, simple-persist
, simple-webapp
and simple-console
. (They are from the Maven Definitive Guide book).
The simple-console
depends on simple-weather
and simple-persist
. simple-persist
and simple-weather
both depend on simple-model
:
simple-console ---> simple-weather ----> simple-model
\开发者_JAVA技巧 /
\---> simple-persist--/
simple-console
depends on spring
and hibernate
, in effect depends on a jar that contains javax.transaction.TransactionManager
.
I generate eclipse projects for these 5 projects.
The Main
class inside simple-console
(which invoke a Hibernate method) run fine in eclipse.
However, when I tried to execute it with Maven
'sexec:java
goal or java -cp
(assemblied with jar-with-dependencies
), I always got this error: Caused by: java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
It really confused me because, while eclipse knows how to include necessary jars before execution, maven plugins don't make sense of that. Why?
P/S: I have uploaded the source code of these projects here: http://seamoo.com/simple-parent.tar.gz
If you run mvn dependency:tree
in simple-console, you won't see the JTA artifact:
[INFO] org.seamoo:simple-console:jar:1.0 [INFO] +- junit:junit:jar:3.8.1:test [INFO] +- org.seamoo:simple-persist:jar:1.0:compile [INFO] | +- org.seamoo:simple-model:jar:1.0:compile [INFO] | +- org.hibernate:hibernate:jar:3.2.5.ga:compile [INFO] | | +- net.sf.ehcache:ehcache:jar:1.2.3:compile [INFO] | | +- asm:asm-attrs:jar:1.5.3:compile [INFO] | | +- antlr:antlr:jar:2.7.6:compile [INFO] | | +- cglib:cglib:jar:2.1_3:compile [INFO] | | +- asm:asm:jar:1.5.3:compile [INFO] | | \- commons-collections:commons-collections:jar:2.1.1:compile [INFO] | +- org.hibernate:hibernate-annotations:jar:3.3.0.ga:compile [INFO] | | \- javax.persistence:persistence-api:jar:1.0:compile [INFO] | \- org.hibernate:hibernate-commons-annotations:jar:3.3.0.ga:compile [INFO] +- org.seamoo:simple-weather:jar:1.0:compile [INFO] | +- log4j:log4j:jar:1.2.14:compile [INFO] | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile [INFO] | +- jaxen:jaxen:jar:1.1.1:compile [INFO] | | +- jdom:jdom:jar:1.0:compile [INFO] | | +- xerces:xercesImpl:jar:2.6.2:compile [INFO] | | \- xom:xom:jar:1.0:compile [INFO] | | +- xerces:xmlParserAPIs:jar:2.6.2:compile [INFO] | | +- xalan:xalan:jar:2.6.0:compile [INFO] | | \- com.ibm.icu:icu4j:jar:2.6.1:compile [INFO] | \- velocity:velocity:jar:1.5:compile [INFO] | +- commons-lang:commons-lang:jar:2.1:compile [INFO] | \- oro:oro:jar:2.0.8:compile [INFO] +- org.springframework:spring:jar:2.0.7:compile [INFO] | \- commons-logging:commons-logging:jar:1.1:compile [INFO] | +- logkit:logkit:jar:1.0.1:compile [INFO] | +- avalon-framework:avalon-framework:jar:4.1.3:compile [INFO] | \- javax.servlet:servlet-api:jar:2.3:compile [INFO] \- hsqldb:hsqldb:jar:1.8.0.7:compile
And indeed, if you look at simple-persist/pom.xml
, you'll see that it has been excluded:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
My guess is that the jta artifact is excluded because the full hibernate jar (hibernate-3.2.5.ga.jar
here) depends on jta-1.0.1B.jar
which is NOT available in the central repo due to licensing issues while hibernate core (i.e. hibernate-core-3.3.0.GA.jar
) depends on jta-1.1.jar
, which is available from central.
The reason why it works in Eclipse is that the simple-model depends on hibernate-annotations-3.3.0.ga.jar
which depends on hibernate-3.2.1.GA.jar
which depends on jta-1.0.1B.jar
(that you very likely have in your local repository). So, because the whole hibernate dependencies are a big mess in this project, because there are big dependencies convergences problems, Eclipse "sees" the JTA jar (that's just a fortunate or unfortunate side effect). But Maven doesn't.
To solve the problem, either remove the JTA exclusion in simple-persist/pom.xml
(that's the quick and very dirty fix) or fix the hibernate dependencies to make them converge (that would be the right fix):
- use
hibernate-core-3.3.0.SP1.jar
wherever required - use
hibernate-annotations-3.4.0.GA.jar
(which depends on the former) wherever required
精彩评论