Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the handling of exception propagation #656

Merged
merged 5 commits into from
Jan 10, 2025

Conversation

starksm64
Copy link
Member

@starksm64 starksm64 commented Dec 17, 2024

This is a first step that preserves the current unit tests, but I think we need to be more aggressive at restoring the original exception from the type hierarchy and almost never actually see an ArquillianProxyException. The only time it would be seen is if none of the exception types could be loaded on the client.

Fixes #641

@jamezp
Copy link
Collaborator

jamezp commented Jan 9, 2025

Sorry for the long delay on this. I build this PR and did a quick test with WildFly and I'm still seeing the same exception. Is that expected? I know this is not a complete fix so I thought I'd ask before debugging further.

@starksm64
Copy link
Member Author

Sorry for the long delay on this. I build this PR and did a quick test with WildFly and I'm still seeing the same exception. Is that expected? I know this is not a complete fix so I thought I'd ask before debugging further.

I think the exception should look a bit better with more info, but ArquillianProxyException is still thrown.

The ExceptionProxyTestCase#handleExceptionClassNotOnClientClasspath test shows the expected output for an exception thrown on the server that is not on the client:

Client exception from proxy: org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.arquillian.test.spi.serveronly.SomeNonClientSideException : The server side reason for this exception [Proxied because : Original exception caused: class java.lang.ClassNotFoundException: org.jboss.arquillian.test.spi.serveronly.SomeNonClientSideException]
Client exception trace from proxy:
org.jboss.arquillian.test.spi.ArquillianProxyException: org.jboss.arquillian.test.spi.serveronly.SomeNonClientSideException : The server side reason for this exception [Proxied because : Original exception caused: class java.lang.ClassNotFoundException: org.jboss.arquillian.test.spi.serveronly.SomeNonClientSideException]
	at org.jboss.arquillian.test.spi.serveronly.SomeBean.invokeImplNested(SomeBean.java:18)
	at org.jboss.arquillian.test.spi.serveronly.SomeBean.invokeImpl(SomeBean.java:15)
	at org.jboss.arquillian.test.spi.serveronly.SomeBean.invoke(SomeBean.java:11)
	at org.jboss.arquillian.test.spi.ExceptionProxyTestCase.causeServerException(ExceptionProxyTestCase.java:129)
	at org.jboss.arquillian.test.spi.ExceptionProxyTestCase.handleExceptionClassNotOnClientClasspath(ExceptionProxyTestCase.java:108)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.lang.ClassNotFoundException: org.jboss.arquillian.test.spi.serveronly.SomeNonClientSideException
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:529)
	at java.base/java.lang.Class.forName(Class.java:508)
	at java.base/java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:789)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2046)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1912)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2237)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1747)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:525)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:483)
	at org.jboss.arquillian.test.spi.ExceptionProxy.readExternal(ExceptionProxy.java:195)
	at java.base/java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:2318)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2267)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1747)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:525)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:483)
	at org.jboss.arquillian.test.spi.ExceptionProxyTestCase.serialize(ExceptionProxyTestCase.java:144)
	at org.jboss.arquillian.test.spi.ExceptionProxyTestCase.handleExceptionClassNotOnClientClasspath(ExceptionProxyTestCase.java:110)
	... 25 more

In the next step ArquillianProxyException would not be thrown and instead this should show as an IException which is the common exception between the client and the server side SomeNonClientSideException.

@starksm64
Copy link
Member Author

@jamezp See if the latest push fixes the exception type. If it does not, I'll have to create a more realistic server side exception testcase.

@jamezp
Copy link
Collaborator

jamezp commented Jan 10, 2025

The exception isn't great:

``` [ERROR] org.jboss.resteasy.test.client.other.DefaultClientHttpEngineTest.injectedClient -- Time elapsed: 0.147 s <<< ERROR! java.lang.RuntimeException at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.getTestResult(JUnitJupiterTestRunner.java:101) at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.access$100(JUnitJupiterTestRunner.java:69) at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.execute(JUnitJupiterTestRunner.java:58) at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.executeTest(ServletTestRunner.java:139) at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.execute(ServletTestRunner.java:117) at deployment.DefaultClientHttpEngineTest.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.doGet(ServletTestRunner.java:86) at [email protected]//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:633) at [email protected]//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:723) at [email protected]//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at [email protected]//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at [email protected]//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at [email protected]//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at [email protected]//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68) at [email protected]//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103) at [email protected]//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161) at [email protected]//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73) at [email protected]//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67) at [email protected]//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at [email protected]//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) at [email protected]//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at [email protected]//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at [email protected]//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at [email protected]//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at org.wildfly.security.elytron-web.undertow-server-servlet@4.1.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38) at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at [email protected]//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44) at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at [email protected]//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51) at [email protected]//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) at [email protected]//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at [email protected]//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1421) at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) at [email protected]//io.undertow.server.Connectors.executeRootHandler(Connectors.java:395) at [email protected]//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:861) at [email protected]//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at [email protected]//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) at [email protected]//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) at java.base/java.lang.Thread.run(Thread.java:840) ```

I'll create a reproducer for this so we have an easy way to see it.

@jamezp
Copy link
Collaborator

jamezp commented Jan 10, 2025

@starksm64
Copy link
Member Author

Ok, thanks, I'll take a look. Either the weld exception is not a subclass of a jakarta exception or for some reason it could not be created.

@starksm64
Copy link
Member Author

Try the lastest push. With this the test run produces:

[INFO] Running dev.resteasy.examples.InjectedClientTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 16.41 s <<< FAILURE! -- in dev.resteasy.examples.InjectedClientTest
[ERROR] dev.resteasy.examples.InjectedClientTest.checkClientInstance -- Time elapsed: 6.236 s <<< ERROR!
java.lang.RuntimeException: org.opentest4j.AssertionFailedError: Unexpected type, expected: <org.jboss.resteasy.client.jaxrs.ResteasyClient> but was: <org.jboss.weld.generated.proxies.ws.rs.client.Client$Configurable$AutoCloseable$2078960113$Proxy$_$$_WeldClientProxy>
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.getTestResult(JUnitJupiterTestRunner.java:101)
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner$ArquillianTestMethodExecutionListener.access$100(JUnitJupiterTestRunner.java:69)
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.war//org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.execute(JUnitJupiterTestRunner.java:58)
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.executeTest(ServletTestRunner.java:139)
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.war//org.jboss.arquillian.protocol.servlet5.runner.ServletTestRunner.execute(ServletTestRunner.java:117)
        at deployment.7e3a45dc-8175-4a84-b867-ac0b8a804d0b.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)

Copy link
Collaborator

@jamezp jamezp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @starksm64. Thank you for digging into this. I'm seeing exactly what I'd expect to see.

@starksm64 starksm64 changed the title Step 1 of improving the handling of exception propagation Iimprove the handling of exception propagation Jan 10, 2025
@starksm64 starksm64 changed the title Iimprove the handling of exception propagation Improve the handling of exception propagation Jan 10, 2025
@starksm64 starksm64 merged commit 642cf7f into arquillian:main Jan 10, 2025
14 checks passed
@starksm64 starksm64 deleted the issue641 branch January 10, 2025 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants