I’m using the jvm-test-suit plugin to configure integration tests, similar to what’s shown in The JVM Test Suite Plugin. I use Arquillian and ShrinkWrap to run them. However, I noticed that once injections (@Inject) are used, the tests pass automatically, even if they should fail (assertTrue(false)). This is because the injections fail. There are a lot of posts about this symptom, but the causes are varied.
I don’t know if the problem comes from Gradle, Arquillian, or ShrinkWrap (which uses the Gradle resolver through the Gradle API Toolings), but in an effort to eliminate causes, I’m asking for someone to have a look at this minimal project. It has one empty bean and one test class that injects that bean. The test can be run with ./gradlew :lib:integrationTest and will pass (wrong behavior). If the injection is commented out, it will fail correctly.
Note that the arquillian.xml points to the Wildfly location, which should be changed according to the environment. It can be downloaded from WildFly Downloads.
If I can be told if the problem is in Arquillian or the ShrinkWrap resolver it will also help a lot.
It’s not really the injection that is the problem.
If you just comment the @Inject it shows the exact same behavior.
When Jupiter tries to load your test class it throws this exception as the Service class is not found:
java.lang.NoClassDefFoundError: testArq/Service
at java.base/java.lang.Class.getDeclaredFields0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3297)
at java.base/java.lang.Class.getDeclaredFields(Class.java:2371)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.commons.util.ReflectionUtils.getDeclaredFields(ReflectionUtils.java:1470)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.commons.util.ReflectionUtils.findAllFieldsInHierarchy(ReflectionUtils.java:1200)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.commons.util.ReflectionUtils.findFields(ReflectionUtils.java:1188)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.jupiter.engine.descriptor.ExtensionUtils.registerExtensionsFromFields(ExtensionUtils.java:96)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:150)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:80)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.execute(JUnitJupiterTestRunner.java:57)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.executeTest(ServletTestRunner.java:139)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.execute(ServletTestRunner.java:117)
at deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.doGet(ServletTestRunner.java:86)
at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73)
at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.core@2.3.12.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.core@2.3.12.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at org.wildfly.security.elytron-web.undertow-server-servlet@4.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44)
at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at io.undertow.core@2.3.12.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256)
at io.undertow.servlet@2.3.12.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101)
at io.undertow.core@2.3.12.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
at io.undertow.core@2.3.12.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
at org.jboss.xnio@3.8.13.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.ClassNotFoundException: testArq.Service from [Module "deployment.786f5493-fa58-40d7-b59d-ad408628bcfb.war" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:200)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
... 83 more
The exception is reported as test failure on the CONTAINER node, which is the test class.
But the org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.ArquillianTestMethodExecutionListener ignores this as it only listens for results from the actual test nodes and thus ignores the failure, swallowing the problem.
Thanks for the help! How did you get this stack trace? It didn’t appear for me.
Any idea what would cause the class to not be found? Sounds like ShrinkWrap isn’t including everything it needs to, though the test suit defines implementation(project()), which should include Service.
I also tried to remove the use of the test suit plugin and moved the contents of integrationTest to test since that one is created for me by the java plugin. So with “dumb old Gradle”:
tasks.withType(Test).configureEach {
useJUnitPlatform()
}
dependencies {
providedCompile("jakarta.platform:jakarta.jakartaee-api:$jakartaVersion")
testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion")
// testImplementation(project(path)) // tried with and without this
testImplementation("org.jboss.arquillian.junit5:arquillian-junit5-container:$arquillianVersion")
testImplementation("org.jboss.arquillian.protocol:arquillian-protocol-servlet-jakarta:$arquillianServletProtocolVersion")
testImplementation("org.wildfly.arquillian:wildfly-arquillian-container-managed:$arquillianWildflyContainerVersion")
testImplementation("org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain:$shrinkwrapResolverVersion")
}
So Service is there, but not inside WEB-INF, which is my guess as to why it doesn’t get picked up. The way ShrinkWrap creates the war is with the Gradle importer (it’s inside the sample project):
Thanks for the help! How did you get this stack trace? It didn’t appear for me.
Debugger
Sounds like ShrinkWrap isn’t including everything it needs to, though the test suit defines implementation(project()), which should include Service.
Afair the intention of Arquillian folks is, that you use shrinkwrap to add all production and test classes need for that test case, so that you produce a minimal deployment. We are work build our full deployment and just add in the test classes and use a plugin that only deploys once for several tests instead for every test. Both has its pros and cons as always. But that is not a Gradle topic actually.
I also tried to remove the use of the test suit plugin and moved the contents
No, you did not.
It is also just one of those test suites it is just registered and configured for you by the Java plugin.
Yes, I used it, but maybe I didn’t debug the right place. I was focused on the injection failing
Afair the intention of Arquillian folks is, that you use shrinkwrap to add all production and test classes need for that test case, so that you produce a minimal deployment. We are work build our full deployment and just add in the test classes and use a plugin that only deploys once for several tests instead for every test. Both has its pros and cons as always.
No, you did not.
It is also just one of those test suites it is just registered and configured for you by the Java plugin.
Well, I meant that I removed the jvm-test-suit plugin and the whole associated configuration block
plugins {
id "java"
id "war"
// id "jvm-test-suite"
}
...
//testing {
// suites {
...
I understand that the Java plugin actually creates the test suit for me, but I was trying to eliminate the possibility that the plugin was not playing nice with ShrinkWrap. Turned out not to be the case, which is not surprising.
Anyway, thanks again Vampire! I’ll take this to ShrinkWrap.
The deployment happens once for all tests, like in your case, if one uses the Arquillian Suite Extension
Yes, that’s what what we use.
Otherwise these tests take O(10) times longer at the very least, in my experience.
If you build a full deployment and it is big, yes. If you build minimal deployments like intended by Arquillian folks, the deployment also works much faster. But then it is further away from the production environment. As I said, all have its pros and cons.
Well, I meant that I removed the jvm-test-suit plugin […] I was trying to eliminate the possibility that the plugin was not playing nice with ShrinkWrap.
And I said no, you didn’t.
You removed the useless no-operation line id "jvm-test-suite". But as the plugin is applied by Java plugin already, that line has no effect anyway.