At my job, we use the wsdl2java maven plugin to generate the appropriate classes from the webservices’ wsdl document. When we received notice that we were to incorporate a new webservice into the system, we thought “No big deal, we’ll just use the plugin and be off!”

Unfortunately, we ran into the dreaded “com.sun.tools.xjc.BadCommandLineException: grammar is not specified” error. After inspecting the code I couldn’t find any issue. The wsdl was right there, and it didn’t reference any outside xsds or anything? What’s the problem?

I did a google search. Found some interesting threads from nabble that had nothing to do with my problem. Eventually, I found that (with a misleading name) the wsdl2java plugin doesn’t automatically pickup xsds. If you are pointed to a directory that has XSDs (usually referenced by the actual wsdl files) it will autogen from those. But if your xsd are in a subdirectory (or not needed for such a simple webservice) then wsdl2java blows up with the grammar error.

I ended up the following in my pom:

<plugin>
    <groupId>com.sun.tools.xjc.maven2</groupId>
    <artifactId>maven-jaxb-plugin</artifactId>
    <executions>
        <execution>
            <!-- This one has the xsd's in the same directory, so it was already working -->
            <id>simple-xsd-wsdl2java</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <!-- directory of the wsdls and the xsds -->
                <schemaDirectory>src/main/wsdl/simple</schemaDirectory>
                <generateDirectory>src/autogen/simple</generateDirectory>
                <readOnly>true</readOnly>
            </configuration>
        </execution>
        <execution>
            <!-- This one was only the WSDL files, with no external XSDs -->
            <id>wsdlOnly-wsdl2java</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <!-- directory of the wsdl files -->
                <schemaDirectory>src/main/wsdl/wsdlOnly</schemaDirectory>
                <generateDirectory>src/main/autogen/wsdlOnly</generateDirectory>
                <readOnly>true</readOnly>
                <includeSchemas>
                    <!-- Each schema has to be spelled out as an includedSchema, or it will be ignored -->
                    <includeSchema>AccountService.wsdl</includeSchema>
                    <includeSchema>SystemService.wsdl</includeSchema>
                    <includeSchema>GiftService.wsdl</includeSchema>
                </includeSchemas>
                <!-- Indicates to the grammar parser that the schema files are in the wsdl format -->
                <args>-wsdl</args>
            </configuration>
        </execution>
    </executions>
</plugin>

Notice that in the wsdlOnly configuration I have specifed each schema file separately. I think there is a way to specify a directory/wildcard search, but I didn’t spend the time figuring it out. The other immensely important part is adding the args section. This tells the parser that the files are in wsdl format, not in XSD.

I hope that this helps anyone out there looking for a way to auto generate class files to use with SpringWS from stand-alone wsdl files.