I'm trying to add the package org.jibble.pircbot to my test archive using shrinkwrap. I've tried every variation I can think of, but in all cases the package is not found. However, for some reason, the classes can be added individually, but any anonymous inner classes are not added.
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class, "RcCustomerTest.war")
// .addPackages(true, PircBot.class.getPackage())
// .addPackages(true, "org.jibble.pircbot")
.addClasses(PircBot.class,
ReplyConstants.class,
IrcException.class,
NickAlreadyInUseException.class,
InputThread.class,
OutputThread.class,
Queue.class)
.addClass(DccManager.class) // Inner classes not added!
.addPackages(true, "com.recursiveloop.webcommon")
.addPackages(true, "com.recursiveloop.jloop.core.irc")
.addAsResource("config.properties")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource("jboss-web.xml", "jboss-web.xml")
.addAsWebInfResource("jboss-deployment-structure.xml", "jboss-deployment-structure.xml")
.addAsResource("persistence.xml", "META-INF/persistence.xml")
.setWebXML("web.xml");
}
This results in the exception
...
Caused by: java.lang.NoClassDefFoundError: org/jibble/pircbot/DccManager$1
at org.jibble.pircbot.PircBot.<init>(PircBot.java:3081)
...
This is odd because browsing the shrinkwrap source code I found a function that makes the following assertion
Assert.assertTrue("Adding a class should also add the anonymous inner classes",
getArchive().contains(expectedPathAnonymousInnerClass));
But sadly, it seems that no test cases actually call this function.
However, the question remains - why isn't shrinkwrap finding the package when I call addPackages(true, "org.jibble.pircbot")? I look at the resulting archive and there's no sign of org.jibble.pircbot, and obviously there are the inevitable ClassDefNotFound exceptions:
...
Caused by: java.lang.NoClassDefFoundError: Failed to link com/recursiveloop/jloop/core/irc/VisitorConnection (Module "deployment.RcCustomerTest.war:main" from Service Module Loader): org/jibble/pircbot/PircBot
...
I'm using gradle, but if I was using maven, the maven resolver would probably do the job. There's a gradle resolver, but it doesn't quite do the same thing. My best attempt at using it was as follows
return ShrinkWrap.create(EmbeddedGradleImporter.class)
.forProjectDirectory()
.forTasks("integTestWar")
.importBuildOutput("build/libs/integTest.war").as(WebArchive.class);
This kicks off a gradle task and inserts the test classes into the resulting archive. The challenge was getting gradle to build a correct war file. I wanted it to contain the resource files (deployment descriptor's etc.) belonging to the integration test sourceset, not the main sourceset, but I just couldn't get it to work.
FYI I'm using shrinkwrap version 1.2.3, which is the latest.
Any help would be much appreciated.
I solved it by using the maven resolver as follows:
return ShrinkWrap.create(WebArchive.class, "RcCustomerTest.war")
.addAsLibraries(Maven.resolver()
.loadPomFromFile("build/pom.xml")
.resolve("pircbot:pircbot")
.withTransitivity().asFile())
...
The POM file is generated using gradle's eclipse plugin, like so
task writeNewPom << {
pom {
writeTo("$buildDir/pom.xml")
}
}
which is set to run before the integration test.
It turns out that the maven resolver can be used without a POM, but you'd have to specify the artifact in the test and make sure it remains up-to-date with what your project uses. Integration tests are already a pain to maintain, so it's better to resolve the dependency from the POM so you know that it's the right version (one less thing to worry about).