WSC Apache Axis ClassCastException Issue Fixed!
This post is especially for those with a Java application (production) working with SFDC web services via Apache Axis stubs (WSDL2Java). However, due to the known advantages of WSC, you want to add some new functionality, such as the Bulk API, as mentioned in the SFDC blog.
When we attempt to use both WSC and Apache Axis WSDL2Java tools together in the same JVM or project, we encounter Java namespace (package) clashes. You will certainly get Class-Cast errors like the following on the first run.
Exception in thread "main" java.lang.ClassCastException:
com.sforce.soap.partner.LoginResult cannot be cast to
com.sforce.ws.bind.XMLizable
at com.sforce.ws.bind.TypeMapper.readSingle(TypeMapper.java:618)
at com.sforce.ws.bind.TypeMapper.readObject(TypeMapper.java:495)
at
com.sforce.soap.partner.LoginResponse_element.loadFields(LoginResponse_element.java:68)
at
com.sforce.soap.partner.LoginResponse_element.load(LoginResponse_element.java:59)
at com.sforce.ws.bind.TypeMapper.readSingle(TypeMapper.java:619)
at com.sforce.ws.bind.TypeMapper.readObject(TypeMapper.java:495)
at com.sforce.ws.transport.SoapConnection.bind(SoapConnection.java:154)
at com.sforce.ws.transport.SoapConnection.receive(SoapConnection.java:128)
at com.sforce.ws.transport.SoapConnection.send(SoapConnection.java:103)
at com.sforce.soap.partner.PartnerConnection.login(PartnerConnection.java:791)
at
com.sforce.soap.partner.PartnerConnection.(PartnerConnection.java:315)
at BulkExample.getRestConnection(BulkExample.java:171)
at BulkExample.runSample(BulkExample.java:43)
at BulkExample.main(BulkExample.java:34)
What creates this Namespace/Package hassle?
When one has compiled the SFDC WSDLs using Apache Axis, Java classes get package names like “com.sforce.soap.partner.*” for Partner WSDL. Similarly, for WSC WSDL compilation, we get the same package names for the WSDLs, i.e., “com.sforce.soap.partner.*”. This happens because one has generated/compiled WSDLs using WSC with default options, i.e.
java -classpath wsc.jar com.sforce.ws.tools.wsdlc wsdl jar.file
Nothing fails at compile time, but when you try running the code in parallel, you get a ClassCastException. I found one such issue posted on the sfdc-wsc Google Code project.
Solution to this Package/Namespace conflict!
The solution to this issue is to specify your own prefix to Java packages when generating/compiling the WSDLs using WSC. So instead of using the default command above, just replace it with something similar below.
java -Dpackage-prefix=wsc -classpath wsc.jar com.sforce.ws.tools.wsdlc wsdl jar.file
Please note that I just added “-Dpackage-prefix=wsc” after the Java command. Specifying this prefix will hint the WSC WSDL2Java compiler to generate all the Java classes with the package name appended with “wsc”. So instead of the Java package “com.sforce.soap.partner.*”, the new package name would be “com.sforce.soap.partner.wsc.*”. This will remove all namespace conflicts with Axis code in your project; now both Axis > LoginResult and WSC > LoginResult can live happily together in the same JVM.
Similarly, I would suggest generating the rest of the stubs for other WSDLs like Enterprise, Apex, and Metadata. So that there are no chances of Java package namespace conflicts.
Why change the packaging structure for WSC only?
I suggested changing the packaging to WSC only, though you can do vice versa too, i.e., change the packaging for Apache Axis generated classes. This was done because I am assuming the following scenario:
You are maintaining and enhancing a Java app using SFDC web services in production.
So you have already done WSDL2Java for your Apache Axis code, and your code has several dependencies on the generated Axis code.
You just want to add some new features, like Bulk API, to that application using SFDC WSC.
So, rather than breaking existing Axis code, it's better to bring new WSC WSDL2Java stuff with corrected non-conflicting namespaces.
In case you are just starting with your Java application, I suggest you only use WSC. It's really fast and easy to use.