apache-karafwiremockpax-exam

PaxExam tests configured with wrappedBundle()


For the configuration in PaxExam (version 4) we're using wrappedBundle() as you can see here:

wrappedBundle(mavenBundle().groupId("com.github.tomakehurst").artifactId("wiremock-jre8").versionAsInProject()),

Because we want to create an OSGi bundle out of an ordinary jar.

Then in order the wrap mechanism can be used we have to install the wrap feature:

features(karafStandardRepo, "wrap"),

The problem is when it comes to install wrappedBundle() the wrap feature is not yet there. How can I assure in the PaxExam configuration wrappedBundle() is executed only after the wrap feature is there and ready for use? The Karaf distribution we are using in this test is version 4.0.7.

Thanks for help, Kladderradatsch


Solution

  • Yes, indeed we had to wrap the WireMock bundle generation by the PaxUrl Wrap mechanism into a separate feature file:

    <features name="wiremock-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
        <feature name="wiremock" version="${project.version}">
            <feature prerequisite="true">wrap</feature>
            <bundle>
                wrap:mvn:com.github.tomakehurst/wiremock-jre8-standalone/2.21.0$Bundle-ClassPath=.
            </bundle>
        </feature>
    </features>
    

    Very important is here to configure the XML namespace properly, namely to address version v1.4.0 otherwise prerequisite is of no use. A further pitfall I stepped in before was not taking the standalone version of WireMock.

    Then in the PaxExam configuration I have just installed the feature:

    features(maven().groupId("com.company.wiremock").artifactId("wiremock-feature").type("xml").classifier("features").version("1.0.0-SNAPSHOT"), "wiremock"),
    

    When it comes to initialize the WireMockServer in your tests, in order the resources in the new generated WireMock-Bundle can be loaded via ClassLoader.getResource() (internal stuff of that library), you have to do this here in your test otherwise the Bundle-Classloader of that WireMock-Bundle is not used:

        @BeforeClass
        public static void setup() {
            ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(WireMockClassRule.class.getClassLoader());
                wireMockServer = new WireMockServer(options().dynamicPort());
                wireMockServer.start();
            } finally {
                Thread.currentThread().setContextClassLoader(savedClassLoader);
            }
        }
    
        @AfterClass
        public static void end() {
            wireMockServer.stop();
        }
    

    You could put this in a JUnit @ClassRule for encapsulation.