Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

Strange Maven dependency resolution problems. How Springframework caused problems when they absorbed the APIs into an existing dependency.

java.lang.NoSuchMethodError: org.springframework.transaction.interceptor.TransactionAttribute.getQualifier()Ljava/lang/String;
	at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:149)
	at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
	at $Proxy0.invoke(Unknown Source)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

What the heck is this? Your library has this class and the method does exist and even takes a String. What makes it even weirder is that your tests run in your editor, but do not run from the Maven command line. How can this be?

Unknown to you, one of the dependencies that you are using is pulling spring-dao-2.0.x.jar (usually version 2.0.8, but not always). OK, but what is the problem with that? The code that was in that jar was absorbed by the spring-tx jar in the spring 2.5. There is no replacement for that jar, so even though you are using a much newer version of Spring, nothing says not to pull the old jar into your project. It is up to you to find any dependency that uses the jar and exclude it.

In Maven, it is done like this:

        <dependency>
            <groupId>com.bhsi</groupId>
            <artifactId>dao-user</artifactId>
            <version>1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-dao</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

This has to be done for any dependency that has that jar as a transitive dependency.

Once that is done, you need to see if you have the replacement. In my specific case, my test class ran sometimes, but did not run other times. This was due to having spring-dao-2.0.8.jar and spring-tx-3.0.4-RELEASE.jar in my project classpath. If you don’t have the spring-tx jar, add it and you should be good to go.

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

January 31st, 2011

Posted In: Java, JUnit, Maven, Spring

3 Comments

  • Patryk says:

    I think it’s not the way to resolve that problem. Of course, I found this spring-dao-2.0.8 as a dependency of spring-hibernate3, but when I excluded that I’ve just lost @Transactional annotation and ResourceTransactionManager class/interface. They, I guess, are just there in this artifact. I fight currently these problems for a while and don’t really know how I can win 🙂

  • Patryk says:

    Ok, I’ve got it. I excluded this damn spring-dao-2.0.8 from spring-hibernate3 and add explicit dependency to spring-tx-3.0.5. Now it works… as far.

Leave a Reply

Your email address will not be published. Required fields are marked *

WP to LinkedIn Auto Publish Powered By : XYZScripts.com