This post is specially for those, having a Java Application(Production) working with SFDC web services via Apache-Axis stubs(WSDL2Java), but because of known advantages from WSC, you want to add some new functionality, like Bulk API as mentioned in SFDC blog here.
When we try to use both WSC and Apache Axis WSDL2Java stuff together in the same JVM or Project, we face Java Namespace(Package) clashes. You will certainly get Class-Cast errors like following on 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.<init>(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 on compile time, but when you try running the code in parallel you get ClassCastException, I found one such issue posted on 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 it to 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 WSC WSDL2Java complier to generate all the Java classes with package name appended with “wsc”. So instead of java package “com.sforce.soap.partner.*”, 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 both live happily together in the same JVM 🙂
In the similar fashion, I would suggest generating rest of the stubs for other WSDLs like Enterprise, Apex and Metadata. So that there are no chances on java package namespace conflicts.
Why change Packaging structure for WSC only ?
I suggested to change packaging with WSC only, though you can do vice versa too i.e. change packaging for Apache Axis generated classes. This was done because, I am assuming 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 on that application using SFDC WSC.
So rather breaking existing Axis code, its better to bring new WSC WSDL2Java stuff with corrected non-conflicting namespaces.
In case you are just starting with your java application, I suggest use only WSC. Its really fast and easy to use.
Leave a Reply