从 Groovy 2.5 升级到 Groovy 3.0 后,OSGi 测试不再有效
OSGi tests no longer working after upgrading from Groovy 2.5 to Groovy 3.0
我有一个 pax-exam 测试,看起来像这样:
@RunWith(PaxExam.class)
public class XmlPathOSGiITest {
@Configuration
public static Option[] configure() {
return new Option[]
{
/* System Properties */
systemProperty(EXAM_FAIL_ON_UNRESOLVED_KEY).value("true"),
systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
/* Hamcrest & JUnit bundles */
restAssuredJunitBundles(),
/* Transitive dependencies needed in the Pax Exam container.
Some of these need to be wrapped because they are not available as OSGi bundles */
mavenBundle().groupId("org.apache.aries.spifly").artifactId("org.apache.aries.spifly.dynamic.bundle").version("1.2.1"),
mavenBundle().groupId("org.hamcrest").artifactId("hamcrest").versionAsInProject(),
mavenBundle().groupId("org.apache.commons").artifactId("commons-lang3").versionAsInProject(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-json").versionAsInProject().noStart(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-xml").versionAsInProject().noStart(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy").versionAsInProject(),
wrappedBundle(mavenBundle().groupId("org.ccil.cowan.tagsoup").artifactId("tagsoup").versionAsInProject()),
wrappedBundle(mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api").versionAsInProject()),
wrappedBundle(mavenBundle("javax.activation", "activation").version("1.1.1")),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpclient").versionAsInProject()),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpmime").versionAsInProject()),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpcore").versionAsInProject()),
/* Rest Assured dependencies needed in the Pax Exam container to be able to execute the tests below */
mavenBundle("io.rest-assured", "json-path").versionAsInProject(),
mavenBundle("io.rest-assured", "xml-path").versionAsInProject(),
mavenBundle("io.rest-assured", "rest-assured").versionAsInProject(),
mavenBundle("io.rest-assured", "rest-assured-common").versionAsInProject()
};
}
@Test
public void getUUIDParsesAStringResultToUUID() {
final String UUID_XML = "<some>\n" +
" <thing id=\"1\">db24eeeb-7fe5-41d3-8f06-986b793ecc91</thing>\n" +
" <thing id=\"2\">d69ded28-d75c-460f-9cbe-1412c60ed4cc</thing>\n" +
"</some>";
final UUID uuid = from(UUID_XML).getUUID("some.thing[0]");
assertThat(uuid, Matchers.equalTo(UUID.fromString("db24eeeb-7fe5-41d3-8f06-986b793ecc91")));
}
}
这曾经在 Groovy 2.5 上运行良好,但在升级到 Groovy 3.0 后,我收到以下错误:
java.lang.ClassNotFoundException: org.codehaus.groovy.runtime.ScriptBytecodeAdapter not found by groovy-xml [20]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1597)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
at java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1375)
at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1618)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1548)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
at java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at io.restassured.internal.common.assertion.AssertParameter.notNull(AssertParameter.groovy:25)
at io.restassured.path.xml.XmlPath.get(XmlPath.java:316)
at io.restassured.path.xml.XmlPath.getUUID(XmlPath.java:584)
at io.restassured.test.osgi.XmlPathOSGiITest.getUUIDParsesAStringResultToUUID(XmlPathOSGiITest.java:84)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runLeafWithRetry(ContainerTestRunner.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChildWithRetry(ContainerTestRunner.java:84)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:75)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:43)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:435)
at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:408)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=13=](TCPTransport.java:677)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:834)
我检查了 mvn dependency:tree
以确保类路径中没有 Groovy 2.5.x 的残余。
这可能是什么原因造成的,我该如何解决?请注意,您可以在 github here.
上找到该项目
我认为这可能是由 groovy 内部 class 加载引起的。可能 groovy 使用用户包的 class 加载器加载它自己的 class ScriptBytecodeAdapter。它应该为此使用自己的 class 加载程序。顺便提一句。获取此类 class 加载程序的最简单方法是获取已知 class 的 class 加载程序。
在 OSGi 中,class 的 class 加载器始终是 class 所在的包的 class 加载器。
此处的讨论提出了问题 GROOVY-9402,该问题已在 Groovy 的 3.0.2
版本中修复。
总结:
Groovy 3.0.0
和 3.0.1
的 OSGi 元数据错误。
在 Groovy 3.0
的早期开发阶段,团队希望摆脱不同模块(JPMS 模块系统)之间的拆分包并相应地更新 OSGi 元数据。
后来他们决定在旧包位置添加一些已弃用的 类 以指示 类 已移动(这意味着 Groovy 3.0
具有拆分包问题和 JPMS 支持将添加 4.0
)。在此操作期间,OSGi 元数据未修复。这是用 Groovy 3.0.2
解决的
我有一个 pax-exam 测试,看起来像这样:
@RunWith(PaxExam.class)
public class XmlPathOSGiITest {
@Configuration
public static Option[] configure() {
return new Option[]
{
/* System Properties */
systemProperty(EXAM_FAIL_ON_UNRESOLVED_KEY).value("true"),
systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
/* Hamcrest & JUnit bundles */
restAssuredJunitBundles(),
/* Transitive dependencies needed in the Pax Exam container.
Some of these need to be wrapped because they are not available as OSGi bundles */
mavenBundle().groupId("org.apache.aries.spifly").artifactId("org.apache.aries.spifly.dynamic.bundle").version("1.2.1"),
mavenBundle().groupId("org.hamcrest").artifactId("hamcrest").versionAsInProject(),
mavenBundle().groupId("org.apache.commons").artifactId("commons-lang3").versionAsInProject(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-json").versionAsInProject().noStart(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-xml").versionAsInProject().noStart(),
mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy").versionAsInProject(),
wrappedBundle(mavenBundle().groupId("org.ccil.cowan.tagsoup").artifactId("tagsoup").versionAsInProject()),
wrappedBundle(mavenBundle("jakarta.xml.bind", "jakarta.xml.bind-api").versionAsInProject()),
wrappedBundle(mavenBundle("javax.activation", "activation").version("1.1.1")),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpclient").versionAsInProject()),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpmime").versionAsInProject()),
wrappedBundle(mavenBundle("org.apache.httpcomponents", "httpcore").versionAsInProject()),
/* Rest Assured dependencies needed in the Pax Exam container to be able to execute the tests below */
mavenBundle("io.rest-assured", "json-path").versionAsInProject(),
mavenBundle("io.rest-assured", "xml-path").versionAsInProject(),
mavenBundle("io.rest-assured", "rest-assured").versionAsInProject(),
mavenBundle("io.rest-assured", "rest-assured-common").versionAsInProject()
};
}
@Test
public void getUUIDParsesAStringResultToUUID() {
final String UUID_XML = "<some>\n" +
" <thing id=\"1\">db24eeeb-7fe5-41d3-8f06-986b793ecc91</thing>\n" +
" <thing id=\"2\">d69ded28-d75c-460f-9cbe-1412c60ed4cc</thing>\n" +
"</some>";
final UUID uuid = from(UUID_XML).getUUID("some.thing[0]");
assertThat(uuid, Matchers.equalTo(UUID.fromString("db24eeeb-7fe5-41d3-8f06-986b793ecc91")));
}
}
这曾经在 Groovy 2.5 上运行良好,但在升级到 Groovy 3.0 后,我收到以下错误:
java.lang.ClassNotFoundException: org.codehaus.groovy.runtime.ScriptBytecodeAdapter not found by groovy-xml [20]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1597)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
at java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1375)
at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1618)
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1548)
at org.apache.felix.framework.BundleWiringImpl.access0(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
at java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at io.restassured.internal.common.assertion.AssertParameter.notNull(AssertParameter.groovy:25)
at io.restassured.path.xml.XmlPath.get(XmlPath.java:316)
at io.restassured.path.xml.XmlPath.getUUID(XmlPath.java:584)
at io.restassured.test.osgi.XmlPathOSGiITest.getUUIDParsesAStringResultToUUID(XmlPathOSGiITest.java:84)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runLeafWithRetry(ContainerTestRunner.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChildWithRetry(ContainerTestRunner.java:84)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:75)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:43)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:435)
at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.invokeMethodOnService(RemoteFrameworkImpl.java:408)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:566)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=13=](TCPTransport.java:677)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:834)
我检查了 mvn dependency:tree
以确保类路径中没有 Groovy 2.5.x 的残余。
这可能是什么原因造成的,我该如何解决?请注意,您可以在 github here.
上找到该项目我认为这可能是由 groovy 内部 class 加载引起的。可能 groovy 使用用户包的 class 加载器加载它自己的 class ScriptBytecodeAdapter。它应该为此使用自己的 class 加载程序。顺便提一句。获取此类 class 加载程序的最简单方法是获取已知 class 的 class 加载程序。
在 OSGi 中,class 的 class 加载器始终是 class 所在的包的 class 加载器。
此处的讨论提出了问题 GROOVY-9402,该问题已在 Groovy 的 3.0.2
版本中修复。
总结:
Groovy 3.0.0
和 3.0.1
的 OSGi 元数据错误。
在 Groovy 3.0
的早期开发阶段,团队希望摆脱不同模块(JPMS 模块系统)之间的拆分包并相应地更新 OSGi 元数据。
后来他们决定在旧包位置添加一些已弃用的 类 以指示 类 已移动(这意味着 Groovy 3.0
具有拆分包问题和 JPMS 支持将添加 4.0
)。在此操作期间,OSGi 元数据未修复。这是用 Groovy 3.0.2