Java – Troubles with WADL / generated XSD using Jersey with a contract-first approach

contract-firstjavajerseywadlxsd

I have been working on a REST web service using Jersey for a few days now, and managed to have all CRUD operations working, with several exchange formats: XML, JSON, Google Protobuf.

However I am facing some issues related to automatically generated WADL and XSD.


Context

To define the objects exchanged in these three formats, I have followed a "contract-first" approach:

  • from a XSD I wrote, I generated my model classes using JAXB;
  • from an equivalent proto file I wrote, I generated the Google Protobuf classes (and internally have a way to convert these to the JAXB-generated objects, in order to have one unique model).

However, as I would like my users to be able to generate their classes too, I would like to share these schema files (.xsd and .proto) and have them well integrated with the automatically generated WADL.

For that purpose, thanks to this wiki page:

  • I have exposed the two files under
    • /schema/schema.xsd
    • /schema/schema.proto
  • I have added an application-grammar file:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <grammars xmlns="http://wadl.dev.java.net/2009/02" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:xi="http://www.w3.org/1999/XML/xinclude">
        <include href="../schema/schema.xsd" />
    </grammars>
    
  • I have added a customized WADL generator:

     public class RichWadlGeneratorConfig extends WadlGeneratorConfig {
        @Override
        public List<WadlGeneratorDescription> configure() {
            return generator(WadlGeneratorApplicationDoc.class)
                .prop("applicationDocsStream", "application-doc.xml")
                .generator(WadlGeneratorGrammarsSupport.class)
                .prop("grammarsStream", "application-grammars.xml")
                .descriptions();
        }
     }
    

This way the below appears in the WADL, when I hit /rest/application.wadl:

<grammars>
     <include href="../schema/schema.xsd"/>
     <include href="application.wadl/xsd0.xsd">
          <doc title="Generated" xml:lang="en"/>
     </include>
</grammars>

Problem

/rest/application.wadl/xsd0.xsd is automatically generated from my classes, but is quite different from what I initially had in schema.xsd.
In addition to that, calling a tool like wadl2java on this WADL fails miserably, presumably because

  • /schema/schema.xsd, and
  • /rest/application.wadl/xsd0.xsd

are now conflicting (two definitions for the same objects).


Questions

  1. Is there a way to disable the generation and diffusion of this automatically generated XSD?
    (As I don't need it since I'm following this "contract-first" approach)

  2. If not, is there a way to "override" its content with my manually written XSD when /rest/application.wadl/xsd0.xsd is hit?
    (I have googled around and found about WadlResource, to generate customized WADL, but found nothing about the XSD generation itself)


Thanks in advance for your help!

M.


Edit

1) I raised the issue to the Jersey team and got a reply:
http://java.net/projects/jersey/lists/users/archive/2012-06/message/8

2) I raised a ticket (JERSEY-1230), according to Pavel's instructions.
I am currently following up to either submit a fix myself or get a fix from the Jersey team.

Best Answer

1.14-SNAPSHOT should allow you to do this:

public class SampleWadlGeneratorConfig extends WadlGeneratorConfig {

    @Override
    public List<WadlGeneratorDescription> configure() {
        return generator( WadlGeneratorApplicationDoc.class )
                .prop( "applicationDocsStream", "application-doc.xml" )
                .generator( WadlGeneratorGrammarsSupport.class )
                .prop( "grammarsStream", "application-grammars.xml" )
                .prop("overrideGrammars", true)                               // !!!
                .generator( WadlGeneratorResourceDocSupport.class )
                .prop( "resourceDocStream", "resourcedoc.xml" )
                .descriptions();
    }

}

when overrideGrammars is set to true, Jersey generated grammars won't be included in returned WADL.

Related Topic