forked from dotnet/java-interop
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJreRuntime.cs
More file actions
149 lines (126 loc) · 4.59 KB
/
JreRuntime.cs
File metadata and controls
149 lines (126 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
namespace Java.Interop {
struct JavaVMInitArgs {
public JniVersion version; /* use JNI_VERSION_1_2 or later */
public int nOptions;
public IntPtr /* JavaVMOption[] */ options;
public byte ignoreUnrecognized;
}
struct JavaVMOption {
public IntPtr /* const char* */ optionString;
public IntPtr /* void * */ extraInfo;
}
public class JreRuntimeOptions : JniRuntime.CreationOptions {
internal List<string> Options = new List<string> ();
public JniVersion JniVersion {get; set;}
public bool IgnoreUnrecognizedOptions {get; set;}
public Collection<string> ClassPath {get; private set;}
public JreRuntimeOptions ()
{
JniVersion = JniVersion.v1_2;
ClassPath = new Collection<string> () {
Path.Combine (
Path.GetDirectoryName (typeof (JreRuntimeOptions).Assembly.Location),
"java-interop.jar"),
};
bool onMono = Type.GetType ("Mono.Runtime", throwOnError: false) != null;
if (onMono) {
ValueManager = ValueManager ?? new MonoRuntimeValueManager ();
ObjectReferenceManager = ObjectReferenceManager ?? new MonoRuntimeObjectReferenceManager ();
}
}
public JreRuntimeOptions AddOption (string option)
{
Options.Add (option);
return this;
}
public JreRuntimeOptions AddSystemProperty (string name, string value)
{
if (name == null)
throw new ArgumentNullException ("name");
if (value == null)
throw new ArgumentNullException ("value");
if (name == "java.class.path")
throw new ArgumentException ("Do not use AddSystemProperty() for the 'java.class.path' property. Add to the ClassPath collection instead.", "name");
Options.Add (string.Format ("-D{0}={1}", name, value));
return this;
}
public JreRuntime CreateJreVM ()
{
return new JreRuntime (this);
}
}
public class JreRuntime : JniRuntime
{
const string LibraryName = "jvm.dll";
[DllImport (LibraryName)]
static extern int JNI_CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args);
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;
return builder;
}
} finally {
for (int i = 0; i < options.Length; ++i)
Marshal.FreeHGlobal (options [i].optionString);
}
}
internal protected JreRuntime (JreRuntimeOptions builder)
: base (CreateJreVM (builder))
{
}
public override string GetCurrentManagedThreadName ()
{
return Thread.CurrentThread.Name;
}
public override string GetCurrentManagedThreadStackTrace (int skipFrames, bool fNeedFileInfo)
{
return new StackTrace (skipFrames, fNeedFileInfo)
.ToString ();
}
protected override void Dispose (bool disposing)
{
var bridge = NativeMethods.java_interop_gc_bridge_get_current ();
if (bridge != IntPtr.Zero) {
NativeMethods.java_interop_gc_bridge_remove_current_app_domain (bridge);
}
base.Dispose (disposing);
}
}
}