Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,8 @@ $(JRE_DLL_CONFIG): src/Java.Runtime.Environment/Java.Runtime.Environment.csproj
$(MSBUILD) $(MSBUILD_FLAGS) $<

run-test-jnimarshal: bin/Test$(CONFIGURATION)/Java.Interop.Export-Tests.dll bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB) $(JRE_DLL_CONFIG)
mv -fv "$(JRE_DLL_CONFIG)" "$(JRE_DLL_CONFIG).bak"
MONO_TRACE_LISTENER=Console.Out \
$(RUNTIME) bin/$(CONFIGURATION)/jnimarshalmethod-gen.exe -v --jvm "$(JI_JVM_PATH)" -L "$(JI_MONO_LIB_PATH)mono/4.5" -L "$(JI_MONO_LIB_PATH)mono/4.5/Facades" "$<"
mv -fv "$(JRE_DLL_CONFIG).bak" "$(JRE_DLL_CONFIG)"
$(call RUN_TEST,$<)

# $(call GEN_CORE_OUTPUT, outdir, suffix, extra)
Expand Down
1 change: 0 additions & 1 deletion gendarme-ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,6 @@ M: System.IntPtr Java.Interop.NativeMethods::java_interop_jnienv_get_direct_buff
M: System.Int64 Java.Interop.NativeMethods::java_interop_jnienv_get_direct_buffer_capacity(System.IntPtr,System.IntPtr)
M: Java.Interop.JniObjectReferenceType Java.Interop.NativeMethods::java_interop_jnienv_get_object_ref_type(System.IntPtr,System.IntPtr)
M: System.Int32 Java.Interop.NativeMethods::java_interop_jvm_list(System.IntPtr[],System.Int32,System.Int32&)
M: System.Int32 Java.Interop.NativeMethods::java_interop_jvm_load(System.String)


