Search code examples
javajsonrestjersey

Jersey: what does "couldn't find grammar element" mean?


After upgrading Jersey from version 1.15 to 1.17 it started to log the following messages:

Apr 2, 2013 5:13:06 PM com.sun.jersey.server.wadl.generators.AbstractWadlGeneratorGrammarGenerator attachTypes
INFO: Couldn't find grammar element for class java.lang.String

An example of a service that produces such a message:

@GET
@Path("/bla/{a}")
@Produces("application/json")
public String doStuff(@PathParam("a") String a) {
    return a;
}

My first impression would be to consider this an error message, purely based on the way the message is phrased ("couldn't find"). However, it's logged at a level of INFO, and it doesn't seem to have any effects in practice since all services continue to work.

So my question is whether these log messages indicate a (potential) problem with the way we are configuring or using Jersey. Since it didn't happen with the previous version I already checked the release notes, but didn't find anything related.


Solution

  • I had the same "info" message as well. I didn't manage to fix it (yet) for basic java types (Boolean, String...) but for my own custom classes if I add the @XmlRootElement annotation and a default no-param constructor the message dissapears.

    Digging into jersey source code I noticed the class "WadlGeneratorJAXBGrammarGenerator" the following code :

    Object parameterClassInstance = null;
    try {
        Constructor<?> defaultConstructor = type.getDeclaredConstructor();
        defaultConstructor.setAccessible(true);
        parameterClassInstance = defaultConstructor.newInstance();
    } catch (InstantiationException ex) {
        LOGGER.log(Level.FINE, null, ex);
    } catch (IllegalAccessException ex) {
        LOGGER.log(Level.FINE, null, ex);
    } catch (IllegalArgumentException ex) {
        LOGGER.log(Level.FINE, null, ex);
    } catch (InvocationTargetException ex) {
        LOGGER.log(Level.FINE, null, ex);
    } catch (SecurityException ex) {
        LOGGER.log(Level.FINE, null, ex);
    } catch (NoSuchMethodException ex) {
        //getting here for Boolean/String and some other primitive data type
        LOGGER.log(Level.FINE, null, ex);
    }
    
    if (parameterClassInstance==null) {
        return null;
    }
    

    So basically there is no default constructor for String, Boolean and few others then it throws a NoSuchMethodException therefore it return nulls and log the info message.

    So still no idea why it happens but in my case the solution was to disable the wadl generation since I was not using it. Just add the following param to your web.xml

      <init-param>
             <param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
             <param-value>true</param-value>
         </init-param>