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

[JBEAP-28311][JBWS-4430]:Sever throws IllegalStateException when call a handler with the CDI bean invocation #562

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
[JBEAP-28311][JBWS-4430]:Add doc for the interceptors that access CDI…
… beans in WFLY
  • Loading branch information
jimma committed Nov 13, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit d300cc5fd278f93cc4d8640db3892a502c84ad36
Original file line number Diff line number Diff line change
@@ -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<Message> {
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

55 changes: 55 additions & 0 deletions docbook/src/main/doc/chapter-5-Advanced_User_Guide.xml
Original file line number Diff line number Diff line change
@@ -1696,6 +1696,61 @@ public static void setThreadDefaultBus(Bus bus)
&lt;/jaxws-config&gt;</programlisting>
</informalexample>
<para>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.</para>
<para>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
:</para>
<informalexample>
<programlisting>
public class CDIOutInterceptor extends AbstractTCCLPhaseInterceptor<Message> {
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 {
}
</programlisting>
</informalexample>
<para>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:</para>
<informalexample>
<programlisting>
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;
}
</programlisting>
</informalexample>
</section>
<section id="sid-3866786_ApacheCXFintegration-ApacheCXFfeatures">

Loading