-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[native-image] Any chance to support dynamic class loading if the JARs loaded by code is given at native-image compiling time? #461
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
Comments
@cqjjjzr thank you for your comment. Yes, the features that you mentioned are not available yet, but we plan to implement them. They should be available soon. |
@cqjjjzr we added |
@cqjjjzr 3c85875 improves |
@cstancu does that mean GraalVM would eventually support scenarios like this: Let's say I have a program that has a pluggable architecture. It has a package org.behrang.program;
public interface Plugin {
String process(String input);
} The entry point of the program looks for a CLI argument named package org.behrang.program;
public class Main {
public static void main(String[] args) throws Exception {
String pluginClassname = null;
for (int i = 0; i < args.length; i++) {
if ("--plugin".equals(args[i]) && args.length > i + 1) {
pluginClassname = args[i + 1];
break;
}
}
if (pluginClassname == null) {
System.err.println("--plugin is required");
System.exit(1);
}
Class<?> pluginClass = Class.forName(pluginClassname);
Plugin p = (Plugin) pluginClass.getDeclaredConstructor().newInstance();
System.out.println(p.process("Hello, World!"));
}
} It then creates an instance of the plugin and invokes it: Class<?> pluginClass = Class.forName(pluginClassname);
Plugin p = (Plugin) pluginClass.getDeclaredConstructor().newInstance();
System.out.println(p.process("Hello, World!")); A third-party can implement a plugin by implementing this interface: package org.behrang.plugin;
import org.behrang.program.Plugin;
public class SamplePlugin implements Plugin {
@Override
public String process(String s) {
return "org.behrang.plugin.SamplePlugin: " + s;
}
} Finally, the user can put the JAR file for the plugin in the classpath and run the program:
In real-world applications the plugin architecutre might use a class path and/or MANIFEST.MF scanner or another approach to load the plugin class. There are many programs that work like this. For example in a static site generator a user can choose what library to use for processing markdown. Will GraalVM support use cases like this? E.g.: a native image program that can load a custom library at execution time/runtime? Or in this example, creating a native image of |
Any answer to @behrangsa questions? We're many to like his comment. It seems there's a community interest in this possibility! |
I am also kind of interested in this feature. Right now, we are running jvm with in-built JIT which is kind of doing job for us on our machines. But due to some requirement, we need to provide our obfuscated jar to one of our clients who will run it on their machines. I tried exploring different obfuscation types which would provide me ultimate security, one approach I came out was to provide "native exe" to client so that he can run it on their env and at the same time we save ourselves from reverse engineering techniques. But right now, I think only graal provides facility to convert whole program to native-image. But here problem is that we cannot load a jar file dynamically. If something exists like that native-image can work with a dynamic jar that would resolve problem. P/S client has some hashing logic in this jar which he wont provide so, I am kind of stuck here to come out with a little bit of better approach. |
same scene |
that reminds me Excelsior Jet JVM which compile java into native code, at the same time they able to compile any downloaded jar into dll as well. |
Any updates on this? |
Same need than behrangsa. We plan to fully migrate Reqchecker to the great Graal native feature, a basic plugin mechanism would be great. |
@khilogic @DevSrSouza @ivanooi @siaron @behrangsa The answer is relativ simple as you produce Operating System dependend binarys you can use all IPC channels the Operating system provides depending on your performance usecase and data you can then choose what to use a simple understand able example is named pipes try {
// Connect to the pipe
RandomAccessFile pipe = new RandomAccessFile("\\\\.\\pipe\\testpipe", "rw");
String echoText = "Hello word\n";
// write to pipe
pipe.write ( echoText.getBytes() );
// read response
String echoResponse = pipe.readLine();
System.out.println("Response: " + echoResponse );
pipe.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} putting that with some kind of logic into your binarys and voila they can talk to each other and call each other if you want something high performant capnproto-java rocks more then the most people understand it is typed binary capability based Remote Function Invocation same style used to drive Fuchsia OS Components by the way and it is a lot of faster then grpc or alternativ calling methods it is a module system for binary !!! Not only Java but in case of native image we can talk about binary :) binary.exe <==> named pipe <==> module.exe |
this look like data sharing. how bout logic? means dynamically load a logic and execute it. |
In bytecode, I can dynamically load and execute a class from the jar file. I can change the logic any times. Client always download and execute the latest logic. |
I see... @frank-dspeed so, your solution is to compile the logic into another executable... binary.exe <==> named pipe <==> module.exe |
@ivanooi for logic you could maybe use espresso it is the JDK running on GraalVM that means you can compile a JDK into your binary that can do runtime evaluation. https://www.graalvm.org/22.0/reference-manual/java-on-truffle/ but at last to get a binary with fast runtime logic evaluation you need to embedded any engine at last i would go for JS as the es4x project did prove that this even outpferforms many java only stacks. https://github.com/reactiverse/es4x you can compile that to nativ via quarkus it got done successfull . |
point number 3, does it mean native executable? so...with espresso, i can dynamically load and execute java bytecode in the native image? thanks! look promising! :-D
|
Wonder if this is working now - with dynamic classes ? forName(..) ? |
I don't think Jet quite did that exactly . Your basic app would be AOT compiled into .exe and .dll files, and additional classes encountered at runtime would be JIT compiled by the JVM Jet provided too. Best of both worlds. |
From the "LIMITATIONS.md" I know the dynamic class loading is not supported.
But is there any way to support it if the JARs loaded is already known when compiling and can the native-image tool statically link it into the built program?
Also, can the tool just analyze the invocations to Class.forName and find out the class being loaded if it's invoked by a const string class name.(Like forcely loading JDBC database drivers)
The reason for supporting this is for plugin supports. Many JVM programs supports dynamic plugin loading or modding. If static linking can be supported it would be greatly helpful.
Thanks.
The text was updated successfully, but these errors were encountered: