It turns out that our programs are based on the Equinox architecture, but later, because of the need to implement the deployment of the war package in the middleware, the implementation of the eclipse-provided bridging approach is used.
There's time behind the bridge. I write an article specifically, please refer to Eclipse official documentation for a moment. The main point here is that the bridge has been successful, but the problem is encountered when using CXF.
Originally in other middleware run a good program, a put into the websphere_v8, on all kinds of error, are related to Axis2, but our project did not use AXIS2, but use CXF.
The error is similar to the following (I have 3 environment, each report of the wrong, but it is obvious that should not appear Axis2):
Java.lang.ClassCastException:org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler incompatible with Org.apache.cxf.frontend.ClientProxyat org.apache.cxf.frontend.ClientProxy.getClient (clientproxy.java:93)
Later, the data found that WebSphere has its own JAXWS engine. You can see that there are three jar packages under $was_home/endorsed_apis:
javax.j2ee.annotation.jarjaxb-api.jarjaxws-api.jar//version:2.2
Then there are org.apache.axis2.jar under the $was_home/plugins.
For example, you realized that MyService inherited the Javax.xml.Service.
So in the service construction method we can see:
Protected Service (Java.net.URL wsdldocumentlocation, QName serviceName) { delegate = Provider.provider (). Createservicedelegate (wsdldocumentlocation, serviceName, this.getclass ()); }
It is this provider.provider () that gets the provider implementation that is always the implementation of axis, not the implementation of our CXF.
I. GENERAL Solutions
The official documents for CXF and IBM were queried for the following solutions:
Reference
Http://www-01.ibm.com/support/knowledgecenter/SS7JFU_7.0.0/com.ibm.websphere.express.doc/info/exp/ae/twbs_ thirdparty.html?lang=en
And
http://cxf.apache.org/docs/application-server-specific-configuration-guide.html# Applicationserverspecificconfigurationguide-forwebsphere6.1.0.29+,v7andv8
1. Turn off the JAXWS engine that comes with WebSphere. There are two levels of settings:
Server level:
In the console interface , go to Application Server > Server1 > Process definition > Java virtual Machine , and then include in common JVM parameters
-dcom.ibm.websphere.webservices.disableibmjaxwsengine=true
Or go to custom properties, add a custom attribute Name=com.ibm.websphere.webservices.disableibmjaxwsengine, Value=true.
For an app:
In the meta-inf/manifest of your war pack. MF Add disableibmjaxwsengine:true, like this
2. Set your app's ClassLoader policy to Parent_last
Enterprise Applications > $YOUR _app > class loading and update detection
Set the class loader order to Parent_last
Enterprise Applications > $YOUR _app > Module management > $YOUR _module, set the class loader order to Parent_last
Finally there is a place for the class loading strategy (you can verify if this needs to be set, some articles do not say this place):
Application Server > Server1, set the class Mount mode to Parent_last
These are the solutions that IBM and CXF officially offer.
And then found some other options on the Web:
1. Remove Org.apache.axis2.jarH or remove ' meta-inf/services/javax.xml.ws.spi.provider ' from Org.apache.axis2.jar
This is more violent and will have an impact on the whole of was.
2. Switch to
Instead of the original
MyWebService SS = New
2nd Article I tried, reported MyWebService is not a interface mistake. There is no specific reason why.
All the ways that can be found on the internet have been tried without fruit and have to be analyzed by ourselves.
Second, the way of bridging the special place
JAX-WS uses the service Provider Interface (SPI) mechanism, defines the upper-level API, run by the provider class load different implementations.
First look at the JAX-ws loading sequence:
JAX-ws load Order Javax.xml.ws.spi.Provider Provider ()
- If A resource with the name of META - Inf/services/javax.xml.ws.spi.provider
= Com.sun.xml.ws.spi.ProviderImpl
- $java. Home/lib/jaxws.properties,it contains an entry whose key is Javax.xml.ws.spi.Provider
- If A System property with the name Javax.xml.ws.spi.Provider
- Default is loaded (Com.sun.xml.internal.ws.spi.ProviderImpl)
Javax.xml.bind.Contextfinder.find
- jaxb.properties (key= javax.xml.bind.jaxbcontext
- system Property With name Javax.xml.bind.JAXBContext
- meta - inf/services/ Javax.xml.bind.JAXBContext
- Default is loaded (com.sun.xml.internal.bind.v2.ContextFactory)
|_meta-inf |_services |_ javax.xml.bind.JAXBContext (com.sun.xml.bind.v2.ContextFactory)
Jaxws-api must have been using WebSphere, and after we've closed the Ibmjaxwsengine and modified the ClassLoader strategy in accordance with the official documentation, he's always loaded into the axis2 that comes with WebSphere, So guess Provider.provider () when looking for the implementation of provider, did not find our application in the CXF package, which is related to the way OSGi bridging, the use of this way students should understand what directory structure. So, the solution is to put a cxf.jar in the war/web-inf/lib. And then no more axis2 came to haunt us.
Here is a problem, the Lib package has a Cxf,eclipse plugin directory also has a CXF. Will there be a class conflict when using it?
If you remove the CXF from Eclipse's plugin directory directly, you must start with a variety of bundles that are dependent on the error. Then outside a cxf, inside a cxf in the end will not have conflict?
The answer is no.
Because I deleted the contents of the CXF package in Lib, only a few files were left in the meta-inf/services/. It can actually run normally. So you can see that the classes loaded into the runtime should also be classes in CXF in Eclipse's plugins. Guessing that the class loaded in CXF is loaded from the classloader of the bundle in Equinox, so it is loaded into the class in plugins in Eclipse. If it is loaded with the module or the ClassLoader above, then only cxf empty package in lib, without the specific class, will certainly not load this class. So, since it can be loaded in this case, it means that it starts loading from the classloader of the bundle.
But for the sake of insurance, the final plan for this step is:
Copy the Meta-inf/services directory from the CXF into a jar package and place it in the war/web-inf/lib directory.