java mockito junit4 powermock linkageerror

java - Mockito+PowerMock LinkageError mientras se burla de la clase del sistema



junit4 (5)

Conflicto de cargador de clases , use esto: @PowerMockIgnore("javax.management.*")

Deja que el cargador de clases falso no cargue javax.*. Funciona.

Tengo un fragmento de código como este:

@RunWith(PowerMockRunner.class) @PrepareForTest({Thread.class}) public class AllMeasuresDataTest { @Before public void setUp() throws Exception { } @Test public void testGetMeasures() { AllMeasuresData measure = new AllMeasuresData(); assertEquals(measure.getMeasures(), null); HashMap<String, Measure> map = new HashMap<String, Measure>(); measure.setMeasures(map); assertEquals(measure.getMeasures(), map); measure.setMeasures(null); assertEquals(measure.getMeasures(), null); } @Test public void testAllMeasuresData() throws IOException { ClassLoader loader = PowerMockito.mock(ClassLoader.class); Thread threadMock = PowerMockito.mock(Thread.class); Vector<URL> vec = new Vector<URL>(); Mockito.when(loader.getResources("measure")).thenReturn(vec.elements()); Mockito.when(threadMock.getContextClassLoader()).thenReturn(loader); PowerMockito.mockStatic(Thread.class); Mockito.when(Thread.currentThread()).thenReturn(threadMock); ... } }

Mientras ejecutaba estas pruebas obtuve:

java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:791) at java.lang.ClassLoader.defineClass(ClassLoader.java:634) at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:201) at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:149) at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at org.codecover.instrumentation.java.measurement.ProtocolImpl.initializeMBean(ProtocolImpl.java:247) at org.codecover.instrumentation.java.measurement.ProtocolImpl.<init>(ProtocolImpl.java:237) at org.codecover.instrumentation.java.measurement.ProtocolImpl.getInstance(ProtocolImpl.java:185) at measure.CodeCoverCoverageCounter$6ya5ud0ow79ijrr1dvjrp4nxx60qhxeua02ta2fzpmb1d.<clinit>(MeasureCalculatorsHolder.java:146) at measure.MeasureCalculatorsHolder.<clinit>(MeasureCalculatorsHolder.java:17) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:188) at javassist.runtime.Desc.getClassObject(Desc.java:43) at javassist.runtime.Desc.getClassType(Desc.java:152) at javassist.runtime.Desc.getType(Desc.java:122) at javassist.runtime.Desc.getType(Desc.java:78) at algorithm.AllMeasuresDataTest.testGetMeasures(AllMeasuresDataTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312) at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86) at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:116) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284) at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84) at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.codecover.juniteclipse.runner.EclipseTestRunner.main(EclipseTestRunner.java:40)

¿Sabes cómo puedo evitar esto? Tal vez haya otra forma de burlarse de una pieza de código:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ... Enumeration<URL> resources = classLoader.getResources(path);


Este puede ser un tema viejo, pero también me encontré con este problema. Resulta que algunas de las versiones de Java no pueden manejar powermockito cuando powermock descubre que hay 2 clases con el mismo nombre en el mismo paquete (en diferentes dependencias).

Con cualquier versión más alta que Java 7_25 da este error.


Intente agregar esta anotación a su clase de prueba:

@PowerMockIgnore("javax.management.*")

Trabajó para mi.


La respuesta de Crandrad me ayudó a llegar a una solución final que era similar. Terminé teniendo que excluir todas las clases relacionadas con SSL:

@PowerMockIgnore({"javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.http.conn.ssl.*", "javax.net.ssl.*"})


Para simular clases del sistema, prepare la clase que es el objetivo de la prueba, no Thread.class . No hay forma de que PowerMock pueda instrumentar Thread.class porque es necesario durante el arranque de JVM, mucho antes de que PowerMock pueda usar el instrumento.

La forma en que funciona la instrumentación, una vez que se carga una clase, ya no se puede instrumentar.

Vea la wiki de PowerMock .