当我将我的测试作为 OSGi 插件测试运行时,我收到 org.hamcrest.Matchers 的 NoClassDefFoundError 错误,但是当我将其作为普通 JUnit 测试运行时,一切都会按预期工作。我正在使用OSGi version of PowerMock并在我的启动配置中包含所有必要的依赖项。 我做错了什么?由于某种原因,测试运行者似乎没有看到该类。
编辑:
我创建了一个简化的示例项目,并发现只有当我在类声明中使用 @PrepareForTest(XXX.class)
时才会出现问题。
java.lang.NoClassDefFoundError: org/hamcrest/Matchers
at eu.gemtec.commons.util.assertion.Assert.assertParamNotNull(Assert.java:107)
at eu.gemtec.eagle.device.aastra.omaxi.core.system.model.impl.MessageHandleFactory.<init>(MessageHandleFactory.java:72)
at eu.gemtec.eagle.device.aastra.omaxi.core.system.model.impl.TestMessageHandleFactory.setUp(TestMessageHandleFactory.java:74)
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.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$LastRuleTestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:148)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:91)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
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.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:23)
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.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
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.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
Caused by: java.lang.ClassNotFoundException: org.hamcrest.Matchers
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:467)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:65)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 52 more
最佳答案
如果你看一下update site在 Powermock-osgi 中,您会注意到,那里有 hamcrest 和 junit 包。然而,它们不是“正常”的官方发布的 bundle ,而是包装 bundle ,公开了比官方 bundle 更多的包。
如果您使用 Eclipse,工作区的 bundle 池是共享的。使用符号名称和版本来查找 bundle 。因此,您必须从 powermock-osgi 的更新站点添加 junit 和 hamcrest,并且您必须确保在解析目标平台之前删除了所有工作区的所有 bundle 池。
Tycho and Eclipse PDE caches the bundles based on symbolic name and version. So if the user already had a 4.11 version of Junit anytime in the past, our hacked powermock version will not be taken.
So before first usage inside Eclipse the user has to delete the .metadata.plugins\org.eclipse.pde.core.bundle_pool and .metadata.plugins\org.eclipse.pde.core.external_libraries in ALL workspaces of the specific Eclipse installation (bundles are looked up cross workspace way). BE SURE, that when you run the unit tests in eclipse the plugins tab in the launch config REALLY contains the JUnit, Mockito and Hamcrest plugins of the Powermock feature, and not some other version. Before first usage with Tycho delete the .meta .cache and p2 folders from the maven local repository
如果不是这种情况,请提供以下信息以便我帮助您:
- XML 格式的目标文件
- 测试片段 list 和主机包 list
- 您的 hamcrest 和 junit 束的大小 里面
如果您通过 https://code.google.com/p/powermock-osgi/ 提交问题有一个示例项目,我会看一下。
编辑:
还有一件事。是类(class)eu.gemtec.commons.util.assertion.Assert
在 OSGI 包中导入 hamcrest 作为依赖项?是eu.gemtec.commons.util.assertion
包导出了吗?
编辑2: 事实证明,我的“黑客”powermock-osgi 版本的 hamcrest 没有将 org.hamcrest 导出为拆分包,这就是问题所在。更新站点的修复即将到来。请参阅https://code.google.com/p/powermock-osgi/issues/detail?id=2#c4
编辑3: 为 Chriss 提供了用于测试目的的更新站点:http://powermock-osgi.googlecode.com/svn/updateSite/1.5.4.1
更新:项目已自动迁移到 github。更新站点:https://raw.githubusercontent.com/liptga/powermock-osgi/master/update-site/1.5.6.0
项目网址:https://github.com/liptga/powermock-osgi
感谢克里斯帮助调查。
关于java - NoClassDefFound错误: org/hamcrest/Matchers using PowerMock-OSGi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22456767/