-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Java.Base] Begin binding JDK-11 java.base module
Context: #858 What do *I* want? To be able to use our wonderful Java binding infrastructure against *Desktop Java*, not just Android. At the same time, I don't want "Android-isms" "leaking" into such a binding. *Just* Java.Interop, no xamarin-android. "Take over" the `generator --codegen-target=JavaInterop1` format so that it *isn't* useful for Xamarin.Android, and is instead usable for non-Android usage. This is a work-in-progress, and *far* from complete. For prototype purposes, this *only* binds: * `java.lang.Object` * `java.lang.Throwable` * `java.lang.Class` The `Java.Base` binding is only for .NET 6 and above. I'm not interested in .NET Standard support at this point in time. Update `samples/Hello` so that it (1) works, and (2) instantiates the `Java.Lang.Object` binding: dotnet run --project samples/Hello ~~ Binding changes vs. Xamarin.Android ~~ Java arrays are bound as appropriate `IList<T>`, using the `Java.Interop.Java*Array` types as an intermediary. This should help reduce marshaling logic & overhead, as if the "source" array is a `Java*Array`, it doesn't need to be "deep copied". The exception is C# `params` arrays, which continue to be bound as arrays, and are marshaled via an appropriate `Java*Array` type. `java.io.InputStream` isn't bound as `System.IO.Stream`, etc. "Java.Interop-style" constructors are used (25de1f3), e.g. // This DeclaringType (ref JniObjectReference reference, JniObjectReferenceOptions options); // Not Xamarin.Android-style DeclaringType (IntPtr handle, JniHandleOwnership transfer); "Java.Interop-style" wrapper construction is used, e.g. // This var wrapper = JniEnvironment.Runtime.ValueManager.GetValue<DeclaringType>(ref h, JniObjectReferenceOptions.CopyAndDispose); // Not this var wrapper = Java.Lang.Object.GetObject<DeclaringType>(handle); Marshal methods are currently skipped. Java-to-managed invocations are not currently supported. ~~ TODO: Marshal Methods? ~~ Xamarin.Android uses Java Callable Wrappers + `Runtime.register()` to specify which methods to register, via lots of reflection, etc. For Desktop, JCW's shouldn't have all the methods to register. Instead, use the `jnimarshalmethod-gen`-originated strategy of `[JniAddNativeMethodRegistrationAttribute]` within the binding, and then have it use `MarshalMethodBuilder` to generate the marshal methods. Need to update `MarshalMethodBuilder` to look for overrides in addition to methods with [`JavaCallable`], which in turn will require an equivalent to `Android.Runtime.RegisterAttribute(…)`. Perhaps `JniMethodSignatureAttribute(string name, string sig)`? In the meantime, `Java.Base` will skip all marshal-method logic plus runtime method generation. Leave that for later. ~~ TODO: Other API Changes? ~~ We should "unify" `java.lang.Object` and `System.Object`. Consider `java.lang.Class`: /* partial */ class Class<T> { public boolean isInstance(java.lang.Object); public java.lang.Object[] getSigners(); } If we unify `java.lang.Object` and `System.Object`, we'd have a binding of: partial class Class { public bool IsInstance (object value); public object[] GetSigners(); } ~~ Open Questions ~~ What's up with `java.lang.Class.getAnnotationsByType()`? During an iteration of this PR, I got: public unsafe Java.Interop.JavaObjectArray<Java.Lang.Object>? GetAnnotationsByType (Java.Lang.Class? annotationClass) { const string __id = "getAnnotationsByType.(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;"; From `__id` we see that the Java return type is `Annotation[]`, yet we bind it as an `Object` array? Why? How do we fix that to instead bind it as `JavaObjectArray<Java.Lang.Annotations.Annotation>`? Currently, it's differently *worse*; I don't know why, but `__id` is now: const string __id = "getAnnotationsByType.(Ljava/lang/Class;)[Ljava/lang/Object;"; i.e. the return type is an `Object` array instead of an `Annotation` array, which is wrong, as per `javap`: % javap -s java.lang.Class … public <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.Class<A>); descriptor: (Ljava/lang/Class;)Ljava/lang/annotation/Annotation; Fixing unit tests...
- Loading branch information
Showing
442 changed files
with
13,692 additions
and
4,399 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>net6.0</TargetFrameworks> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Java.Interop\Java.Interop.csproj" /> | ||
<ProjectReference Include="..\..\tools\class-parse.csproj" ReferenceOutputAssembly="False" /> | ||
<ProjectReference Include="..\..\tools\generator.csproj" ReferenceOutputAssembly="False" /> | ||
</ItemGroup> | ||
|
||
<Import Project="Java.Base.targets" /> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<Project> | ||
|
||
<PropertyGroup> | ||
<GeneratorPath>$(ToolOutputFullPath)generator.dll</GeneratorPath> | ||
</PropertyGroup> | ||
|
||
<Target Name="_GetJavaBaseJmodPath"> | ||
<PropertyGroup Condition=" '$(Java11SdkDirectory)' != '' "> | ||
<_JavaBaseJmod>$(Java11SdkDirectory)/jmods/java.base.jmod</_JavaBaseJmod> | ||
</PropertyGroup> | ||
</Target> | ||
|
||
<Target Name="_GenerateApiDescription" | ||
DependsOnTargets="_GetJavaBaseJmodPath" | ||
BeforeTargets="_GenerateBinding" | ||
Inputs="$(_JavaBaseJmod)" | ||
Outputs="$(IntermediateOutputPath)\mcw\api.xml"> | ||
<MakeDir Directories="$(IntermediateOutputPath)mcw" /> | ||
<PropertyGroup> | ||
<_ClassParse>"$(ToolOutputFullPath)class-parse.dll"</_ClassParse> | ||
<_Input>"$(_JavaBaseJmod)"</_Input> | ||
<_Output>"-o=$(IntermediateOutputPath)/mcw/api.xml"</_Output> | ||
</PropertyGroup> | ||
<Error | ||
Condition=" !Exists($(_JavaBaseJmod)) " | ||
Text="Could not find a JDK-11 installation directory" | ||
/> | ||
<Exec | ||
Command="$(DotnetToolPath) $(_ClassParse) $(_Input) $(_Output)" | ||
/> | ||
</Target> | ||
|
||
<ItemGroup> | ||
<_GenerateBindingInputs Include="$(GeneratorPath)" /> | ||
<_GenerateBindingInputs Include="$(MSBuildThisFileFullPath)" /> | ||
<_GenerateBindingInputs Include="Transforms\**" /> | ||
<_GenerateBindingInputs Include="$(IntermediateOutputPath)mcw\api.xml" /> | ||
</ItemGroup> | ||
|
||
<Target Name="_GenerateBinding" | ||
BeforeTargets="CoreCompile" | ||
Inputs="@(_GenerateBindingInputs)" | ||
Outputs="$(IntermediateOutputPath)mcw\Java.Base.projitems"> | ||
<MakeDir Directories="$(IntermediateOutputPath)mcw" /> | ||
<PropertyGroup> | ||
<Generator>"$(GeneratorPath)"</Generator> | ||
<_GenFlags>--public</_GenFlags> | ||
<_Out>-o "$(IntermediateOutputPath)mcw"</_Out> | ||
<_Codegen>--codegen-target=JavaInterop1</_Codegen> | ||
<_Fixup>--fixup=Transforms/Metadata.xml</_Fixup> | ||
<_Enums1>--preserve-enums --enumflags=Transforms/enumflags --enumfields=Transforms/map.csv --enummethods=Transforms/methodmap.csv</_Enums1> | ||
<_Enums2>--enummetadata=$(IntermediateOutputPath)mcw/enummetadata</_Enums2> | ||
<_Assembly>"--assembly=Java.Base"</_Assembly> | ||
<_TypeMap>--type-map-report=$(IntermediateOutputPath)mcw/type-mapping.txt</_TypeMap> | ||
<_Api>$(IntermediateOutputPath)mcw/api.xml</_Api> | ||
<_Dirs>--enumdir=$(IntermediateOutputPath)mcw</_Dirs> | ||
<_FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)'))</_FullIntermediateOutputPath> | ||
<_LangFeatures>--lang-features=nullable-reference-types,default-interface-methods,nested-interface-types,interface-constants</_LangFeatures> | ||
</PropertyGroup> | ||
<Exec | ||
Command="$(DotnetToolPath) $(Generator) $(_GenFlags) $(_ApiLevel) $(_Out) $(_Codegen) $(_Fixup) $(_Enums1) $(_Enums2) $(_Versions) $(_Annotations) $(_Assembly) $(_TypeMap) $(_LangFeatures) $(_Dirs) $(_Api) $(_WithJavadocXml)" | ||
IgnoreStandardErrorWarningFormat="True" | ||
/> | ||
<ItemGroup> | ||
<Compile Include="$(_FullIntermediateOutputPath)\mcw\**\*.cs" KeepDuplicates="False" /> | ||
</ItemGroup> | ||
<XmlPeek | ||
Namespaces="<Namespace Prefix='msbuild' Uri='http://schemas.microsoft.com/developer/msbuild/2003' />" | ||
XmlInputPath="$(IntermediateOutputPath)mcw\Java.Base.projitems" | ||
Query="/msbuild:Project/msbuild:PropertyGroup/msbuild:DefineConstants/text()" > | ||
<Output TaskParameter="Result" PropertyName="_GeneratedDefineConstants" /> | ||
</XmlPeek> | ||
<PropertyGroup> | ||
<DefineConstants>$(DefineConstants);$([System.String]::Copy('$(_GeneratedDefineConstants)').Replace ('%24(DefineConstants);', ''))</DefineConstants> | ||
</PropertyGroup> | ||
</Target> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Java.Interop; | ||
|
||
namespace Java.Lang { | ||
|
||
public partial class Object : JavaObject { | ||
|
||
public Object (ref JniObjectReference reference, JniObjectReferenceOptions options) | ||
: base (ref reference, options) | ||
{ | ||
} | ||
} | ||
} |
Oops, something went wrong.