Commit c8f3e51
committed
[Java.Interop] Java
The Java Native Interface Functions [0] mostly covers calling Java
code *from* non-Java code, e.g. JNIEnv::CallVoidMethod() can be used
to call all Java instance methods which have a `void` return type.
What about the calling non-Java code from Java? That can't be *fully*
done through the JNIEnv type; it also requires cooperation with Java
bytecode, though the use of `native` method declarations [1]:
// Java
class Example {
public native void m ();
}
Before Java code can invoke the Example.m() instance method, that
method must first be *registered* via JNIEnv::RegisterNatives() [2].
What we have, then, is a two step process:
1. Write/generate/otherwise obtain Java bytecode with `native` method
declarations.
2. At runtime, "somehow" ensure that the native methods declared in
(1) are *registered* before they are first used from Java.
To date, JNIEnv::RegisterNatives() has been used in numerous places in
Java.Interop via JniType.RegisterNativeMethods() -- e.g. the
JavaProxyObject static constructor -- but the current architecture
doesn't support (2), as there is no way to *ensure* that e.g.
JavaProxyObject registers its native methods before Java invokes them.
(Normal use would preclude that, but if someone uses Reflection to
create a JavaProxyObject instance...)
How do we ensure that "something" -- native method registration --
happens before anything important is done with the Java type? By using
Java static initalizers, and introducing the new
com.xamarin.java_interop.ManagedPeer.registerNativeMembers() method:
class Example {
static final String assemblyQualifiedName = "Example, ...";
static {
com.xamarin.java_interop.ManagedPeer.registerNativeMembers (
Example.class,
assemblyQualifiedName,
"method-blob"
);
}
}
ManagedPeer.registerNativeMembers() will call into managed code and
(eventually) call JNIEnv::RegisterNatives() for the Java type.
Next important question: How does ManagedPeer.registerNativeMembers()
*actually* register the native methods?
Additionally, this mechanism needs to help support the future desired
Ahead-Of-Time (AOT) compilation mechanism of jnimarshalmethod-gen
(176240d).
The answer is the new
JniRuntime.JniTypeManager.RegisterNativeMembers() virtual method.
The default implementation will do the following:
1. Lookup the assembly to use.
1.a: Check to see if there is a corresponding -JniMarshalMethods
assembly, as generated by jnimarshalmethod-gen.
For example, if the type to register is in Example.dll, then the
assembly Example-JniMarshalMethods.dll will be loaded.
1.b: If (1.a) fails, then use the assembly that contains the
Type being registered -- the assemblyQualifiedName parameter
provided to ManagedPeer.registerNativeMembers().
2. Lookup the type to use, which is the type's FullName resolved
from the assembly found in (1).
3. Look for the __RegisterNativeMembers() method on the type from (2)
and invoke it, passing the JniType which corresponds to the Java
class to register, and the "method-blob" value.
For example, when registering methods for the Example type in
Example.dll, the following methods will be searched for, and the first
method found will be invoked:
Example.__RegisterNativeMembers() from Example-JniMarshalMethods.dll
Example.__RegisterNativeMembers() from Example.dll
If no such __RegisterNativeMembers() method is found, we bail.
JniRuntime.JniTypeManager subclasses may do something else. For
example, Xamairn.Android could (will?) process the "method-blob"
string as it normally does within JNIEnv.RegisterJniNatives().
The benefit of this architecture is that it allows "normal user"
assemblies to be post-processed to emit the -JniMarshalMethods
assembly, and use *that* for method registration at runtime.
This in turn avoids the need to emit marshaling code at runtime, as
marshaling code was previously emitted.
[0]: http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html
[1]: http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#compiling_loading_and_linking_native_methods
[2]: http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNativesnative method registration1 parent fcfa22b commit c8f3e51
File tree
17 files changed
+224
-15
lines changed- src
- Java.Interop.Export/Tests
- Java.Interop
- java/com/xamarin/interop/export
- Java.Interop
- Java.Interop
- Tests
- Java.Interop
- java/com/xamarin/interop
- java/com/xamarin/java_interop
- internal
- tools/jnimarshalmethod-gen
17 files changed
+224
-15
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
13 | 21 | | |
14 | 22 | | |
15 | 23 | | |
| |||
Lines changed: 0 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
38 | 36 | | |
39 | 37 | | |
40 | 38 | | |
| |||
Lines changed: 27 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
4 | 18 | | |
5 | 19 | | |
6 | 20 | | |
| |||
30 | 44 | | |
31 | 45 | | |
32 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
33 | 59 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
10 | 14 | | |
11 | 15 | | |
12 | 16 | | |
| |||
Lines changed: 45 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
174 | 175 | | |
175 | 176 | | |
176 | 177 | | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
177 | 222 | | |
178 | 223 | | |
179 | 224 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
24 | 31 | | |
25 | 32 | | |
26 | 33 | | |
| |||
30 | 37 | | |
31 | 38 | | |
32 | 39 | | |
33 | | - | |
| 40 | + | |
34 | 41 | | |
35 | 42 | | |
36 | 43 | | |
| |||
170 | 177 | | |
171 | 178 | | |
172 | 179 | | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
173 | 210 | | |
174 | 211 | | |
175 | 212 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
0 commit comments