【问题标题】:Resolving OSGi tests when upgrading from Groovy 2.4 to 2.5 due to "Fragment bundles can not be started"?从 Groovy 2.4 升级到 2.5 时由于“无法启动片段包”而解决 OSGi 测试?
【发布时间】:2019-03-20 07:15:00
【问题描述】:

这是How to upgrade groovy-all from 2.4 to 2.5 when running in OSGi? 的后续问题。 groovy-all 工件在 Groovy 的 2.5 版中不再作为 jar 文件提供,因此上述答案中的建议是使用单独的 jar 文件。我有一个使用Pax Exam 的测试用例,看起来像this

@RunWith(PaxExam.class)
public class XmlPathOSGiITest {

    @Configuration
    public static Option[] configure() {
        return new Option[]
                {
                        mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.hamcrest", "1.3_1"),
                        junitBundles(),
                        systemProperty("pax.exam.osgi.unresolved.fail").value("true"),
                        systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),

                        /* Transitive dependencies needed in the Pax Exam container.
                        Some of these need to be wrapped because they are not available as OSGi bundles */
                        mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
                        wrappedBundle(mavenBundle().groupId("org.ccil.cowan.tagsoup").artifactId("tagsoup").versionAsInProject()),
                        wrappedBundle(mavenBundle("javax.xml.bind", "jaxb-api").versionAsInProject()),
                        wrappedBundle(mavenBundle("javax.activation", "activation").version("1.1.1")),
                        wrappedBundle(mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-all").version("2.4.12")),
                        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")));
    }
}

兴趣点在哪里:

wrappedBundle(mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-all").version("2.4.12")),

现在我想升级到 Groovy 2.5.6,所以我将上面的行替换为:

wrappedBundle(mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy").version("2.5.6")),
wrappedBundle(mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-json").version("2.5.6")),
wrappedBundle(mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-xml").version("2.5.6")),

但是现在当我重新运行测试时,我收到以下错误:

org.osgi.framework.BundleException: Fragment bundles can not be started.

    at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)
    at org.ops4j.pax.swissbox.framework.RemoteFrameworkImpl.startBundle(RemoteFrameworkImpl.java:178)

我该如何解决这个问题?

【问题讨论】:

    标签: groovy osgi pax-exam osgi-fragment


    【解决方案1】:

    你需要在重新运行你的包后检查它是否碎片:

    private static boolean isBundleFragment(final Bundle bundle) {
        boolean frament = false;
        final Dictionary<String, String> dictionary = bundle.getHeaders();
    
        if (dictionary.get("Fragment-Host") != null) {
            frament = true;
        }
        return frament;
    }
    

    发生这种情况时,您需要先停止捆绑:

    if (!isBundleFragment(bundle)) {
        bundle.stop();
    }
    

    然后启动您的捆绑包或更新它。希望对您有所帮助!

    【讨论】:

    • 谢谢,但是我把这段代码放在哪里呢?如何将它与我的 pax-exam 测试集成?
    • 我以为您在运行时更改了捆绑包。如果您只是重新运行并使用该捆绑包更改测试,问题似乎是自己的捆绑包。捆绑包开始的顺序是相关的。尝试将artifactId("groovy") 的顺序更改为最后一个,先保留卫星包
    • 你的意思是把artifactId("groovy")移到artifact"groovy-xml")下面?这似乎没有任何区别:(
    • Groovy 包确实是片段包(afaict)。是这个原因吗?为什么不能启动?
    最近更新 更多