From 76bb7ac3b4bbc264fb9b34521a2f9a0815723edf Mon Sep 17 00:00:00 2001 From: Jim Ma Date: Wed, 13 Nov 2024 16:24:21 +0800 Subject: [PATCH 1/4] [JBEAP-28311][JBWS-4430]:Sever throws IllegalStateException when call a handler with the CDI bean invocation --- .../stack/cxf/configuration/BusHolder.java | 2 + .../interceptor/HandlerAuthInterceptor.java | 104 ++++++++++++++---- .../cxf/interceptor/SecurityActions.java | 81 ++++++++++++++ modules/testsuite/cxf-tests/pom.xml | 5 + .../ws/jaxws/cxf/jbws4430/DelegateBean.java | 30 +++++ .../test/ws/jaxws/cxf/jbws4430/EmptyBean.java | 28 +++++ .../test/ws/jaxws/cxf/jbws4430/Hello.java | 29 +++++ .../test/ws/jaxws/cxf/jbws4430/HelloBean.java | 37 +++++++ .../jaxws/cxf/jbws4430/JBWS4430TestCase.java | 75 +++++++++++++ .../ws/jaxws/cxf/jbws4430/LoggingHandler.java | 55 +++++++++ .../jaxws/cxf/jbws4430/WEB-INF/web.xml | 17 +++ .../cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl | 56 ++++++++++ .../resources/jaxws/cxf/jbws4430/handlers.xml | 8 ++ pom.xml | 8 +- 14 files changed, 515 insertions(+), 20 deletions(-) create mode 100644 modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/SecurityActions.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/DelegateBean.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/EmptyBean.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/Hello.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/LoggingHandler.java create mode 100644 modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/web.xml create mode 100644 modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl create mode 100644 modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/handlers.xml diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java index 6acb29834..201456a95 100644 --- a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java @@ -370,6 +370,8 @@ protected void setInterceptors(Bus bus, Deployment dep, Map prop final String p = (props != null) ? props.get(Constants.JBWS_CXF_DISABLE_HANDLER_AUTH_CHECKS) : null; if ((p == null || (!"true".equalsIgnoreCase(p) && !"1".equalsIgnoreCase(p))) && !Boolean.getBoolean(Constants.JBWS_CXF_DISABLE_HANDLER_AUTH_CHECKS)) { bus.getInInterceptors().add(new HandlerAuthInterceptor()); + } else { + bus.getInInterceptors().add(new HandlerAuthInterceptor(true)); } final SOAPAddressRewriteMetadata sarm = dep.getAttachment(SOAPAddressRewriteMetadata.class); diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java index b75d1aa9b..32f697f4a 100644 --- a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java @@ -44,6 +44,7 @@ import org.apache.cxf.security.SecurityContext; import org.apache.cxf.service.invoker.MethodDispatcher; import org.apache.cxf.service.model.BindingOperationInfo; +import org.jboss.ws.common.utils.DelegateClassLoader; import org.jboss.wsf.spi.deployment.Endpoint; import org.jboss.wsf.spi.security.EJBMethodSecurityAttribute; import org.jboss.wsf.spi.security.EJBMethodSecurityAttributeProvider; @@ -51,19 +52,36 @@ /** * Interceptor which checks the current principal is authorized to * call a given handler - * + * * @author alessio.soldano@jboss.com * @since 23-Sep-2013 */ public class HandlerAuthInterceptor extends AbstractPhaseInterceptor { private static final String KEY = HandlerAuthInterceptor.class.getName() + ".SECURITY_EXCEPTION"; - + + private final boolean skip; public HandlerAuthInterceptor() { super(Phase.PRE_PROTOCOL_FRONTEND); addBefore(SOAPHandlerInterceptor.class.getName()); addBefore(LogicalHandlerInInterceptor.class.getName()); + skip = false; + } + /** + * Create a {@code HandlerAuthInterceptor} that can optionally skip authentication. + * When the authentication is skipped, it added a customized {@code JBossWSHandlerChainInvoker} + * which set the correct TCCL to allow the handler to access CDI + * Please see + * This interceptor will be added to CXF interceptor chain + * @param skipAuth a boolean flag indicating whether to skip authentication. + **/ + public HandlerAuthInterceptor(boolean skipAuth) + { + super(Phase.PRE_PROTOCOL_FRONTEND); + addBefore(SOAPHandlerInterceptor.class.getName()); + addBefore(LogicalHandlerInInterceptor.class.getName()); + skip = skipAuth; } @Override @@ -74,61 +92,110 @@ public void handleMessage(Message message) throws Fault if (null == invoker) { final org.apache.cxf.endpoint.Endpoint endpoint = ex.getEndpoint(); - if (endpoint instanceof JaxWsEndpointImpl) { // JAXWS handlers are not assigned to different endpoint types + if (endpoint instanceof JaxWsEndpointImpl) { // JAXWS handlers are not assigned to different endpoint types final JaxWsEndpointImpl ep = (JaxWsEndpointImpl)endpoint; @SuppressWarnings("rawtypes") final List handlerChain = ep.getJaxwsBinding().getHandlerChain(); if (handlerChain != null && !handlerChain.isEmpty()) { //save - invoker = new JBossWSHandlerChainInvoker(handlerChain, isOutbound(message, ex)); + invoker = new JBossWSHandlerChainInvoker(handlerChain, isOutbound(message, ex), skip); ex.put(HandlerChainInvoker.class, invoker); } } } } - + private boolean isOutbound(Message message, Exchange ex) { return message == ex.getOutMessage() - || message == ex.getOutFaultMessage(); + || message == ex.getOutFaultMessage(); } - + private static class JBossWSHandlerChainInvoker extends HandlerChainInvoker { + private final boolean skip; public JBossWSHandlerChainInvoker(@SuppressWarnings("rawtypes") List hc, boolean isOutbound) { super(hc, isOutbound); + skip = false; + } + + public JBossWSHandlerChainInvoker(@SuppressWarnings("rawtypes") List hc, boolean isOutbound, boolean skipAuth) + { + super(hc, isOutbound); + skip = skipAuth; } @Override public boolean invokeLogicalHandlers(boolean requestor, LogicalMessageContext context) { - checkAuthorization(context); - return super.invokeLogicalHandlers(requestor, context); + if (!skip) { + checkAuthorization(context); + } + ClassLoader original = SecurityActions.getContextClassLoader(); + try { + if (original instanceof DelegateClassLoader) { + DelegateClassLoader delegateClassLoader = (DelegateClassLoader)original; + SecurityActions.setContextClassLoader(delegateClassLoader.getDelegate()); + } + return super.invokeLogicalHandlers(requestor, context); + } finally { + SecurityActions.setContextClassLoader(original); + } } @Override public boolean invokeProtocolHandlers(boolean requestor, MessageContext context) { - checkAuthorization(context); - return super.invokeProtocolHandlers(requestor, context); + if (!skip) { + checkAuthorization(context); + } + ClassLoader original = SecurityActions.getContextClassLoader(); + try { + if (original instanceof DelegateClassLoader) { + DelegateClassLoader delegateClassLoader = (DelegateClassLoader)original; + SecurityActions.setContextClassLoader(delegateClassLoader.getDelegate()); + } + return super.invokeProtocolHandlers(requestor, context); + } finally { + SecurityActions.setContextClassLoader(original); + } } - + @Override public boolean invokeLogicalHandlersHandleFault(boolean requestor, LogicalMessageContext context) { - if (context.containsKey(KEY)) { + + if (!skip && context.containsKey(KEY)) { return true; } - return super.invokeLogicalHandlersHandleFault(requestor, context); + ClassLoader original = SecurityActions.getContextClassLoader(); + try { + if (original instanceof DelegateClassLoader) { + DelegateClassLoader delegateClassLoader = (DelegateClassLoader)original; + SecurityActions.setContextClassLoader(delegateClassLoader.getDelegate()); + } + return super.invokeLogicalHandlersHandleFault(requestor, context); + } finally { + SecurityActions.setContextClassLoader(original); + } } @Override public boolean invokeProtocolHandlersHandleFault(boolean requestor, MessageContext context) { - if (context.containsKey(KEY)) { + if (!skip && context.containsKey(KEY)) { return true; } - return super.invokeProtocolHandlersHandleFault(requestor, context); + ClassLoader original = SecurityActions.getContextClassLoader(); + try { + if (original instanceof DelegateClassLoader) { + DelegateClassLoader delegateClassLoader = (DelegateClassLoader)original; + SecurityActions.setContextClassLoader(delegateClassLoader.getDelegate()); + } + return super.invokeProtocolHandlersHandleFault(requestor, context); + } finally { + SecurityActions.setContextClassLoader(original); + } } protected void checkAuthorization(MessageContext ctx) @@ -141,7 +208,7 @@ protected void checkAuthorization(MessageContext ctx) Exchange exchange = message.getExchange(); Endpoint ep = exchange.get(Endpoint.class); EJBMethodSecurityAttributeProvider attributeProvider = ep - .getAttachment(EJBMethodSecurityAttributeProvider.class); + .getAttachment(EJBMethodSecurityAttributeProvider.class); if (attributeProvider != null) //ejb endpoints only can be associated with this... { SecurityContext secCtx = message.get(SecurityContext.class); @@ -177,5 +244,4 @@ protected void checkAuthorization(MessageContext ctx) } } } - -} +} \ No newline at end of file diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/SecurityActions.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/SecurityActions.java new file mode 100644 index 000000000..035bcb5d1 --- /dev/null +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/SecurityActions.java @@ -0,0 +1,81 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2014, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.wsf.stack.cxf.interceptor; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * + * @author alessio.soldano@jboss.com + * @since 17-Feb-2010 + * + */ +class SecurityActions +{ + /** + * Get context classloader. + * + * @return the current context classloader + */ + static ClassLoader getContextClassLoader() + { + SecurityManager sm = System.getSecurityManager(); + if (sm == null) + { + return Thread.currentThread().getContextClassLoader(); + } + else + { + return AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + /** + * Set context classloader. + * + * @param classLoader the classloader + */ + static void setContextClassLoader(final ClassLoader classLoader) + { + if (System.getSecurityManager() == null) + { + Thread.currentThread().setContextClassLoader(classLoader); + } + else + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Thread.currentThread().setContextClassLoader(classLoader); + return null; + } + }); + } + } +} diff --git a/modules/testsuite/cxf-tests/pom.xml b/modules/testsuite/cxf-tests/pom.xml index fa7229f11..0e6dad0cf 100644 --- a/modules/testsuite/cxf-tests/pom.xml +++ b/modules/testsuite/cxf-tests/pom.xml @@ -102,6 +102,11 @@ ${wildfly.elytron.version} test + + javax.enterprise + cdi-api + test + diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/DelegateBean.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/DelegateBean.java new file mode 100644 index 000000000..52f6a1f4d --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/DelegateBean.java @@ -0,0 +1,30 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +import javax.enterprise.context.Dependent; +import javax.enterprise.inject.spi.CDI; + +@Dependent +public class DelegateBean { + EmptyBean logic = CDI.current().select(EmptyBean.class).get(); +} \ No newline at end of file diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/EmptyBean.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/EmptyBean.java new file mode 100644 index 000000000..081103f91 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/EmptyBean.java @@ -0,0 +1,28 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +import javax.enterprise.context.Dependent; + +@Dependent +public class EmptyBean { +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/Hello.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/Hello.java new file mode 100644 index 000000000..6d9a3306f --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/Hello.java @@ -0,0 +1,29 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +@javax.jws.WebService(wsdlLocation = "WEB-INF/wsdl/HelloWorld.wsdl") +public interface Hello { + + @javax.jws.WebMethod + public String hello(String name); +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java new file mode 100644 index 000000000..ba7e5d0d4 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java @@ -0,0 +1,37 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +import javax.jws.HandlerChain; + +@javax.jws.WebService(targetNamespace = "http://test.ws.jboss.org/", + wsdlLocation = "WEB-INF/wsdl/HelloWorld.wsdl") +@HandlerChain(file = "/handlers.xml") +public class HelloBean { + public HelloBean() { + } + + @javax.jws.WebMethod + public String hello(String name) { + return "Hello " + name; + } +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java new file mode 100644 index 000000000..ec8297304 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java @@ -0,0 +1,75 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +import javax.xml.ws.Service; +import java.io.File; +import java.net.URL; +import javax.xml.namespace.QName; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.FileAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.wsf.test.JBossWSTest; +import org.jboss.wsf.test.JBossWSTestHelper; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(Arquillian.class) +public class JBWS4430TestCase extends JBossWSTest { + private static final String DEP = "jaxws-cxf-jbws4430"; + + @ArquillianResource + private URL baseURL; + + @Deployment(name = DEP, testable = false) + public static WebArchive createDeployment() { + WebArchive archive = ShrinkWrap.create(WebArchive.class, DEP + ".war"); + archive.setManifest(new StringAsset("Manifest-Version: 1.0\n" + + "Dependencies: org.apache.cxf\n")) + .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, LoggingHandler.class) + .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl"), "wsdl/HelloWorld.wsdl") + .add(new FileAsset(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/handlers.xml")), "WEB-INF/classes/handlers.xml") + .setWebXML(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/web.xml")); + return archive; + } + + @Test + @RunAsClient + public void testWS() throws Exception { + QName serviceName = new QName("http://test.ws.jboss.org/", "HelloBeanService"); + QName portName = new QName("http://test.ws.jboss.org/", "HelloBeanPort"); + + URL wsdlURL = new URL(baseURL + "?wsdl"); + + Service service = Service.create(wsdlURL, serviceName); + Hello proxy = (Hello) service.getPort(portName, Hello.class); + assertEquals("Hello jbossws", proxy.hello("jbossws")); + + } + + +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/LoggingHandler.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/LoggingHandler.java new file mode 100644 index 000000000..22b423f8c --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/LoggingHandler.java @@ -0,0 +1,55 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; + +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; +import java.util.Collections; +import java.util.Set; +import javax.xml.namespace.QName; + +public class LoggingHandler implements SOAPHandler { + @Override + public boolean handleMessage(SOAPMessageContext soapMessageContext) { + boolean isOutBound = (boolean) soapMessageContext.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY); + if (isOutBound) { + new DelegateBean(); + } + return true; + } + + @Override + public Set getHeaders() { + return Collections.emptySet(); + } + + @Override + public boolean handleFault(SOAPMessageContext soapMessageContext) { + return true; + } + + @Override + public void close(MessageContext messageContext) { + // no-operation + } +} diff --git a/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/web.xml b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/web.xml new file mode 100644 index 000000000..58dc9d622 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + + + + HelloBean + org.jboss.test.ws.jaxws.cxf.jbws4430.HelloBean + + + + HelloBean + /* + + diff --git a/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl new file mode 100644 index 000000000..e607a1fb5 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/handlers.xml b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/handlers.xml new file mode 100644 index 000000000..eacf69809 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/jbws4430/handlers.xml @@ -0,0 +1,8 @@ + + + + + org.jboss.test.ws.jaxws.cxf.jbws4430.LoggingHandler + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 343ae3a26..969732a8f 100644 --- a/pom.xml +++ b/pom.xml @@ -65,12 +65,13 @@ 1.9.1.Final 1.1.2.Final 3.4.0.Final - 3.3.3.Final + 3.4.0-SNAPSHOT 1.4.0.Final 5.4.6.Final 24.0.0.Final 25.0.0.Final 2.0.0.Final + 2.0 3.5.1 9.1 3.3.1 @@ -1011,6 +1012,11 @@ + + javax.enterprise + cdi-api + ${cdi.api.version} + From 9215971c2f0d0d9432a1a967c0ac11f6ca5a8e27 Mon Sep 17 00:00:00 2001 From: Jim Ma Date: Thu, 24 Oct 2024 16:02:55 +0800 Subject: [PATCH 2/4] [JBEAP-28311][JBWS-4430]:Fix IllegalStateException in CXF interceptor when it tries to access CDI bean --- .../AbstractTCCLPhaseInterceptor.java | 57 +++++++++++++++++++ .../jaxws/cxf/jbws4430/CDIOutInterceptor.java | 40 +++++++++++++ .../test/ws/jaxws/cxf/jbws4430/HelloBean.java | 2 + .../jaxws/cxf/jbws4430/JBWS4430TestCase.java | 4 +- 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/AbstractTCCLPhaseInterceptor.java create mode 100644 modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/AbstractTCCLPhaseInterceptor.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/AbstractTCCLPhaseInterceptor.java new file mode 100644 index 000000000..ec9a18e46 --- /dev/null +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/AbstractTCCLPhaseInterceptor.java @@ -0,0 +1,57 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.wsf.stack.cxf.interceptor; + +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; + +public abstract class AbstractTCCLPhaseInterceptor extends AbstractPhaseInterceptor { + public AbstractTCCLPhaseInterceptor(String phase) { + super(null, phase, false); + } + + public AbstractTCCLPhaseInterceptor(String i, String p) { + super(i, p, false); + } + + public AbstractTCCLPhaseInterceptor(String phase, boolean uniqueId) { + super(null, phase, uniqueId); + } + + public AbstractTCCLPhaseInterceptor(String i, String p, boolean uniqueId) { + super(i,p, uniqueId); + } + + @Override + public void handleMessage(T message) throws Fault { + ClassLoaderUtils.ClassLoaderHolder origLoader = null; + try { + origLoader = ClassLoaderUtils.setThreadContextClassloader(this.getClass().getClassLoader()); + handleMessageWithTCCL(message); + } finally { + origLoader.reset(); + } + } + public abstract void handleMessageWithTCCL(T message) throws Fault; +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java new file mode 100644 index 000000000..f6919df16 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java @@ -0,0 +1,40 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2024, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.test.ws.jaxws.cxf.jbws4430; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.phase.Phase; +import org.jboss.wsf.stack.cxf.interceptor.AbstractTCCLPhaseInterceptor; + +public class CDIOutInterceptor extends AbstractTCCLPhaseInterceptor { + public CDIOutInterceptor() { + super(Phase.PRE_STREAM); + } + + @Override + public void handleMessageWithTCCL(Message message) throws Fault { + if (!MessageUtils.isRequestor(message)) { + DelegateBean bean = new DelegateBean(); + } + } +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java index ba7e5d0d4..4eb592a5c 100644 --- a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/HelloBean.java @@ -22,10 +22,12 @@ package org.jboss.test.ws.jaxws.cxf.jbws4430; import javax.jws.HandlerChain; +import org.apache.cxf.interceptor.OutInterceptors; @javax.jws.WebService(targetNamespace = "http://test.ws.jboss.org/", wsdlLocation = "WEB-INF/wsdl/HelloWorld.wsdl") @HandlerChain(file = "/handlers.xml") +@OutInterceptors(interceptors = {"org.jboss.test.ws.jaxws.cxf.jbws4430.CDIOutInterceptor"}) public class HelloBean { public HelloBean() { } diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java index ec8297304..3f950e4b8 100644 --- a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java @@ -49,8 +49,8 @@ public class JBWS4430TestCase extends JBossWSTest { public static WebArchive createDeployment() { WebArchive archive = ShrinkWrap.create(WebArchive.class, DEP + ".war"); archive.setManifest(new StringAsset("Manifest-Version: 1.0\n" - + "Dependencies: org.apache.cxf\n")) - .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, LoggingHandler.class) + + "Dependencies: org.jboss.ws.cxf.jbossws-cxf-server\n")) + .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, CDIOutInterceptor.class, LoggingHandler.class) .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl"), "wsdl/HelloWorld.wsdl") .add(new FileAsset(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/handlers.xml")), "WEB-INF/classes/handlers.xml") .setWebXML(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/web.xml")); From 212d3c47e13cc8dbb16631ecc1cf8b7bb82f11af Mon Sep 17 00:00:00 2001 From: Jim Ma Date: Fri, 1 Nov 2024 14:11:52 +0800 Subject: [PATCH 3/4] [JBEAP-28311][JBWS-4430]:Rename HandlerAuthInterceptor to HandlerConfigInterceptor;Improve comment and test --- .../stack/cxf/configuration/BusHolder.java | 6 ++--- ...tor.java => HandlerConfigInterceptor.java} | 27 ++++++++++--------- .../jaxws/cxf/jbws4430/CDIOutInterceptor.java | 1 + .../jaxws/cxf/jbws4430/JBWS4430TestCase.java | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) rename modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/{HandlerAuthInterceptor.java => HandlerConfigInterceptor.java} (91%) diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java index 201456a95..dacbd8623 100644 --- a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/configuration/BusHolder.java @@ -90,7 +90,7 @@ import org.jboss.wsf.stack.cxf.i18n.Messages; import org.jboss.wsf.stack.cxf.interceptor.EndpointAssociationInterceptor; import org.jboss.wsf.stack.cxf.interceptor.GracefulShutdownInterceptor; -import org.jboss.wsf.stack.cxf.interceptor.HandlerAuthInterceptor; +import org.jboss.wsf.stack.cxf.interceptor.HandlerConfigInterceptor; import org.jboss.wsf.stack.cxf.interceptor.NsCtxSelectorStoreInterceptor; import org.jboss.wsf.stack.cxf.interceptor.WSDLSoapAddressRewriteInterceptor; import org.jboss.wsf.stack.cxf.management.InstrumentationManagerExtImpl; @@ -369,9 +369,9 @@ protected void setInterceptors(Bus bus, Deployment dep, Map prop final String p = (props != null) ? props.get(Constants.JBWS_CXF_DISABLE_HANDLER_AUTH_CHECKS) : null; if ((p == null || (!"true".equalsIgnoreCase(p) && !"1".equalsIgnoreCase(p))) && !Boolean.getBoolean(Constants.JBWS_CXF_DISABLE_HANDLER_AUTH_CHECKS)) { - bus.getInInterceptors().add(new HandlerAuthInterceptor()); + bus.getInInterceptors().add(new HandlerConfigInterceptor()); } else { - bus.getInInterceptors().add(new HandlerAuthInterceptor(true)); + bus.getInInterceptors().add(new HandlerConfigInterceptor(true)); } final SOAPAddressRewriteMetadata sarm = dep.getAttachment(SOAPAddressRewriteMetadata.class); diff --git a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerConfigInterceptor.java similarity index 91% rename from modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java rename to modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerConfigInterceptor.java index 32f697f4a..65672106c 100644 --- a/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerAuthInterceptor.java +++ b/modules/server/src/main/java/org/jboss/wsf/stack/cxf/interceptor/HandlerConfigInterceptor.java @@ -50,38 +50,39 @@ import org.jboss.wsf.spi.security.EJBMethodSecurityAttributeProvider; /** - * Interceptor which checks the current principal is authorized to - * call a given handler - * + * Interceptor that configures a jbossws handler chain and can skip authentication. + * It set {@code JBossWSHandlerChainInvoker} to use correct Thread Context Class Loader + * and perform security checks before invoking the handlers. * @author alessio.soldano@jboss.com + * @author ema@redhat.com * @since 23-Sep-2013 */ -public class HandlerAuthInterceptor extends AbstractPhaseInterceptor +public class HandlerConfigInterceptor extends AbstractPhaseInterceptor { - private static final String KEY = HandlerAuthInterceptor.class.getName() + ".SECURITY_EXCEPTION"; + private static final String KEY = HandlerConfigInterceptor.class.getName() + ".SECURITY_EXCEPTION"; - private final boolean skip; - public HandlerAuthInterceptor() + private final boolean skipAuth; + public HandlerConfigInterceptor() { super(Phase.PRE_PROTOCOL_FRONTEND); addBefore(SOAPHandlerInterceptor.class.getName()); addBefore(LogicalHandlerInInterceptor.class.getName()); - skip = false; + skipAuth = false; } /** - * Create a {@code HandlerAuthInterceptor} that can optionally skip authentication. + * Create a {@code HandlerConfigInterceptor} that can optionally skip authentication. * When the authentication is skipped, it added a customized {@code JBossWSHandlerChainInvoker} * which set the correct TCCL to allow the handler to access CDI - * Please see + * Please see https://issues.redhat.com/browse/JBWS-4430 * This interceptor will be added to CXF interceptor chain * @param skipAuth a boolean flag indicating whether to skip authentication. **/ - public HandlerAuthInterceptor(boolean skipAuth) + public HandlerConfigInterceptor(boolean skipAuth) { super(Phase.PRE_PROTOCOL_FRONTEND); addBefore(SOAPHandlerInterceptor.class.getName()); addBefore(LogicalHandlerInInterceptor.class.getName()); - skip = skipAuth; + this.skipAuth = skipAuth; } @Override @@ -97,7 +98,7 @@ public void handleMessage(Message message) throws Fault @SuppressWarnings("rawtypes") final List handlerChain = ep.getJaxwsBinding().getHandlerChain(); if (handlerChain != null && !handlerChain.isEmpty()) { //save - invoker = new JBossWSHandlerChainInvoker(handlerChain, isOutbound(message, ex), skip); + invoker = new JBossWSHandlerChainInvoker(handlerChain, isOutbound(message, ex), skipAuth); ex.put(HandlerChainInvoker.class, invoker); } } diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java index f6919df16..e7b0b5309 100644 --- a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/CDIOutInterceptor.java @@ -23,6 +23,7 @@ import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.jboss.wsf.stack.cxf.interceptor.AbstractTCCLPhaseInterceptor; diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java index 3f950e4b8..a30d7f932 100644 --- a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/jbws4430/JBWS4430TestCase.java @@ -49,7 +49,7 @@ public class JBWS4430TestCase extends JBossWSTest { public static WebArchive createDeployment() { WebArchive archive = ShrinkWrap.create(WebArchive.class, DEP + ".war"); archive.setManifest(new StringAsset("Manifest-Version: 1.0\n" - + "Dependencies: org.jboss.ws.cxf.jbossws-cxf-server\n")) + + "Dependencies: org.apache.cxf,org.jboss.ws.cxf.jbossws-cxf-server\n")) .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, CDIOutInterceptor.class, LoggingHandler.class) .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl"), "wsdl/HelloWorld.wsdl") .add(new FileAsset(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/handlers.xml")), "WEB-INF/classes/handlers.xml") From d300cc5fd278f93cc4d8640db3892a502c84ad36 Mon Sep 17 00:00:00 2001 From: Jim Ma Date: Wed, 13 Nov 2024 17:17:20 +0800 Subject: [PATCH 4/4] [JBEAP-28311][JBWS-4430]:Add doc for the interceptors that access CDI beans in WFLY --- .../chapter-5-Advanced_User_Guide.adoc | 51 +++++++++++++++++ .../doc/chapter-5-Advanced_User_Guide.xml | 55 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/docbook/src/main/doc/adoc/content/chapter-5-Advanced_User_Guide.adoc b/docbook/src/main/doc/adoc/content/chapter-5-Advanced_User_Guide.adoc index f87b7aec0..a2fbe8ce1 100644 --- a/docbook/src/main/doc/adoc/content/chapter-5-Advanced_User_Guide.adoc +++ b/docbook/src/main/doc/adoc/content/chapter-5-Advanced_User_Guide.adoc @@ -1470,6 +1470,57 @@ A new instance of each specified interceptor class will be added to the client or endpoint the configuration is assigned to. The interceptor classes must have a no-argument constructor. +When using CXF interceptors that access CDI beans in the WildFly environment, you need to ensure that +the Thread Context ClassLoader (TCCL) is correctly set to make sure the CDI beans are loaded/read properly. +To do this, CXF interceptors with CDI access should extend `org.jboss.wsf.stack.cxf.interceptor.AbstractTCCLPhaseInterceptor` +and override the method `handleMessageWithTCCL(Message message)` to ensure the proper classloader is set before execution +: +``` +public class CDIOutInterceptor extends AbstractTCCLPhaseInterceptor { +public CDIOutInterceptor() { +super(Phase.PRE_STREAM); +} + @Override + public void handleMessageWithTCCL(Message message) throws Fault { + if (!MessageUtils.isRequestor(message)) { + DelegateBean bean = new DelegateBean(); + } + } +} +``` +``` +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.spi.CDI; +@Dependent +public class DelegateBean { + EmptyBean logic = CDI.current().select(EmptyBean.class).get(); +} +``` +``` +@Dependent +public class EmptyBean { +} +``` +The `AbstractTCCLPhaseInterceptor` can set the deployment classloader to thread context classloader before the +handleMessage() method is called, and it restores the previous classloader afterward. +Since AbstractTCCLPhaseInterceptor was created to set the thread context classloader and is included in +'org.jboss.ws.cxf.jbossws-cxf-server' WildFly module dependency, you must add this necessary dependency to the MANIFEST.MF file of your deployment artifact. +Additionally, don't forget to include the `org.apache.cxf` dependency for importing the cxf interceptor apis. Here is the package example code with Arquillian to +add these two dependencies to the user's deployment artifact. Please use the same dependency adding format when +including these dependencies to the MANIFEST.MF file: +``` + public static WebArchive createDeployment() { + WebArchive archive = ShrinkWrap.create(WebArchive.class, DEP + ".war"); + archive.setManifest(new StringAsset("Manifest-Version: 1.0\n" + + "Dependencies: org.apache.cxf,org.jboss.ws.cxf.jbossws-cxf-server\n")) + .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, CDIOutInterceptor.class, LoggingHandler.class) + .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl"), "wsdl/HelloWorld.wsdl") + .add(new FileAsset(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/handlers.xml")), "WEB-INF/classes/handlers.xml") + .setWebXML(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/web.xml")); + return archive; + } +``` + ==== Apache CXF features diff --git a/docbook/src/main/doc/chapter-5-Advanced_User_Guide.xml b/docbook/src/main/doc/chapter-5-Advanced_User_Guide.xml index 3ccb8dfab..1c7c65964 100644 --- a/docbook/src/main/doc/chapter-5-Advanced_User_Guide.xml +++ b/docbook/src/main/doc/chapter-5-Advanced_User_Guide.xml @@ -1696,6 +1696,61 @@ public static void setThreadDefaultBus(Bus bus) </jaxws-config> A new instance of each specified interceptor class will be added to the client or endpoint the configuration is assigned to. The interceptor classes must have a no-argument constructor. + When using CXF interceptors that access CDI beans in the WildFly environment, you need to ensure that + the Thread Context ClassLoader (TCCL) is correctly set to make sure the CDI beans are loaded/read properly. + To do this, CXF interceptors with CDI access should extend `org.jboss.wsf.stack.cxf.interceptor.AbstractTCCLPhaseInterceptor` + and override the method `handleMessageWithTCCL(Message message)` to ensure the proper classloader is set before execution + : + + + public class CDIOutInterceptor extends AbstractTCCLPhaseInterceptor { + public CDIOutInterceptor() { + super(Phase.PRE_STREAM); + } + @Override + public void handleMessageWithTCCL(Message message) throws Fault { + if (!MessageUtils.isRequestor(message)) { + DelegateBean bean = new DelegateBean(); + } + } + } + ... + + import jakarta.enterprise.context.Dependent; + import jakarta.enterprise.inject.spi.CDI; + @Dependent + public class DelegateBean { + EmptyBean logic = CDI.current().select(EmptyBean.class).get(); + } + + ... + + @Dependent + public class EmptyBean { + } + + + The `AbstractTCCLPhaseInterceptor` can set the deployment classloader to thread context classloader before the + handleMessage() method is called, and it restores the previous classloader afterward. + Since AbstractTCCLPhaseInterceptor was created to set the thread context classloader and is included in + 'org.jboss.ws.cxf.jbossws-cxf-server' WildFly module dependency, you must add this necessary dependency to the MANIFEST.MF file of your deployment artifact. + Additionally, don't forget to include the `org.apache.cxf` dependency for importing the cxf interceptor apis. Here is the package example code with Arquillian to + add these two dependencies to the user's deployment artifact. Please use the same dependency adding format when + including these dependencies to the MANIFEST.MF file: + + + public static WebArchive createDeployment() { + WebArchive archive = ShrinkWrap.create(WebArchive.class, DEP + ".war"); + archive.setManifest(new StringAsset("Manifest-Version: 1.0\n" + + "Dependencies: org.apache.cxf,org.jboss.ws.cxf.jbossws-cxf-server\n")) + .addClasses(HelloBean.class, DelegateBean.class, EmptyBean.class, CDIOutInterceptor.class, LoggingHandler.class) + .addAsWebInfResource(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/wsdl/HelloWorld.wsdl"), "wsdl/HelloWorld.wsdl") + .add(new FileAsset(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/handlers.xml")), "WEB-INF/classes/handlers.xml") + .setWebXML(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/jbws4430/WEB-INF/web.xml")); + return archive; + } + +