Question

I have some integration-tests that run perfectly using the surefire plugin with command:

mvn -Dtest=path.to.test.classIT surefire:test

When I run the same integrationtest with the failsafe plugin using

mvn verify

the test fails indicating it is missing a dependency (jackson lib, "No Message body writer found for response class ").

The needed dependency is added to the pom with scope test. What is the difference in how surefire and failsafe executes tests?

Some more context: My pom contains the following:

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.12.4</version>
    <configuration>
        <forkMode>never</forkMode>
        <threadCount>1</threadCount>
    </configuration>
</plugin>
...
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-cxf-rs</artifactId>
        <version>4.6.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-mockito</artifactId>
        <version>4.6.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <scope>provided</scope>
    </dependency>

The test class uses applicationcomposer

@RunWith(ApplicationComposer.class)
public class PdaServiceIT {

    ....
    @Configuration
    public Properties config() throws Exception {

        Properties properties = new Properties();

        properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
        properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
        properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");

        return properties;
    }
...
Was it helpful?

Solution

The problem might be caused because the class used as Json provider is not on the classpath. This can be solved by adding a module that contains the class to the integration test:

...
@RunWith(ApplicationComposer.class)
public class PdaServiceIT {

    ...
    @Configuration
    public Properties config() throws Exception {

        Properties properties = new Properties();

        properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
        properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
        properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");

        return properties;
    }

    @Module
    public static Class<?>[] myJaxbProviders() {
        return new Class<?>[] { com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.class };
    }
    ...
}

Then the required class will be available when using both maven-surefire and maven-failsafe plugins.

A similar integration test setup is described here.

OTHER TIPS

I'm not really sure about what is happening here but there is a full documentation page about Class loading issues that might be related to your problem.

https://maven.apache.org/surefire/maven-failsafe-plugin/examples/class-loading.html

This page explains that, while using the parameter forkMode=never (Which is apparently deprecated), the plugin have to use an isolated classloader.

One of the limitation of having an isolated class loader is explained here:

For example, the system property java.class.path won't include your jars; if your app notices this, it could cause a problem

I agree that it is a bit esoteric in this case but I can't stop thinking it is related to your issue.

Did you try to change the current configuration you have? I don't know, maybe dropping the forkMode and threadCount and see how the default configuration is handling all that?

If it doesn't work, I would try to

tinker with these three settings: forkCount, useSystemClassLoader, and useManifestOnlyJar.

As the document says.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top