Sasha Shpota
Sasha Shpota

Reputation: 10290

Arquillian test works only if it is placed in root package

I have a simple Wildfly Swarm application which has JAX-RS endpoint and Service class injected into the endpoint through CDI.

I wrote an integration test for my app which looks somehow like this:

@RunWith(Arquillian.class)
@DefaultDeployment(type = WAR)
public class MyEndpointIT {

    @ArquillianResource
    private URI uri;

    @Deployment
    public static WARArchive createDeployment() throws Exception {
        return ShrinkWrap.create(WARArchive.class);
    }

    @Test
    public void shouldGet() {
        Client client = ClientBuilder.newClient();
        Invocation.Builder request = client.target(uri)
                .path("/api/my-endpoint")
                .request();

        Response response = request.get();

        assertThat(response.getStatusInfo(), is(OK));
    }
}  

Problem: The test works only if I put it into the root level of package hierarchy. Let's say my project structure looks like this.

com
├ mycompany
| ├ rest
| | └ MyEndpoint.java
| ├ service
| | └ MyService.java

If I create the integration test in com.mycompany.rest it fails with NoClassDefFoundError:

ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 5) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./: java.lang.NoClassDefFoundError: Lcom/mycompany/service/MyService;

...

Caused by: java.lang.ClassNotFoundException: com.mycompany.service.MyService from [Module "deployment.MyEndpointIT.war:main" from Service Module Loader]

But if I add my test one level higher it works fine (mens into the com.mycompany package).

Question: Why the test work in such a strange way? Is it documented behaviour? How can I put my tests into the same packages where the tested classes are?

I also tried to use trick like this:

warArchive.addClass(MyService.class);

but it didn't help.

Upvotes: 0

Views: 299

Answers (2)

fangdi
fangdi

Reputation: 121

when you create your WARArchive, please try to add your desired packages:

return ShrinkWrap.create(WARArchive.class, "your-company.war")
         .addPackages(true, "com.yourcompany");

Upvotes: 0

Ladicek
Ladicek

Reputation: 6577

One: if you add a @DefaultDeployment annotation, you shouldn't add a @Deployment annotation at the same time. @DefaultDeployment builds a deployment archive for you based on some "sensible defaults".

Two, the "sensible defaults" don't work for you at the current form. @DefaultDeployment builds a deployment archive that contains classes from the package the test resides in and all the subpackages. If that doesn't work for you, you can always remove the @DefaultDeployment annotation and build a deployment manually using plain old @Deployment.

Upvotes: 1

Related Questions