R: Gendarme.Rules.Naming.UseCorrectSuffixRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ void WritePropertyFile (string jarPath, string javacPath, string jdkJvmPath, IEn
void WriteMakeFragmentFile (string jarPath, string javacPath, string jdkJvmPath, IEnumerable<string> includes)
{
using (var o = new StreamWriter (MakeFragmentFile.ItemSpec)) {
o.WriteLine ($"JI_JAR_PATH := {jarPath}");
o.WriteLine ($"JI_JAVAC_PATH := {javacPath}");
o.WriteLine ($"JI_JDK_INCLUDE_PATHS := {string.Join (" ", includes)}");
o.WriteLine ($"JI_JVM_PATH := {jdkJvmPath}");
o.WriteLine ($"export JI_JAR_PATH := {jarPath}");
o.WriteLine ($"export JI_JAVAC_PATH := {javacPath}");
o.WriteLine ($"export JI_JDK_INCLUDE_PATHS := {string.Join (" ", includes)}");
o.WriteLine ($"export JI_JVM_PATH := {jdkJvmPath}");
}
}

Expand Down
26 changes: 2 additions & 24 deletions src/Java.Interop/Java.Interop/JniRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public partial class CreationOptions {

public JniObjectReferenceManager ObjectReferenceManager {get; set;}
public JniTypeManager TypeManager {get; set;}
public string JvmDllPath {get; set;}
public string JvmLibraryPath {get; set;}

public CreationOptions ()
{
Expand All @@ -77,17 +77,10 @@ interface ISetRuntime {
}

partial class NativeMethods {
const string JvmLibrary = "jvm.dll";
const string JavaInteropLibrary = "java-interop";

[DllImport (JvmLibrary)]
internal static extern int JNI_GetCreatedJavaVMs ([Out] IntPtr[] handles, int bufLen, out int nVMs);

[DllImport (JavaInteropLibrary)]
internal static extern int java_interop_jvm_list ([Out] IntPtr[] handles, int bufLen, out int nVMs);

[DllImport (JavaInteropLibrary, CharSet=CharSet.Ansi)]
internal static extern int java_interop_jvm_load (string path);
}

public partial class JniRuntime : IDisposable
Expand All @@ -96,8 +89,6 @@ public partial class JniRuntime : IDisposable
const int JNI_EDETACHED = -2;
const int JNI_EVERSION = -3;

static public bool JvmDllLoaded { get; private set; }

static ConcurrentDictionary<IntPtr, JniRuntime> Runtimes = new ConcurrentDictionary<IntPtr, JniRuntime> ();

public static IEnumerable<JniRuntime> GetRegisteredRuntimes ()
Expand All @@ -115,10 +106,7 @@ public static JniRuntime GetRegisteredRuntime (IntPtr invocationPointer)

internal static int GetCreatedJavaVMs (IntPtr[] handles, int bufLen, out int nVMs)
{
if (JvmDllLoaded)
return NativeMethods.java_interop_jvm_list (handles, bufLen, out nVMs);

return NativeMethods.JNI_GetCreatedJavaVMs (handles, bufLen, out nVMs);
return NativeMethods.java_interop_jvm_list (handles, bufLen, out nVMs);
}

public static IEnumerable<IntPtr> GetAvailableInvocationPointers ()
Expand All @@ -134,16 +122,6 @@ public static IEnumerable<IntPtr> GetAvailableInvocationPointers ()
return handles;
}

protected static bool LoadJvmDll (string path)
{
if (JvmDllLoaded)
return true;

JvmDllLoaded = NativeMethods.java_interop_jvm_load (path) != 0;

return JvmDllLoaded;
}

static JniRuntime current;
public static JniRuntime CurrentRuntime {
get {
Expand Down
32 changes: 17 additions & 15 deletions src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class JreRuntimeOptions : JniRuntime.CreationOptions {

internal List<string> Options = new List<string> ();

public string JvmLibraryPath {get; set;}

public JniVersion JniVersion {get; set;}
public bool IgnoreUnrecognizedOptions {get; set;}

Expand Down Expand Up @@ -73,21 +75,9 @@ public JreRuntime CreateJreVM ()

public class JreRuntime : JniRuntime
{
const string JvmLibrary = "jvm.dll";
const string JavaInteropLibrary = "java-interop";

[DllImport (JvmLibrary)]
static extern int JNI_CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);

[DllImport (JavaInteropLibrary)]
static extern int java_interop_jvm_create (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);

static int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args)
{
if (JvmDllLoaded)
return java_interop_jvm_create (out javavm, out jnienv, ref args);

return JNI_CreateJavaVM (out javavm, out jnienv, ref args);
return NativeMethods.java_interop_jvm_create (out javavm, out jnienv, ref args);
}

static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
Expand All @@ -98,8 +88,12 @@ static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
if (builder.InvocationPointer != IntPtr.Zero)
return builder;

if (builder.JvmDllPath != null && !LoadJvmDll (builder.JvmDllPath))
throw new Exception ($"Unable to load JVM library: {builder.JvmDllPath}");
if (!string.IsNullOrEmpty (builder.JvmLibraryPath)) {
int r = NativeMethods.java_interop_jvm_load (builder.JvmLibraryPath);
if (r != 0) {
throw new Exception ($"Could not load JVM path `{builder.JvmLibraryPath}` ({r})!");
}
}

var args = new JavaVMInitArgs () {
version = builder.JniVersion,
Expand Down Expand Up @@ -160,5 +154,13 @@ protected override void Dispose (bool disposing)
base.Dispose (disposing);
}
}

partial class NativeMethods {
[DllImport (JavaInteropLib, CharSet=CharSet.Ansi)]
internal static extern int java_interop_jvm_load (string path);

[DllImport (JavaInteropLib, CharSet=CharSet.Ansi)]
internal static extern int java_interop_jvm_create (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);
}
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<configuration>
<dllmap dll="jvm.dll" os="@OS_NAME@" target="@JI_JVM_PATH@"/>
@JAVA_RUNTIME_ENVIRONMENT_DLLMAP@
</configuration>
69 changes: 43 additions & 26 deletions src/java-interop/java-interop-jvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,73 @@
#include "java-interop-logger.h"
#include "java-interop-util.h"

static struct DylibJVM *jvm = NULL;

int java_interop_jvm_load (const char *path)
typedef int (*java_interop_JNI_CreateJavaVM_fptr) (JavaVM **p_vm, void **p_env, void *vm_args);
typedef int (*java_interop_JNI_GetCreatedJavaVMs_fptr) (JavaVM **vmBuf, int bufLen, int *nVMs);

struct DylibJVM {
void *dl_handle;
java_interop_JNI_CreateJavaVM_fptr JNI_CreateJavaVM;
java_interop_JNI_GetCreatedJavaVMs_fptr JNI_GetCreatedJavaVMs;
};

static struct DylibJVM *jvm;

int
java_interop_jvm_load (const char *path)
{
if (jvm != NULL) {
return JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED;
}

jvm = calloc (1, sizeof (struct DylibJVM));
if (!jvm) {
return JAVA_INTEROP_JVM_FAILED_OOM;
}

jvm->dl_handle = dlopen (path, RTLD_LAZY);

if (!jvm->dl_handle)
return 0;
if (!jvm->dl_handle) {
free (jvm);
jvm = NULL;
return JAVA_INTEROP_JVM_FAILED_NOT_LOADED;
}

int symbols_missing = 0;

#define LOAD_SYMBOL(symbol) \
jvm->symbol = dlsym (jvm->dl_handle, #symbol); \
if (!jvm->symbol) { \
log_error (LOG_DEFAULT, "Failed to load JVM symbol: %s", #symbol); \
symbols_missing = 1; \
}
#define LOAD_SYMBOL(symbol) do { \
jvm->symbol = dlsym (jvm->dl_handle, #symbol); \
if (!jvm->symbol) { \
log_error (LOG_DEFAULT, "Failed to load JVM symbol: %s", #symbol); \
symbols_missing = 1; \
} \
} while (0)

LOAD_SYMBOL(JNI_CreateJavaVM);
LOAD_SYMBOL(JNI_GetCreatedJavaVMs);

LOAD_SYMBOL(JNI_CreateJavaVM)
LOAD_SYMBOL(JNI_GetCreatedJavaVMs)
#undef LOAD_SYMBOL

if (symbols_missing) {
log_fatal (LOG_DEFAULT, "Failed to load some Mono symbols, aborting...");
exit (FATAL_EXIT_JVM_MISSING_SYMBOLS);
free (jvm);
jvm = NULL;
return JAVA_INTEROP_JVM_FAILED_SYMBOL_MISSING;
}

return 1;
return 0;
}

static inline void
_assert_dl_handle ()
{
if (!jvm || !jvm->dl_handle) {
log_fatal (LOG_DEFAULT, "Missing JVM symbols!");
exit (FATAL_EXIT_JVM_MISSING_SYMBOLS);
}
}
#define ji_return_val_if_fail(expr, val) do { if (!(expr)) return (val); } while (0)

int java_interop_jvm_create (JavaVM **p_vm, void **p_env, void *vm_args)
{
_assert_dl_handle ();
ji_return_val_if_fail (jvm != NULL, JAVA_INTEROP_JVM_FAILED_NOT_LOADED);

return (*jvm->JNI_CreateJavaVM) (p_vm, p_env, vm_args);
}

int java_interop_jvm_list (JavaVM **vmBuf, int bufLen, int *nVMs)
{
_assert_dl_handle ();
ji_return_val_if_fail (jvm != NULL, JAVA_INTEROP_JVM_FAILED_NOT_LOADED);

return (*jvm->JNI_GetCreatedJavaVMs) (vmBuf, bufLen, nVMs);
}
16 changes: 6 additions & 10 deletions src/java-interop/java-interop-jvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@

typedef void JavaVM;

typedef int (*java_interop_JNI_CreateJavaVM_fptr) (JavaVM **p_vm, void **p_env, void *vm_args);
typedef int (*java_interop_JNI_GetCreatedJavaVMs_fptr) (JavaVM **vmBuf, int bufLen, int *nVMs);

/* NOTE: structure members MUST NOT CHANGE ORDER. */
struct DylibJVM {
void *dl_handle;
java_interop_JNI_CreateJavaVM_fptr JNI_CreateJavaVM;
java_interop_JNI_GetCreatedJavaVMs_fptr JNI_GetCreatedJavaVMs;
};

JAVA_INTEROP_BEGIN_DECLS

#define JAVA_INTEROP_JVM_FAILED (-1000)
#define JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED (JAVA_INTEROP_JVM_FAILED-1)
#define JAVA_INTEROP_JVM_FAILED_NOT_LOADED (JAVA_INTEROP_JVM_FAILED-2)
#define JAVA_INTEROP_JVM_FAILED_OOM (JAVA_INTEROP_JVM_FAILED-3)
#define JAVA_INTEROP_JVM_FAILED_SYMBOL_MISSING (JAVA_INTEROP_JVM_FAILED-4)

MONO_API int java_interop_jvm_load (const char *path);
MONO_API int java_interop_jvm_create (JavaVM **p_vm, void **p_env, void *vm_args);
MONO_API int java_interop_jvm_list (JavaVM **vmBuf, int bufLen, int *nVMs);
Expand Down
4 changes: 3 additions & 1 deletion tests/TestJVM/TestJVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class TestJVM : JreRuntime {
static JreRuntimeOptions CreateBuilder (string[] jars)
{
var dir = Path.GetDirectoryName (typeof (TestJVM).Assembly.Location);
var builder = new JreRuntimeOptions ();
var builder = new JreRuntimeOptions () {
JvmLibraryPath = Environment.GetEnvironmentVariable ("JI_JVM_PATH"),
};
if (jars != null) {
foreach (var jar in jars)
builder.ClassPath.Add (Path.Combine (dir, jar));
Expand Down
4 changes: 3 additions & 1 deletion tools/jnimarshalmethod-gen/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ void ProcessAssemblies (List<string> assemblies)

void CreateJavaVM (string jvmDllPath)
{
var builder = new JreRuntimeOptions { JvmDllPath = jvmDllPath };
var builder = new JreRuntimeOptions {
JvmLibraryPath = jvmDllPath,
};

try {
builder.CreateJreVM ();
Expand Down