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.81k stars 376 forks source link

Add ClassLoader to CompileOptions in order to allow for overriding the ClassLoader #72

Closed vksiva closed 1 year ago

vksiva commented 5 years ago

Expected behavior and actual behavior:

Using the example as presented in the README,

Supplier<String> supplier = Reflect.compile(
    "com.example.HelloWorld",
    "package com.example;\n" +
    "class HelloWorld implements java.util.function.Supplier<String> {\n" +
    "    public String get() {\n" +
    "        return \"Hello World!\";\n" +
    "    }\n" +
    "}\n").create().get();

// Prints "Hello World!"
System.out.println(supplier.get());

If the text has to be changed to "Hi World!" and the class is recompiled, the below code still prints "Hello World!"

 supplier = Reflect.compile(
    "com.example.HelloWorld",
    "package com.example;\n" +
    "class HelloWorld implements java.util.function.Supplier<String> {\n" +
    "    public String get() {\n" +
    "        return \"Hi World!\";\n" +
    "    }\n" +
    "}\n").create().get();

// Still prints "Hello World!"
System.out.println(supplier.get());

One way to ensure the class gets recompiled is by using different classloaders during compile. Can we use a custom classloader for the Reflect.compile() method. It was raised in #64.

Steps to reproduce the problem:

Mentioned above.

Versions:

lukaseder commented 5 years ago

Thanks for reporting this. Indeed, we've solved this in the next release through https://github.com/jOOQ/jOOR/issues/67

lukaseder commented 5 years ago

In fact, no. CompileOptions does not allow for overriding the ClassLoader yet. Will look into this soon. There are tons of open questions when doing that, of course. The current approach allows for some additional visibility to be implemented, from the very location of where the class is being compiled. With arbitrary class loaders, this will no longer be true.

Further investigation needed.

lukaseder commented 5 years ago

The custom class loader feature has been implemented. But I will also implement a breaking change that avoids re-loading a previously compiled class by default. I don't think that's what anyone really wants. See #76

lukaseder commented 5 years ago

Hmm, no in fact #76 cannot be implemented. The current implementation prevents LinkageError in some cases.

lukaseder commented 5 years ago

I will revert this change. Unfortunately, providing a custom ClassLoader doesn't really help solve any problems in JDK 9+

lukaseder commented 1 year ago

This appears to be useful for jOOQ's code generator as well, including for:

A quick attempt at re-implementing this seems to work for jOOQ (whose code generation plugin creates its own URLClassLoader). Perhaps I just made a mistake when implementing the tests at the time?

I'll try this again.

lukaseder commented 1 year ago

Hmm, no in fact #76 cannot be implemented. The current implementation prevents LinkageError in some cases.

I'm no longer running into these errors from: https://github.com/jOOQ/jOOR/issues/72#issuecomment-444077568

Perhaps that was a JDK bug, at the time?

lukaseder commented 1 year ago

Fixed for jOOR 0.9.15

lukaseder commented 1 year ago

Time for a release, too.