2011-10-23 7 views
7

Ho un'applicazione primavera e faccio la mia classe di test come segue:Perché ho bisogno di cglib (Spring AOP) per avere più classi di test?

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback = true) 
@Transactional 
public class MyTest { 

} 

Quando cerco di creare un'altra classe di test e ho cercato di eseguire l'applicazione, ottengo la seguente eccezione sul nuovo test classe:

ERROR [main] (TestContextManager.java:324) - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecut 
[email protected]] to prepare test instance [[email protected]] 
org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. 
     at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67) 
     at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104) 
     at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112) 
     at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476) 
     at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) 
     at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:386) 
     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:111) 
     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
     at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303) 
     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:62) 
     at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) 
     at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) 
     at org.apache.maven.surefire.Surefire.run(Surefire.java:177) 
     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.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) 
     at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) 

Questa eccezione è stato risolto con l'aggiunta di cglib al mio percorso di classe, ma voglio capire perché più classi di test ha bisogno del cglib?

Si prega di avvisare, grazie.

+0

Il tuo "altro test" usa lo stesso 'applicationContext.xml'? – axtavt

+0

sì, poiché ho bisogno di entrambi i test per utilizzare la stessa configurazione del database che esiste in applicationContext.xml. –

risposta

10

primavera richiede i vasi CGLIB perchè sta usando CGLIB per proxy i tuoi bean. Ciò accade se si configura Spring per utilizzare questo meccanismo nel proprio applicationContext.xml o se Spring ha bisogno di proxy una classe che non implementa interfacce. La documentazione di Spring per questo è here e fornisce una spiegazione molto chiara.

Per utilizzare i proxy dinamici JDK assicurarsi che tutte le classi proxy implementino un'interfaccia appropriata e che non si stia obbligando Spring a utilizzare CGLIB tramite la configurazione.

+1

La necessità di CGLIB "se Spring ha bisogno di proxy una classe che non implementa interfacce" è stata una novità per me. Grazie! – Snekse

1

La mia ipotesi è che la primavera aggiunge la sua alla classe in fase di esecuzione, e questo è il motivo per cui ha bisogno la libreria cglib (viene utilizzato per la manipolazione bytecode e iniezione di codice, vedere here)

0

Spring utilizzerà definitivamente il meccanismo proxy per alcune delle tue classi.

Tuttavia, a partire dalla versione Spring 3.2 il CGLIB sources are repackaged e aggiunto a spring-core per impostazione predefinita, quindi non è necessario aggiungere manualmente la libreria CGLIB al classpath.

A proposito, come lo stato spring blog entry di Michael Isvy e this issue report, il progetto CGLIB non è più attivo. Nelle versioni future, Spring utilizzerà Javassist per impostazione predefinita.

Problemi correlati