This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 0e062b1e5b3658c0447a389da6d95fe662b97aeb Author: Andriy Redko <[email protected]> AuthorDate: Sun Nov 10 14:45:32 2024 -0500 CXF-9076: Exception message is not unmarshalled with JDK17+ (#2137) --- .../cxf/interceptor/ClientFaultConverter.java | 25 ++++++++-- .../systest/jaxws/ClientServerExceptionServer.java | 56 ++++++++++++++++++++++ .../systest/jaxws/ClientServerExceptionTest.java | 54 +++++++++++++++++++++ .../apache/cxf/systest/jaxws/ExceptionService.java | 27 +++++++++++ 4 files changed, 158 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java b/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java index e6b9f97705..c2c1f9c365 100644 --- a/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java +++ b/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java @@ -191,17 +191,34 @@ public class ClientFaultConverter extends AbstractInDatabindingInterceptor { LogUtils.log(LOG, Level.INFO, "EXCEPTION_WHILE_CREATING_EXCEPTION", e1, e1.getMessage()); } } else { - if (fault.getMessage() != null) { + Exception ex = (Exception)e; + final String message = fault.getMessage(); + if (message != null) { Field f; try { f = Throwable.class.getDeclaredField("detailMessage"); ReflectionUtil.setAccessible(f); - f.set(e, fault.getMessage()); + f.set(ex, fault.getMessage()); } catch (Exception e1) { - //ignore + try { + // Fallback, try to clone the exception instead of accessing the detailMessage over reflection + final Constructor<? extends Object> constructor = ReflectionUtil.getConstructor(ex.getClass(), + String.class, Throwable.class); /* String message, Throwable cause */ + + if (constructor != null) { + final Exception clone = (Exception) constructor.newInstance(message, ex.getCause()); + clone.setStackTrace(ex.getStackTrace()); + if (ex.getSuppressed().length > 0) { + Arrays.stream(ex.getSuppressed()).forEach(clone::addSuppressed); + } + ex = clone; + } + } catch (Exception e2) { + /* nothing to do */ + } } } - msg.setContent(Exception.class, e); + msg.setContent(Exception.class, ex); } } diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionServer.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionServer.java new file mode 100644 index 0000000000..a20db6bd12 --- /dev/null +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionServer.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.systest.jaxws; + +import javax.jws.WebService; +import javax.xml.ws.Endpoint; + +import org.apache.cxf.testutil.common.AbstractBusTestServerBase; + +public class ClientServerExceptionServer extends AbstractBusTestServerBase { + static final String PORT = allocatePort(ClientServerExceptionServer.class); + + @WebService(endpointInterface = "org.apache.cxf.systest.jaxws.ExceptionService", + serviceName = "ExceptionService", targetNamespace = "http://cxf.apache.org/") + static class ExceptionServiceImpl implements ExceptionService { + @Override + public String saySomething(String text) throws IllegalArgumentException { + throw new IllegalArgumentException("Simulated!"); + } + } + + protected void run() { + Object implementor = new ExceptionServiceImpl(); + String address = "http://localhost:" + PORT + "/ExceptionService"; + Endpoint.publish(address, implementor); + } + + public static void main(String[] args) { + try { + ClientServerExceptionServer s = new ClientServerExceptionServer(); + s.start(); + } catch (Exception ex) { + ex.printStackTrace(); + System.exit(-1); + } finally { + System.out.println("done!"); + } + } +} diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionTest.java new file mode 100644 index 0000000000..d0e8fe499c --- /dev/null +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerExceptionTest.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.systest.jaxws; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; + +import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; + +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +public class ClientServerExceptionTest extends AbstractBusClientServerTestBase { + @BeforeClass + public static void startServers() throws Exception { + assertTrue("server did not launch correctly", launchServer(ClientServerExceptionServer.class, true)); + } + + @Test + public void exceptionMessageIsPreserved() throws MalformedURLException { + URL wsdlURL = new URL("http://localhost:" + ClientServerExceptionServer.PORT + "/ExceptionService?wsdl"); + QName qname = new QName("http://cxf.apache.org/", "ExceptionService"); + Service service = Service.create(wsdlURL, qname); + ExceptionService port = service.getPort(ExceptionService.class); + + final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, + () -> port.saySomething("Hello World!")); + assertEquals("Simulated!", ex.getMessage()); + } +} diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ExceptionService.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ExceptionService.java new file mode 100644 index 0000000000..fa2a525fa7 --- /dev/null +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ExceptionService.java @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.systest.jaxws; + +import javax.jws.WebService; + +@WebService +interface ExceptionService { + String saySomething(String text) throws IllegalArgumentException; +}
