-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GR-37582] Default to running image-builder on module path. #4468
Conversation
6fd6d0a
to
139280e
Compare
fdd8459
to
5ca7721
Compare
9ca9ba5
to
5cdabc9
Compare
Hi, is there a description (or issue?) that goes along with this PR? I'm interested in the rationale behind moving the native image builder to the module path and what the follow-on repercussions of the move are.
Any additional context for this would be appreciated. |
Hi @DanHeidinga
For native-image to support building Java modules into images we run the image builder on module path. So far we only do that when native-image gets a
Nope. You can still do that. But if you use internal APIs you will need to add options to open The best strategy is to open up package
That's already the second stage 😉 For a while now all the images of a GraalVM release that are provided by the substratevm suite are entirely build on module-path. (Search for In the future we hope to be able to build all images that are part of GraalVM on the module-path. For that to happen we have to make truffle also load truffle languages as Java modules (and not via URLClassloader, as it is now). Once this is achieved we can remove all the code from the builder that is specific to running the builder on classpath. BTW, I talked more about this a while ago in the Native Image Committer Community Meeting #4385 Feel free to attend those meetings in the future. |
e638e6e
to
ebf99f1
Compare
That makes a lot of sense - a single way to do things is easier to support than two ways.
So we can still Substitute any class, we just need to open the required Graal modules to get access to APIs to change the runtime (not buildtime) view of module accessibility. Or does using
Thanks for sharing the link. There's some interesting context in there, especially related to how the BootModule.layer() needs to be rebuilt between the build & run time.
Will do. |
Module accessibility is carried over from hosted to runtime world. Thus if you change the state of the module system of modules that are seen by the reachability-analysis then you also affected the state of the module system that is part of the image that you are building. |
ebf99f1
to
cda99b4
Compare
bcef040
to
fc95742
Compare
@zakkak has been doing some testing and found an error on this run:
|
You can pass |
b8b6fb9
to
3ca818d
Compare
Once oracle/graal#4468 gets merged, native-image will run on module-path requiring some additional exports to be passed to it in order to access internal APIs.
Hi @olpaw I did make Quarkus add all the necessary
but I fail to see how the module path change could be affecting that part. Do you have any clue that could possibly help me figure out what's wrong? Note that |
f74c8be
to
bf7efe5
Compare
@zakkak please provide me with a simple way to reproduce this and I will debug it to figure out what is missing. |
Thank you @olpaw. Not a "minimal" reproducer, but the following commands build and run the test that is failing.
To pass additional options to
|
…oader with a parent ClassPathClassLoader
bf7efe5
to
bfb082e
Compare
Hi @zakkak! Re:
I debugged a bit deeper into this and this is where we end up at image runtime:
Then in
It looks like That's all for now. I will further look into this next week. |
|
When building with |
I think that's exactly what's happening. The generated // Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
private static void registerJniAccessibleClass70() {
try {
ClassLoader var0 = Thread.currentThread().getContextClassLoader();
Class var1 = Class.forName("sun.font.TrueTypeFont", (boolean)0, var0);
Constructor[] var3 = var1.getDeclaredConstructors();
Method[] var4 = var1.getDeclaredMethods();
Field[] var5 = var1.getDeclaredFields();
Class[] var2 = new Class[]{var1};
JNIRuntimeAccess.register(var2);
JNIRuntimeAccess.register((Executable[])var3);
JNIRuntimeAccess.register((Executable[])var4);
JNIRuntimeAccess.register((boolean)0, var5);
} catch (Throwable var6) {
}
} However looking at the GraalVM code I see that when registering a constructor or a method it first looks it up using the graal/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ReflectionUtil.java Lines 49 to 55 in 06c54c1
Which apparently Quarkus doesn't do, which might be what's causing the issue. I will try a quick patch tomorrow if including that part makes it work. Thanks a lot @olpaw !
Unfortunately not. |
@zakkak thanks for confirming. Btw ... private static void registerJniAccessibleClass70() {
try {
...
} catch (Throwable var6) {
}
} Swallowing this You will save yourself a lot of trouble if you fix this 😉 |
Indeed, after fixing this it became clear what the issue was and the fix was as simple as adding Thanks again @olpaw that really saved me a lot of time :) |
Once oracle/graal#4468 gets merged, native-image will run on module-path requiring some additional exports to be passed to it in order to access internal APIs.
This commit adds a workaround for GraalVM 22.2 native-image builder running on module path. Because Micronaut uses features which use internal APIs (and no workaround for that), building on 22.2 fails. This commit adds a flag which will let users build by adding a module export. See oracle/graal#4468
* Fix support for GraalVM 22.2 This commit adds a workaround for GraalVM 22.2 native-image builder running on module path. Because Micronaut uses features which use internal APIs (and no workaround for that), building on 22.2 fails. This commit adds a flag which will let users build by adding a module export. See oracle/graal#4468 * Test against latest GraalVM
* `--allow-incomplete-classpath` is now default. * `VersionEnum` is now loaded during build time. * Native image now runs on the module path, obviously missing an export (see also: oracle/graal#4468)
* `--allow-incomplete-classpath` is now default. * `VersionEnum` is now loaded during build time. * Native image now runs on the module path, obviously missing an export (see also: oracle/graal#4468)
* `--allow-incomplete-classpath` is now default. * `VersionEnum` is now loaded during build time. * Native image now runs on the module path, obviously missing an export (see also: oracle/graal#4468)
No description provided.