@@ -39,27 +39,14 @@ struct JavaVMThreadAttachArgs {
3939 public IntPtr group ; /* global ref of a ThreadGroup object, or NULL */
4040 }
4141
42- struct JavaVMOption {
43- public IntPtr /* const char * */ optionString ;
44- public IntPtr /* void * */ extraInfo ;
45- }
46-
47- struct JavaVMInitArgs {
48- public JniVersion version ; /* use JNI_VERSION_1_2 or later */
49-
50- public int nOptions ;
51- public IntPtr /* JavaVMOption[] */ options ;
52- public byte ignoreUnrecognized ;
53- }
54-
5542 public sealed class JavaVMSafeHandle : SafeHandle {
5643
5744 JavaVMSafeHandle ( )
5845 : base ( IntPtr . Zero , ownsHandle : false )
5946 {
6047 }
6148
62- internal JavaVMSafeHandle ( IntPtr handle )
49+ public JavaVMSafeHandle ( IntPtr handle )
6350 : this ( )
6451 {
6552 SetHandle ( handle ) ;
@@ -90,52 +77,36 @@ public override string ToString ()
9077 }
9178 }
9279
93- public sealed class JavaVMBuilder {
94-
95- internal List < string > Options = new List < string > ( ) ;
80+ public class JavaVMOptions {
9681
97- public JniVersion JniVersion { get ; set ; }
98- public bool IgnoreUnrecognizedOptions { get ; set ; }
9982 public bool TrackIDs { get ; set ; }
83+ public bool DestroyVMOnDispose { get ; set ; }
10084
101- public JavaVMBuilder ( )
102- {
103- JniVersion = JniVersion . v1_2 ;
104- }
105-
106- public JavaVMBuilder AddOption ( string option )
107- {
108- Options . Add ( option ) ;
109- return this ;
110- }
111-
112- public JavaVMBuilder AddSystemProperty ( string name , string value )
113- {
114- if ( name == null )
115- throw new ArgumentNullException ( "name" ) ;
116- if ( value == null )
117- throw new ArgumentNullException ( "value" ) ;
118- Options . Add ( string . Format ( "-D{0}={1}" , name , value ) ) ;
119- return this ;
120- }
85+ public JavaVMSafeHandle VMHandle { get ; set ; }
86+ public JniEnvironmentSafeHandle EnvironmentHandle { get ; set ; }
12187
122- public JavaVM CreateJavaVM ( )
88+ public JavaVMOptions ( )
12389 {
124- return new JavaVM ( this ) ;
12590 }
12691 }
12792
128- public partial class JavaVM : IDisposable
93+ public abstract partial class JavaVM : IDisposable
12994 {
130- const string LibraryName = "/System/Library/Frameworks/JavaVM.framework/JavaVM" ;
13195
132- [ DllImport ( LibraryName ) ]
133- static extern int JNI_CreateJavaVM ( out JavaVMSafeHandle javavm , out JniEnvironmentSafeHandle jnienv , ref JavaVMInitArgs args ) ;
96+ static ConcurrentDictionary < IntPtr , JavaVM > JavaVMs = new ConcurrentDictionary < IntPtr , JavaVM > ( ) ;
13497
135- [ DllImport ( LibraryName ) ]
136- static extern int JNI_GetCreatedJavaVMs ( [ Out ] IntPtr [ ] handles , int bufLen , out int nVMs ) ;
98+ public static IEnumerable < JavaVM > GetRegisteredJavaVMs ( )
99+ {
100+ return JavaVMs . Values ;
101+ }
137102
138- static ConcurrentDictionary < IntPtr , JavaVM > JavaVMs = new ConcurrentDictionary < IntPtr , JavaVM > ( ) ;
103+ public static JavaVM GetRegisteredJavaVM ( JavaVMSafeHandle handle )
104+ {
105+ JavaVM vm ;
106+ return JavaVMs . TryGetValue ( handle . DangerousGetHandle ( ) , out vm )
107+ ? vm
108+ : null ;
109+ }
139110
140111 static JavaVM current ;
141112 public static JavaVM Current {
@@ -144,12 +115,12 @@ public static JavaVM Current {
144115 return current ;
145116 JavaVM c = null ;
146117 int count = 0 ;
147- foreach ( var vm in GetCreatedJavaVMs ( ) ) {
118+ foreach ( var vm in JavaVMs . Values ) {
148119 if ( count ++ == 0 )
149120 c = vm ;
150121 }
151122 if ( count == 0 )
152- throw new InvalidOperationException ( "No JavaVM has been created. Please use JavaVMBuilder.CreateJavaVM ()." ) ;
123+ throw new InvalidOperationException ( "No JavaVM has been created. Please use Java.Interop.JreVMBuilder.CreateJreVM ()." ) ;
153124 if ( count > 1 )
154125 throw new NotSupportedException ( string . Format ( "Found {0} JavaVMs. Don't know which to use. Use JavaVM.SetCurrent()." , count ) ) ;
155126 return current = c ;
@@ -160,52 +131,10 @@ public static void SetCurrent (JavaVM newCurrent)
160131 {
161132 if ( newCurrent == null )
162133 throw new ArgumentNullException ( "newCurrent" ) ;
134+ JavaVMs . TryAdd ( newCurrent . SafeHandle . DangerousGetHandle ( ) , newCurrent ) ;
163135 current = newCurrent ;
164136 }
165137
166- public static IEnumerable < JavaVM > GetCreatedJavaVMs ( )
167- {
168- int nVMs ;
169- int r = JNI_GetCreatedJavaVMs ( null , 0 , out nVMs ) ;
170- if ( r != 0 )
171- throw new NotSupportedException ( "JNI_GetCreatedJavaVMs() returned: " + r ) ;
172- var handles = new IntPtr [ nVMs ] ;
173- r = JNI_GetCreatedJavaVMs ( handles , handles . Length , out nVMs ) ;
174- if ( r != 0 )
175- throw new InvalidOperationException ( "JNI_GetCreatedJavaVMs() [take 2!] returned: " + r ) ;
176- foreach ( var h in handles ) {
177- JavaVM v ;
178- if ( ! JavaVMs . TryGetValue ( h , out v ) )
179- JavaVMs . TryAdd ( h , v = new JavaVM ( new JavaVMSafeHandle ( h ) ) ) ;
180- yield return v ;
181- }
182- }
183-
184- public static JavaVM FromHandle ( JavaVMSafeHandle handle )
185- {
186- JavaVM vm ;
187- if ( JavaVMs . TryGetValue ( handle . DangerousGetHandle ( ) , out vm ) )
188- return vm ;
189- return new JavaVM ( handle , null ) ;
190- }
191-
192- void CreateJavaVM ( ref JavaVMInitArgs args )
193- {
194- JavaVMSafeHandle javavm ;
195- JniEnvironmentSafeHandle jnienv ;
196- int r = JNI_CreateJavaVM ( out javavm , out jnienv , ref args ) ;
197- if ( r != 0 ) {
198- var message = string . Format ( "{1}JNI_CreateJavaVM returned {0}." ,
199- r ,
200- JavaVMs . Count == 0
201- ? ""
202- : "The JDK supports creating at most one JVM per process, ever; " +
203- "do you have a JVM running already, or have you already created (and destroyed?) one? " ) ;
204- throw new NotSupportedException ( message ) ;
205- }
206- Initialize ( javavm , jnienv ) ;
207- }
208-
209138 ConcurrentDictionary < IntPtr , JniEnvironment > Environments = new ConcurrentDictionary < IntPtr , JniEnvironment > ( ) ;
210139
211140 ConcurrentDictionary < SafeHandle , IDisposable > TrackedInstances ;
@@ -219,58 +148,26 @@ void CreateJavaVM (ref JavaVMInitArgs args)
219148
220149 public JavaVMSafeHandle SafeHandle { get ; private set ; }
221150
222- protected JavaVM ( )
223- : this ( new JavaVMBuilder ( ) )
151+ protected JavaVM ( JavaVMOptions options )
224152 {
225- }
226-
227- internal protected unsafe JavaVM ( JavaVMBuilder builder )
228- {
229- if ( builder == null )
230- throw new ArgumentNullException ( "builder" ) ;
231-
232- var args = new JavaVMInitArgs ( ) {
233- version = builder . JniVersion ,
234- nOptions = builder . Options . Count ,
235- ignoreUnrecognized = builder . IgnoreUnrecognizedOptions ? ( byte ) 1 : ( byte ) 0 ,
236- } ;
237- var options = new JavaVMOption [ builder . Options . Count ] ;
238- try {
239- for ( int i = 0 ; i < options . Length ; ++ i )
240- options [ i ] . optionString = Marshal . StringToHGlobalAnsi ( builder . Options [ i ] ) ;
241- fixed ( JavaVMOption * popts = options ) {
242- args . options = ( IntPtr ) popts ;
243- CreateJavaVM ( ref args ) ;
244- }
245- } finally {
246- for ( int i = 0 ; i < options . Length ; ++ i )
247- Marshal . FreeHGlobal ( options [ i ] . optionString ) ;
248- }
153+ if ( options == null )
154+ throw new ArgumentNullException ( "options" ) ;
155+ if ( options . VMHandle == null )
156+ throw new ArgumentException ( "options.VMHandle is null" , "options" ) ;
157+ if ( options . VMHandle . IsInvalid )
158+ throw new ArgumentException ( "options.VMHandle is not valid." , "options" ) ;
249159
250- TrackIDs = builder . TrackIDs ;
251- DestroyVM = true ;
252- }
160+ TrackIDs = options . TrackIDs ;
161+ DestroyVM = options . DestroyVMOnDispose ;
253162
254- public JavaVM ( JavaVMSafeHandle safeHandle , JniEnvironmentSafeHandle jnienv = null )
255- {
256- Initialize ( safeHandle , jnienv ) ;
257- }
258-
259- void Initialize ( JavaVMSafeHandle safeHandle , JniEnvironmentSafeHandle jnienv )
260- {
261- if ( safeHandle == null )
262- throw new ArgumentNullException ( "safeHandle" ) ;
263- if ( safeHandle . IsInvalid )
264- throw new ArgumentException ( "safeHandle is not valid." , "safeHandle" ) ;
163+ SafeHandle = options . VMHandle ;
164+ Invoker = SafeHandle . CreateInvoker ( ) ;
265165
266166 if ( current == null )
267167 current = this ;
268168
269- SafeHandle = safeHandle ;
270- Invoker = safeHandle . CreateInvoker ( ) ;
271-
272- if ( jnienv != null ) {
273- var env = new JniEnvironment ( jnienv , this ) ;
169+ if ( options . EnvironmentHandle != null ) {
170+ var env = new JniEnvironment ( options . EnvironmentHandle , this ) ;
274171 Environments . TryAdd ( env . SafeHandle . DangerousGetHandle ( ) , env ) ;
275172 }
276173
@@ -301,10 +198,10 @@ protected virtual void Dispose (bool disposing)
301198 current = null ;
302199
303200 ClearTrackedReferences ( ) ;
304- if ( DestroyVM )
305- DestroyJavaVM ( ) ;
306201 JavaVM _ ;
307202 JavaVMs . TryRemove ( SafeHandle . DangerousGetHandle ( ) , out _ ) ;
203+ if ( DestroyVM )
204+ DestroyJavaVM ( ) ;
308205 SafeHandle . Dispose ( ) ;
309206 SafeHandle = null ;
310207 }
0 commit comments