X

Geertjan's Blog

  • February 14, 2015

[ERROR] Two declarations cause a collision in the ObjectFactory class.

Geertjan Wielenga
Product Manager

The error message in the title of this blog entry seems to be causing a lot of people in the world a lot of problems. In this blog entry, I hope to be able to reproduce the problem and solve it, once and for all, for everyone everywhere, using a great tool to support you in doing so, i.e., NetBeans IDE. 

Let's start with this WSDL, which is useful in this context since it lets us reproduce the problem and then solve it:

http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?wsdl

  1. Create a new Java SE application in NetBeans IDE, named 'MoebiusIntegration', or any other name you like:

    Now you should see this:

  2. Go to the New File dialog and choose Web Services | Web Service Client. Click Next. In the WSDL URL field, paste the URL above and nothing else, i.e., do not fill in any field other than the WSDL URL field.  



  3. Click Finish. After a few moments, files are generated into your project structure and the first thing you notice is this big dialog:



    When you look in the Projects window, you should see this set of folders and files:



    In the Output window (Ctrl-4), you should see the following:



  4. Right-click the project in the Projects window and choose Build. The Output window now shows the following:



  5. Take note of the fact that there are different kinds of errors here, not all visible in the screenshot above, and the first below being the title of this blog entry and one that is a problem for many people, apparently, when I look on Google:

    • [ERROR] Two declarations cause a collision in the ObjectFactory class.

    • [ERROR] A class/interface with the same name "moebiusintegration.Reclamation" is already in use. Use a class customization to resolve this conflict.

    • [ERROR] This error is caused because on Windows you cannot have both "PersistentObjectOfstring.java" and "PersistentObjectOfString.java" in the same directory.

    • [ERROR] This error is caused because on Windows you cannot have both "PersistentObjectOfint.java" and "PersistentObjectOfInt.java" in the same directory.

Hurray! We've reproduced several JAXB binding problems. Let's now focus on solving them.

The biggest problem in solving these kinds of problems is that you're now going to go to Google and etc. There's hundreds (thousands, maybe) of developers who have encountered these kinds of problems over the years, there are many different solutions, each depending on the specific conflicts in the specific WSDL file, hence each solution being relevant for a subset of problems only. For example, in some scenarios, the -XautoNameResolution flag is helpful, while in others it isn't. It simply depends on the kind of JAXB binding problem you're dealing with.

The best thing to do is to start here, in the official documentation:

https://jaxb.java.net/guide/Dealing_with_errors.html

When you put the error message into a search in the official documentation above, you'll see this:

When schemas contain similar looking element/type names, they can result in "Two declarations

cause a collision in the ObjectFactory class" errors. To be more precise, for each of all

types and many elements (exactly what elements get a factory and what doesn't is bit

tricky to explain), XJC produces one method on the ObjectFactory class in the

same package. The ObjectFactory class is created for each package that XJC generates

some files into. The name of the method is derived from XML element/type names, and the error

is reported if two elements/types try to generate the same method name."

The first solution given for the above problem, right below the paragraph above in the documentation, is this:

"If the collision is coming from two different

schemas with different target namespaces, then you can easily avoid the collision by compiling

them into different Java packages. To do this, use <schemabindings> customization

on two schemas and specify the package name."

An awesome contributor to this discussion on the NetBeans users mailing list, where this has been discussed over the past weeks, is Matthias Bläsing. He provided a solution that includes the binding customization referred to above. I used that approach to make this YouTube screencast today:

However, though the above fixes the ObjectFactory problem, the end of the YouTube screencast ends with a bit of a hack where I search through various files and rewrite bits of names to other names, which could be handled more gracefully. Matthias Bläsing to the rescue again who tells me that my approach with the rewriting is probably going to be wrong in the end: "Depending on what you changed in the XSD, the result might compile, but not work, as the elements are not recognized on the receiving side. The approach via customization is that I don't change the data definition, but only its mapping to the Java side."

So, hurray, Matthias has provided a new binding file which solves all the problems simultaneously:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd0">
<jxb:schemaBindings>
<jxb:package name="moebius.data" />
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd1">
<jxb:schemaBindings>
<jxb:package name="moebius.data.serialization"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd2">
<jxb:schemaBindings>
<jxb:package name="moebius.data.ssi.integracaomoebius.core.model"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd3">
<jxb:schemaBindings>
<jxb:package name="moebius.data.ssi.moebiuscore.core.model"/>
<jxb:nameXmlTransform>
<jxb:typeName suffix="Type" />
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd4">
<jxb:schemaBindings>
<jxb:package name="moebius.data.serialization.arrays"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
schemaLocation="http://homologamoebius.sondaprocwork.com.br/V5/IntegracaoMoebius/MoebiusIntegration.svc?xsd=xsd5">
<jxb:schemaBindings>
<jxb:package name="moebius.data.ssi.core.model"/>
</jxb:schemaBindings>
<jxb:bindings node="//xs:complexType[@name='PersistentObjectOfInt']">
<jxb:class name="PersistentObjectOfInt2" />
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='PersistentObjectOfString']">
<jxb:class name="PersistentObjectOfString2" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>

Alternatively, download it here:

//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/d8094322b634a9d5f9e19e4fe143ab4d/globalcustomization1.xml

Download the above file and put it anywhere in your project, e.g., in the META-INF folder, where the 'jax-ws-catalog.xml' file is found. Name the file 'binding.xml' or whatever you like:

Select the file and press Alt-Shift-L, which copies the file's full path to the clipboard. In NetBeans IDE, right-click on the 'MoebiusIntegration' node within the 'Web Service References' node and choose 'Edit Web Service Attributes':


