Skip to content

Commit ebb49cb

Browse files
Invoke Main.main via JVM and its JNI
1 parent ed2ce35 commit ebb49cb

File tree

2 files changed

+44
-13
lines changed
  • engine/runner/src/main/java/org/enso/runner
  • lib/java/os-environment/src/main/java/org/enso/os/environment/jni

2 files changed

+44
-13
lines changed

engine/runner/src/main/java/org/enso/runner/Main.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.enso.editions.DefaultEdition;
3939
import org.enso.libraryupload.LibraryUploader.UploadFailedError;
4040
import org.enso.os.environment.chdir.WorkingDirectory;
41+
import org.enso.os.environment.jni.JVM;
4142
import org.enso.pkg.Contact;
4243
import org.enso.pkg.PackageManager;
4344
import org.enso.pkg.PackageManager$;
@@ -1404,10 +1405,9 @@ private boolean isJvmModeEnabled(CommandLine line) {
14041405
}
14051406

14061407
private void launchJvm(
1407-
CommandLine line, Map<String, String> props, File component, String javaPath)
1408+
CommandLine line, Map<String, String> props, File component, String javaHome)
14081409
throws IOException, InterruptedException {
14091410
var commandAndArgs = new ArrayList<String>();
1410-
commandAndArgs.add(javaPath);
14111411
var jvmOptions = System.getenv("JAVA_OPTS");
14121412
if (jvmOptions != null) {
14131413
for (var op : jvmOptions.split(" ")) {
@@ -1435,6 +1435,9 @@ private void launchJvm(
14351435
commandAndArgs.add(component.getPath());
14361436
commandAndArgs.add("-m");
14371437
commandAndArgs.add("org.enso.runner/org.enso.runner.Main");
1438+
1439+
var jvm = JVM.create(javaHome, commandAndArgs.toArray(new String[0]));
1440+
commandAndArgs.clear();
14381441
var it = line.iterator();
14391442
while (it.hasNext()) {
14401443
var op = it.next();
@@ -1456,16 +1459,11 @@ private void launchJvm(
14561459
}
14571460
}
14581461
commandAndArgs.addAll(line.getArgList());
1459-
var pb = new ProcessBuilder();
1460-
pb.inheritIO();
1461-
pb.command(commandAndArgs);
1462-
var p = pb.start();
1463-
var exitCode = p.waitFor();
1464-
if (exitCode == 0) {
1465-
throw exitSuccess();
1466-
} else {
1467-
throw doExit(exitCode);
1468-
}
1462+
1463+
jvm.executeMain("org/enso/runner/Main", commandAndArgs.toArray(new String[0]));
1464+
1465+
// the above call should never return
1466+
throw doExit(1);
14691467
}
14701468

14711469
private void launch(String[] args) throws IOException, InterruptedException, URISyntaxException {

lib/java/os-environment/src/main/java/org/enso/os/environment/jni/JVM.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,45 @@ public static JVM create(String javaHome, String... options) {
3434
return new JVM(createJvmFn, options);
3535
}
3636

37+
/**
38+
* Executes main method of provided class
39+
*
40+
* @param classNameWithSlashes class (with `/` as separators) to search main method in
41+
* @param args arguments to pass to the main method
42+
*/
43+
public void executeMain(String classNameWithSlashes, String[] args) {
44+
var e = env();
45+
try (var className = CTypeConversion.toCString(classNameWithSlashes);
46+
var mainName = CTypeConversion.toCString("main");
47+
var stringName = CTypeConversion.toCString("java/lang/String");
48+
var mainSig = CTypeConversion.toCString("([Ljava/lang/String;)V"); ) {
49+
var fn = e.getFunctions();
50+
var mainClazz = fn.getFindClass().call(e, className.get());
51+
assert mainClazz.isNonNull() : "Class not found " + classNameWithSlashes;
52+
var mainMethod = fn.getGetStaticMethodID().call(e, mainClazz, mainName.get(), mainSig.get());
53+
assert mainMethod.isNonNull() : "main method found in " + classNameWithSlashes;
54+
var stringClazz = fn.getFindClass().call(e, stringName.get());
55+
var argsCopy =
56+
fn.getNewObjectArray().call(e, args.length, stringClazz, WordFactory.nullPointer());
57+
58+
for (var i = 0; i < args.length; i++) {
59+
try (var ithArg = CTypeConversion.toCString(args[i]); ) {
60+
var str = fn.getNewStringUTF().call(e, ithArg.get());
61+
fn.getSetObjectArrayElement().call(e, argsCopy, i, str);
62+
}
63+
}
64+
var arg = StackValue.get(JNI.JValue.class);
65+
arg.setJObject(argsCopy);
66+
fn.getCallStaticVoidMethodA().call(e, mainClazz, mainMethod, arg);
67+
}
68+
}
69+
3770
/**
3871
* Initialize or just obtain environment associated with this JVM.
3972
*
4073
* @return JNI environment to make calls into the JVM
4174
*/
42-
public final JNI.JNIEnv env() {
75+
final JNI.JNIEnv env() {
4376
if (env.isNull()) {
4477
env = initializeEnv();
4578
}

0 commit comments

Comments
 (0)