Spring 3.0.x i uszkodzone drzewo zależności
09 lutego 2011, 17:16:59, Patryk Dobrowolski « Instalacja i konfiguracja Maven'a | Testy jednostkowe w Spring 3.0 »Ostatnio postanowiłem przyjrzeć się dokładniej Spring Framework w wersji 3.0.x. W związku z tym postanowiłem napisać prostą aplikację webową z wykorzystaniem najnowszych wersji używanych przeze mnie na co dzień frameworków, a także z zachowaniem wszystkich zasad programowania aplikacji webowych w Javie. W tym z użyciem znienawidzonych przez wielu testów jednostkowych. Przygotowałem wszystko zgodnie z dokumentacją Springa, ale przy uruchomieniu testów przy użyciu Mavena, wyskoczył następujący wyjątek:
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:358) 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:49) 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)
Wstyd się przyznać, ale sporo czasu upłynęło, nim udało mi się z tym uporać. Okazało się, że odpowiedzialność za zamieszanie ponosi błędnie zdefiniowane w Springu drzewo zależności. Otóż artefakt spring-hibernate3 w swoich zależnościach zawiera bibliotekę spring-dao w wersji 2.0.8, która nie jest już używana. Wszystkie jej klasy zostały przeniesione do spring-tx i tam są rozwijane.
Kiedy zna się już ten fakt, rozwiązanie problemu jest całkiem banalne. Po pierwsze należy wykluczyć w pom.xml z drzewa zależności to nieszczęsne spring-dao:
org.springframework spring-hibernate3 ${springframework.hibernate3.version} org.springframework spring-dao
A następnie jawnie zdefiniować zależność do spring-tx:
org.springframework spring-tx ${springframework.version}
I koniec. Testy powinny się wykonywać. Czy bez błędów? To już zależy od innych czynników. Ja na razie próbuję dojść dlaczego transakcja po testach nie chce się zrollbackować.