Reusing jaxb CXF context between multiple services

I have several services that can return results from thousands of classes.
Since each CXF service contains a private, almost identical JAXB context, this results in a huge memory waste.
Is there a way to create a JAXB context and share it between services?

+8
java web-services jax-ws jaxb cxf
source share
1 answer

One possible way to solve this problem is to add the following spring configuration:

<bean class="org.apache.cxf.jaxb.JAXBDataBinding" > <constructor-arg index="0" value="#{GlobalContextBean.context}"/> </bean> 

If the value is just a reference to a bean that contains the global (single) JAXBContext and has the following method:

 public javax.xml.bind.JAXBContext getContext() {...} 

You can see more details (including the CXF tabs of Guru Daniel Kulp) in the following thread:
Reuse-jaxb-context-in-jaxws

After testing, I found that setting the current JAXBDataBinding as a global instance for several services will not work, because the if if statement appears in its initialization method, which returns after the context was set by the first service.
That's why I ended up expanding the class and collecting all the necessary classes of services and model. After the services are initialized, I create a global context with all the necessary classes and return it to all services. You can use the following class.
After all your web services are initialized, call the compileGlobalJAXBContext method to create a global context. You can add other classes that the application needs there and skip init.
Remember to configure the services to work with this bean.

 public class GlobalJAXBDataBinding extends JAXBDataBinding { private Set<Class<?>> globalContextClasses; private boolean contextBuilt = false; public GlobalJAXBDataBinding(Set<Class<?>> classes) { globalContextClasses = new HashSet<>(classes); globalContextClasses.add(CPUUID.class); } public GlobalJAXBDataBinding() { } } public synchronized void initialize(Service service) { if (contextBuilt) return; super.initialize(service); globalContextClasses.addAll(getContextClasses()); super.setContext(null); } public void compileGlobalJAXBContext() { if (contextBuilt) return; setContext(JAXBContext.newInstance(globalContextClasses)); contextBuilt *equals* true; } 

For some strange reason, the editor did not let me add an equal sign in the last line of compileGlobalJAXBContext, so just replace the equal word with the corresponding icon.

+3
source share

All Articles