JCommander annotation error

2012-01-27
2013-04-15
  • Knut Arild Erstad

    I was trying to use autojar to build a program that uses JCommander (http://jcommander.org/) for command line parsing. JCommander is annotation-based, and it seems that autojar was not able to detect all the dependent classes, so I got an error like this when running the program:

    Exception in thread "main" java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class com.beust.jcommander.Parameter.splitter()
        at java.lang.reflect.Method.getDefaultValue(Method.java:726)
        at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:99)
        at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:66)
        at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:202)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:69)
        at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:52)
        at java.lang.reflect.Field.declaredAnnotations(Field.java:1014)
        at java.lang.reflect.Field.getAnnotation(Field.java:1000)
        at com.beust.jcommander.JCommander.addDescription(JCommander.java:501)
        at com.beust.jcommander.JCommander.createDescriptions(JCommander.java:490)
        at com.beust.jcommander.JCommander.parse(JCommander.java:272)
        at com.beust.jcommander.JCommander.parse(JCommander.java:257)
        at com.beust.jcommander.JCommander.<init>(JCommander.java:202)
            ...
    

    I'm not sure if this is due to a bug or dynamic loading that autojar had no way of detecting, but I was able to work around it by checking which jcommander classes were missing and then adding two additional wildcard parameters when invoking autojar: "com.beust.jcommander.converters.*.class" and "com.beust.jcommander.validators.*.class".

    According to google I'm the only one who's had this particular problem, so just thought I'd document it. :-)

     
  • Bernd Eggink

    Bernd Eggink - 2012-01-30

    I don't know JCommander, but I'm pretty sure the problem was caused by dynamic loading. The verbose output (option -v) should show you if and where dynamic loading happens.
    After finding out which classes had been missing, you could supply them directly. on the command line, instead of using wildcards (which might pull unneeded classes into the jar file).

     
  • Knut Arild Erstad

    I investigated a bit more, and I'm still confused about why autojar doesn't load the referenced classes automatically.

    The source for the @Parameter annotation class can be seen here: https://github.com/cbeust/jcommander/blob/master/src/main/java/com/beust/jcommander/Parameter.java

    When using the verbose output, I can see that the Parameter class is loaded correctly, but the classes defined as defaults (NoValidator.class, NoConverter.class, CommaParameterSplitter.class) are not.

     
  • Bernd Eggink

    Bernd Eggink - 2012-02-14

    Ah, I see. The simple reason is that Autojar does not look into annotations. The underlying BCEL library does not support them, and unfortunately it seems that BCEL isn't actively developed any more. I'm also not sure if one could tell from the bytecode whether the specified default class is used, but I'll look into it.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks