jOOQ / jOOR

jOOR - Fluent Reflection in Java jOOR is a very simple fluent API that gives access to your Java Class structures in a more intuitive way. The JDK's reflection APIs are hard and verbose to use. Other languages have much simpler constructs to access type meta information at runtime. Let us make Java reflection better.
http://www.jooq.org/products
Apache License 2.0
2.8k stars 377 forks source link

ClassFormatError when processors passed to Reflect.compile() produce new source files #81

Open lukaseder opened 5 years ago

lukaseder commented 5 years ago

When a processor passed to Reflect.compile() attempts to produce new source files, we get the following error:

Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1885430635 in class file test/Data
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:877)
    at org.joor.Compile$ByteArrayClassLoader.findClass(Compile.java:169)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.joor.Compile.lambda$compile$3(Compile.java:142)
    at org.joor.Compile$ClassFileManager.loadAndReturnMainClass(Compile.java:232)
    at org.joor.Compile.compile(Compile.java:141)
    at org.joor.Reflect.compile(Reflect.java:102)
    at org.jooq.annotation.processor.Test.main(Test.java:9)
ghost commented 4 years ago

Hi, @lukaseder! +1 to this issue. I also faced this issue, while trying to test my annotation processor with jOOR. But I have another error... Kind of this:

Caused by: java.lang.RuntimeException: java.lang.UnsupportedOperationException
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:163)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
        at org.joor.Compile.compile(Compile.java:97)
        ... 67 more
Caused by: java.lang.UnsupportedOperationException
        at java.compiler@13.0.2/javax.tools.SimpleJavaFileObject.getCharContent(SimpleJavaFileObject.java:131)
        at jdk.compiler/com.sun.tools.javac.api.ClientCodeWrapper$WrappedFileObject.getCharContent(ClientCodeWrapper.java:661)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:613)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:676)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:1031)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.<init>(JavacProcessingEnvironment.java:1117)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.next(JavacProcessingEnvironment.java:1153)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1392)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1263)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
        ... 70 more

Tested on Java 13, as you can see.

java -version

openjdk version "13.0.2" 2020-01-14

javax.tools.SimpleJavaFileObject#getCharContent just throws an exception and org.joor.Compile.JavaFileObject doesn't override this method and that's it.

lukaseder commented 4 years ago

Thanks, @jbreathe. Perhaps it's the same error, perhaps it isn't. To be sure, would you mind creating a new issue with a full example on how to reproduce this?

ghost commented 4 years ago

Sure, @lukaseder!

gabrielps commented 4 years ago

I'm having the same error as @lukaseder. Will probably fork and try to solve it.

michael-schnell commented 4 years ago

Same problem here ("java.lang.ClassFormatError: Incompatible magic value") while trying to test an annotation processor.

It seems that the source code generated by the annotation processor is interpreted as byte code. In ByteArrayClassLoader the return defineClass(name, bytes, 0, bytes.length) method fails, because the bytes array has the source and not class byte code. So the failing "magical number" is actually representing the first bytes of the source code created by the annotation processor.

muehmar commented 2 years ago

I'm developing an annotation processor which should create a new source file for each annotated class and facing the same issue when trying to use jOOR in tests:

Incompatible magic value 1885430635 in class file CustomerExtension
java.lang.ClassFormatError: Incompatible magic value 1885430635 in class file CustomerExtension
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:878)
    at org.joor.Compile$ByteArrayClassLoader.findClass(Compile.java:183)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at org.joor.Compile.lambda$compile$3(Compile.java:150)
    at org.joor.Compile$ClassFileManager.loadAndReturnMainClass(Compile.java:251)
    at org.joor.Compile.compile(Compile.java:149)
    at org.joor.Reflect.compile(Reflect.java:104)

I guess the new source files should get compiled before the class can be loaded.