0

I am writing a webservice client using a very large webservice schema (40,000 lines with 5,000 elements). This schema was provided externally, i.e. I can't change it.

I use JAXB to generate Java classes for the client. By default, all classes are generated into a single Java file, which ends up having 500,000 lines.

This is a huge problem for my IDE (Eclipse), which hangs and crashes even with 4GB of memory.

I could overcome this problem by generating separate Java files, but many of the entities in the schema have identical names. There are more than 500 name clashes, when all Java classes are generated in the same package.

If I were to avoid these clashes using jaxb bindings, I would have to manually write over 500 binding definitions.

It would be very convenient if I could automatically map the XML hierarchy into java packages, but I have nevery seen an example for this.

I can't disclose the schema itself, but here is a small example to illustrate the problem:

<xs:element name="top">
    <xs:element name="customer">
        <xs:element name="name">
            ...
        </xs:element>
        <xs:element name="address">
            ...
        </xs:element>
        <xs:element name="employee">
            <xs:element name="name">
                ...
            </xs:element>
            <xs:element name="address">
                ...
            </xs:element>
        </xs:element>
    </xs:element>
    <xs:element name="provider">
        <xs:element name="product">
            <xs:element name="name">
                ...
            </xs:element>
        </xs:element>
        <xs:element name="name">
            ...
        </xs:element>
        <xs:element name="address">
            ...
        </xs:element>
    </xs:element>
</xs:element>

The desired result would be Java classes like:

com.mycompany.generated.Top
com.mycompany.generated.top.Customer
com.mycompany.generated.top.customer.Name
com.mycompany.generated.top.customer.Address
com.mycompany.generated.top.customer.Employee
com.mycompany.generated.top.customer.employee.Name
com.mycompany.generated.top.customer.employee.Address
...
com.mycompany.generated.top.Provider
...

How can I achieve this?

Edit: The original xsd (unlike the snippet provided here) is perfectly valid, but it defines every element individually. E.g. even though there are many types called address with identical definitions, each one is defined between its element tags instead of re-using a type. This is one reason why it's so big, and why there are so many identical classes. To make it even more complicated, I also found type definitions with identical names and different details.

I don't need to fill all elements in the WS, so my main objective is to enable successful code generation without much fuss.

I am reluctant to change the schema locally to re-use type definitions, because I expect future changes from above which would require applying the same modifications again and again.

2
  • The only way I can think of right now is to write a scrip to manually tease apart the XML so that it will generate smaller classes. Anything else you can tell us about the schema would be helpful, "it's really big" isn't a lot to go on. Commented Nov 12, 2015 at 15:09
  • The solution is not to use JAXB. There are some schemas for which it simply isn't appropriate. Apart from anything else, a schema that is very large also tends to change more often, so you not only have the problem of compiling a vast amount of Java code, but you also have a serious headache with change management. JAXB is great for small simple stable schemas, but it doesn't scale. Commented Nov 12, 2015 at 18:50

1 Answer 1

1

You can generate separate Java classes with:

<jaxb:globalBindings localScoping="toplevel"/>

But then this still leaves you with 500 class name customizations. You can either go brute-force or write an XJC plugin to handle that. I think brute-force would be faster than writing a plugin.

However I wouldn't disrtibute classes among different packages. JAXB has a number of package-level feature which may fail/go wrong if you distibute classes of the same namespace among different packages. So I'd just do <jaxb:class name="CustomerName"/> customizations.

I'd also consider writing an XSLT transformation which would generate the bindings file out of the schema automatically. Should not be difficult at all.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.