static unsafe JreRuntimeOptions CreateJreVM(JreRuntimeOptions builder) { if (builder == null) { throw new ArgumentNullException("builder"); } if (builder.InvocationPointer != IntPtr.Zero) { return(builder); } var args = new JavaVMInitArgs() { version = builder.JniVersion, nOptions = builder.Options.Count + 1, ignoreUnrecognized = builder.IgnoreUnrecognizedOptions ? (byte)1 : (byte)0, }; var options = new JavaVMOption [builder.Options.Count + 1]; try { for (int i = 0; i < builder.Options.Count; ++i) { options [i].optionString = Marshal.StringToHGlobalAnsi(builder.Options [i]); } var classPath = Marshal.StringToHGlobalAnsi(string.Format("-Djava.class.path={0}", string.Join(Path.PathSeparator.ToString(), builder.ClassPath))); options [builder.Options.Count].optionString = classPath; fixed(JavaVMOption *popts = options) { args.options = (IntPtr)popts; IntPtr javavm; IntPtr jnienv; int r = JNI_CreateJavaVM(out javavm, out jnienv, ref args); if (r != 0) { var message = string.Format( "The JDK supports creating at most one JVM per process, ever; " + "do you have a JVM running already, or have you already created (and destroyed?) one? " + "(JNI_CreateJavaVM returned {0}).", r); throw new NotSupportedException(message); } builder.InvocationPointer = javavm; builder.EnvironmentPointer = jnienv; builder.DestroyRuntimeOnDispose = true; return(builder); } } finally { for (int i = 0; i < options.Length; ++i) { Marshal.FreeHGlobal(options [i].optionString); } } }
static unsafe JreRuntimeOptions CreateJreVM(JreRuntimeOptions builder) { if (builder == null) { throw new ArgumentNullException("builder"); } bool onMono = Type.GetType("Mono.Runtime", throwOnError: false) != null; if (onMono) { builder.ValueManager = builder.ValueManager ?? new MonoRuntimeValueManager(); builder.ObjectReferenceManager = builder.ObjectReferenceManager ?? new MonoRuntimeObjectReferenceManager(); } else { builder.ValueManager = builder.ValueManager ?? new ManagedValueManager(); builder.ObjectReferenceManager = builder.ObjectReferenceManager ?? new ManagedObjectReferenceManager(builder.JniGlobalReferenceLogWriter, builder.JniLocalReferenceLogWriter); } if (builder.InvocationPointer != IntPtr.Zero) { return(builder); } if (!string.IsNullOrEmpty(builder.JvmLibraryPath)) { IntPtr errorPtr = IntPtr.Zero; int r = NativeMethods.java_interop_jvm_load_with_error_message(builder.JvmLibraryPath !, out errorPtr); if (r != 0) { string error = Marshal.PtrToStringAnsi(errorPtr); NativeMethods.java_interop_free(errorPtr); throw new Exception($"Could not load JVM path `{builder.JvmLibraryPath}`: {error} ({r})!"); } } var args = new JavaVMInitArgs() { version = builder.JniVersion, nOptions = builder.Options.Count + 1, ignoreUnrecognized = builder.IgnoreUnrecognizedOptions ? (byte)1 : (byte)0, }; var options = new JavaVMOption [builder.Options.Count + 1]; try { for (int i = 0; i < builder.Options.Count; ++i) { options [i].optionString = Marshal.StringToHGlobalAnsi(builder.Options [i]); } var classPath = Marshal.StringToHGlobalAnsi(string.Format("-Djava.class.path={0}", string.Join(Path.PathSeparator.ToString(), builder.ClassPath))); options [builder.Options.Count].optionString = classPath; fixed(JavaVMOption *popts = options) { args.options = (IntPtr)popts; IntPtr javavm; IntPtr jnienv; int r = CreateJavaVM(out javavm, out jnienv, ref args); if (r != 0) { var message = string.Format( "The JDK supports creating at most one JVM per process, ever; " + "do you have a JVM running already, or have you already created (and destroyed?) one? " + "(JNI_CreateJavaVM returned {0}).", r); throw new NotSupportedException(message); } builder.InvocationPointer = javavm; builder.EnvironmentPointer = jnienv; return(builder); } } finally { for (int i = 0; i < options.Length; ++i) { Marshal.FreeHGlobal(options [i].optionString); } } }