0

i want to generate some code like below:

AbstractSomeClass<?> someClassObj = new AbstractSomeClass<MyConcreteType> {
    ...
}

I tried the following:

JDefinedClass anonymousSomeClass = codeModel.anonymousClass(AbstractSomeClass.class);
...
conditionalBody.decl(anonymousSomeClass, "someClassObj", JExpr._new(anonymousSomeClass.narrow(jClass)));

Got exception below, caused by ’anonymousSomeClass.narrow(jClass)‘. if i remove '.narrow(jClass)', everything goes fine.

java.lang.NullPointerException
    at com.sun.codemodel.JDefinedClass.outer(JDefinedClass.java:776)
    at com.sun.codemodel.JFormatter.t(JFormatter.java:280)
    at com.sun.codemodel.JNarrowedClass.generate(JNarrowedClass.java:143)
    at com.sun.codemodel.JFormatter.g(JFormatter.java:350)
    at com.sun.codemodel.JInvocation.generate(JInvocation.java:173)
    at com.sun.codemodel.JFormatter.g(JFormatter.java:350)
    at com.sun.codemodel.JVar.bind(JVar.java:212)
    at com.sun.codemodel.JFormatter.b(JFormatter.java:396)
    at com.sun.codemodel.JVar.declare(JVar.java:216)
        ...

Thanks.

jww
  • 97,681
  • 90
  • 411
  • 885
Cheng
  • 572
  • 8
  • 12

1 Answers1

2

This seems to be a bug in the way CodeModel handles anonymous classes and their ownership. There is a way around this, however, by narrowing the class before you treat it as an anonymous type:

    JDefinedClass tester = codeModel._class("Tester");

    JClass jClass = codeModel.ref(Reference.class);
    JClass unnarrowed =  codeModel.ref(AbstractSomeClass.class).narrow(codeModel.wildcard());
    JClass narrowed = codeModel.ref(AbstractSomeClass.class).narrow(jClass);

    JClass anonymous = codeModel.anonymousClass(narrowed);

    tester.field(JMod.PUBLIC, unnarrowed, "someClassObj", JExpr._new(anonymous));

Gives:

import test.Tester.AbstractSomeClass;

public class Tester {

    public test.Tester.AbstractSomeClass<?> someClassObj = new AbstractSomeClass<Reference>() {


    }
    ;

}
John Ericksen
  • 10,995
  • 4
  • 45
  • 75
  • Thanks a lot. It produces a correct result, but the result source code includes multiple duplicated imports of AbstractSomeClass. As you said, i think this could be a bug of CodeModel. – Cheng Oct 08 '14 at 05:38
  • What do you mean by duplicated imports? I see one import, but one AbstractSomeClass is referenced by full package name. Granted, Codemodel isn't known for generating the prettiest of results. – John Ericksen Oct 08 '14 at 13:59
  • Hi jonhcarl. Thanks. There are multiple 'import test.Tester.AbstractSomeClass' in my generated source files. I think you only use it at one location. I used anonymousClass in several locations with different narrow types. But that doesn't matter, as that doesn't give any syntax errors anyway, just duplicated imports. Thanks for your help. – Cheng Oct 09 '14 at 01:05