Next, when the dialog opens, click the 'WSDL Customization' tab, scroll all the way down to 'External Binding Files', click Add, read the helpful information, click Yes, press Ctrl-V to paste the clipboard content into the Open dialog, and click Open. You should now see this:


Click OK. Then Click OK again. After a few seconds of processing, you should now see this and be able to expand the node as shown below:


But that's not all! Guess what? Not only do you now have all the client code... and not only are all the JAXB binding problems solved... you can drag all those red-bulleted nodes you see above, which represent classes, into your own Java code. For example, this is what my main method looks like initially:

Now I put my mouse on 'AddHardwareServiceOrder', which is the first node underneath 'CustomBinding_IMoebusIntegration':

Then I drag the mouse anywhere within my own class and when I release the mouse I see this:

Also notice that everything throughout the project, generated code and everything else, compiled. In other words, I now have a solid starting point for interacting with a service made available by the WSDL with which I started.

In upcoming blog entries, I'll look more closely at the binding.xml file and explain, via explanations received from Matthias Bläsing, what the entries in it mean, how it is hooked into the build process (and also how it can be done via Maven instead of Ant) and help understand the binding file's content. For the moment, you can simply take it and then adapt it to your own needs. Hope the above helps all those people out there struggling with these specific binding problems with JAXB.

Join the discussion

Comments ( 12 )
  • alex Saturday, February 14, 2015

    Or, take the easy way out and just use REST. If you have the option to do so.

    Fwiw, I have never liked generating code from WSDL, I have always preferred to generate the WSDL from annotated classes instead. Of course, this is not an option when you have to talk to system that only gives you a WSDL.


  • Geertjan Sunday, February 15, 2015

    Given that this blog entry is very clearly about fixing JAXB binding problems in WSDL-related web services, isn't it hilariously idiotic to point out that it's better to use REST than WSDL-based services? Isn't it a lot like advising someone with a puncture in their bicycle to use a car instead? I.e., how does that advice help anyone to fix the problem with their bicycle?


  • alex Sunday, February 15, 2015

    Well, if they used the car, they wouldn't care about the bike's tire anymore.

    But yeah, the geek in me had nothing better to do on Valentine's day, I admit it.

    Still, it's puzzling to see that after all these years, tools still can't import a WSDL without manual adjustments (nor are they capable of showing a helpful warning/error).


  • Geertjan Sunday, February 15, 2015

    Not a question of "can't", I think, don't you? Simply a question of how much time do we want to spend helping people with tools for working with WSDL instead of REST. Puzzling that you don't get that.


  • Matthias Sunday, February 15, 2015

    @alex: You like REST - fine with me.

    But to be clear: XML + XSD + WSDL + multiple Implementation + multiple Platforms is a hard problem. REST is nowhere near as complex as SOAP and maybe should not be. But please don't evangelize.

    Not everybody has small nicly isolated systems that work like that. Some of us have to work with different technologies and the pace is too fast for tools to always keep up (or it would be to expansive).

    If you got the whole truth - good for you. But the strangers around you will still produce:

    - Weakly definied HTTP-Interfaces they call REST

    - interfaces for DCOM

    - non remote interfaces like COM

    - or overly complex Webservices

    For me the take away from this is: Learn to deal with complexity. I can tell my boss: No we can't connect to XY. But I can better use the tools at my fingertips to get my job done, instead of bitching about the technologie (in fact I can do both :-))


  • alex Sunday, February 15, 2015

    Ok, maybe wrong choice of words (happens to me a lot).

    I thought I was just pointing oout the obvious; when dealing with a WSDL mess, check whether switching to REST is an option. If you can't, then have this blog post bookmarked.

    My personal belief is that taking the time to switch (it's involving, I know, it's not a simple translation) can ease one's life in the future.

    @Matthias: I'd say "learn to avoid having to deal with complexity, but be prepared to do so, because sometimes you will have to" instead.

    Sorry if I sounded like an a$$ before.


  • guest Sunday, March 15, 2015

    Very nice and very clear.

    So.... how does one go about creating the schema binding?? I can't use yours for my wsdl? Tutorial anywhere?


  • guest Tuesday, September 15, 2015

    Thanks!


  • Hoel Sunday, September 20, 2015

    Hi,

    Thank you for providing a solution for this wsimport issue, i face the exact same class collision error.I rewrote the bindings file to fit my WSDL (https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl) and used wsimport options to add it, but no luck but it just doesn't work, i keep getting the exact same collision error. Do you or anyone else have an idea of what i am doing wrong?

    Thanks.

    <?xml version="1.0" encoding="UTF-8"?>

    <jxb:bindings version="1.0"

    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd0">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data0" />

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd1">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data1"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd2">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data2"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd3">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data3"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd4">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data4"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd5">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data5"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    <jxb:bindings schemaLocation="https://wsvc.cdiscount.com/MarketplaceAPIService.svc?xsd=xsd6">

    <jxb:schemaBindings>

    <jxb:package name="cdiscountclient.data6"/>

    </jxb:schemaBindings>

    </jxb:bindings>

    </jxb:bindings>


  • guest Wednesday, December 2, 2015

    @Hoel

    I have same problem as you. Edited binding.xml for my WSDL, but still getting "Two declarations cause a collision in the ObjectFactory class" error.

    Any progress?


  • guest Friday, January 29, 2016

    Hi,

    Yes the solution worked successfully for me.

    Thank you Geertjan.

    Regards,

    Abdus.


  • iamsubho76 Wednesday, August 24, 2016

    Thank you very much, you have save my time!!!!!


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services