java - NoClassDefFound错误: org/hamcrest/Matchers using PowerMock-OSGi

标签 java osgi mockito powermock hamcrest

当我将我的测试作为 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 池。

参见Powermock-OSGI site :

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/

相关文章:

java - 为什么不从父类(super class)继承 OSGi 声明性服务 (DS) 注释?

java - Final 类和 Final 方法 - 使用 Mockito 2 进行模拟

java - 显示给定字符的 ASCII 值

java - 防止导入 android.R

java - Firebase 查询似乎不适用于 Android

java.lang.ClassNotFoundException : org. slf4j.bridge.SLF4JBridgeHandler 问题

osgi - OSGi 组件模型中的捆绑内和捆绑间相互依赖关系

java - Apache Felix mvn 包

java - AspectJ 找不到 .raw 父类(super class)

spring - 为什么 Mockito 的 when() 没有被触发?