NoClassDefFoundError:使用PowerMock-OSGi的org / hamcrest / Matchers

时间:2014-03-17 14:19:00

标签: java osgi mockito powermock hamcrest

当我运行我的测试作为OSGi PlugIn测试时,我得到org.hamcrest.Matchers的NoClassDefFoundError,但是当我将其作为普通JUnit运行时测试everthing按预期工作。我正在使用OSGi version of PowerMock并在我的启动配置中包含所有必要的依赖项。 我做错了什么?由于某种原因,似乎Testrunner没有看到这个班级。

修改 我创建了一个简化的示例项目,并发现只有在我的类声明中使用@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

1 个答案:

答案 0 :(得分:2)

如果你看一下Powermock-osgi的update site,你会注意到那里有hamcrest和junit捆绑。然而,它们不是官方发布的“正常”捆绑包,而是包装捆绑包,暴露出比官方包更多的包。

如果使用Eclipse,则共享工作空间的捆绑包池。使用符号名称和版本查找捆绑包。所以你必须从powermock-osgi的更新站点添加junit和hamcrest,你必须确定,在解析目标平台之前你删除了所有工作区的所有bundle池。

请参阅Powermock-OSGI site

  

Tycho和Eclipse PDE根据符号名称缓存捆绑包   版。因此,如果用户已经有了4.11版本的Junit   过去,我们的黑客电动摇滚版本将不会被拍摄。

     

因此,在Eclipse内首次使用之前,用户必须删除   .metadata.plugins \ org.eclipse.pde.core.bundle_pool和   ALL中的.metadata.plugins \ org.eclipse.pde.core.external_libraries   特定Eclipse安装的工作空间(查找包   跨工作区方式)。当然,当你运行单元测试时   eclipse启动配置中的插件选项卡REALLY包含   Powermock功能的JUnit,Mockito和Hamcrest插件,而不是   其他一些版本。在第一次使用Tycho之前删除.meta   来自maven本地存储库的.cache和p2文件夹

如果情况并非如此,请提供以下信息,让我帮助您:

  • 您的目标文件为XML
  • 测试片段清单和主机包清单
  • 你的hamcrest和junit包的大小 内部

如果您在https://code.google.com/p/powermock-osgi/提交了一个示例项目问题,我会看一下。

修改 还有一件事。 OSGI包中的类eu.gemtec.commons.util.assertion.Assert是否将hamcrest作为依赖项导入?是eu.gemtec.commons.util.assertion包导出了吗?

<强> EDIT2: 事实证明,我的“hacked”powermock-osgi版本的hamcrest不会将org.hamcrest导出为拆分包,这就是问题所在。很快就会修复更新站点。见https://code.google.com/p/powermock-osgi/issues/detail?id=2#c4

<强> EDIT3:http://powermock-osgi.googlecode.com/svn/updateSite/1.5.4.1

为Chris提供更新站点以进行测试

更新:项目已自动迁移到github。更新网站:https://raw.githubusercontent.com/liptga/powermock-osgi/master/update-site/1.5.6.0

项目网站:https://github.com/liptga/powermock-osgi

感谢Chriss帮助调查。