Closed akalghatgi closed 3 years ago
jar2xml
is deprecated and will be removed in .NET6
. It does not have the support we wrote for Kotlin in it, so it's not going to produce very good bindings to Kotlin libraries.
Most of the messages telling you why classes are not bound are not warnings, they are simply messages in the build log. You'll want to turn on Diagnostic build logging and then Rebuild (not just Build) your solution.
If you look in the Output Log you should see messages like:
Kotlin: Hiding internal class my.InternalClass
Which will tell you why types are not being bound.
@jpobst here is a part of Diagnostic logs
Error while processing '[Method] java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal temporal, long newValue)' in '[Class] java.time.temporal.ChronoField': Type 'java.time.temporal.Temporal' was not found.
Error while processing '[Method] java.time.temporal.Temporal addTo(java.time.temporal.Temporal temporal, long amount)' in '[Class] java.time.temporal.ChronoUnit': Type 'java.time.temporal.Temporal' was not found.
Error while processing '[Constructor] ContextDelegate.Companion(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)' in '[Class] com.vvvvvv.xxxxxx.ContextDelegate.Companion': Type 'kotlin.jvm.internal.DefaultConstructorMarker' was not found.
Error while processing '[Constructor] HttpRequest(int seen1, java.lang.String url, java.lang.String method, java.lang.String[] pinnedPublicKeys, int pinnedPublicKeyIndex, java.lang.String[] headers, java.lang.String body, kotlinx.serialization.SerializationConstructorMarker serializationConstructorMarker)' in '[Class] com.vvvvvv.xxxxxx.http.HttpRequest': Type 'kotlinx.serialization.SerializationConstructorMarker' was not found.
Error while processing type '[Class] com.vvvvvv.xxxxxx.http.HttpRequest..serializer': Type 'kotlinx.serialization.internal.GeneratedSerializer' was not found.
Error while processing '[Method] kotlinx.serialization.KSerializer<com.vvvvvv.xxxxxx.http.HttpRequest> serializer()' in '[Class] com.vvvvvv.xxxxxx.http.HttpRequest.Companion': Type 'kotlinx.serialization.KSerializer' was not found.
Error while processing '[Constructor] HttpRequest.Companion(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)' in '[Class] com.vvvvvv.xxxxxx.http.HttpRequest.Companion': Type 'kotlin.jvm.internal.DefaultConstructorMarker' was not found.
Error while processing '[Constructor] LoggerLevel.Companion(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker)' in '[Class] com.vvvvvv.xxxxxx.logger.LoggerLevel.Companion': Type 'kotlin.jvm.internal.DefaultConstructorMarker' was not found.
Done executing task "BindingsGenerator".
Are those the class-parse
or jar2xml
logs? What are the types that you are missing from the binding? If you search the log for those type names, do you find anything?
It is with class-parser
.. I don't see any other error. attaching the logs for your reference.
BindingLogs.txt
Type ,missing are HttpFunction, HttpRequest$Serializer etc...
From the logs, we hid HttpFunction
because it is an internal
class in Kotlin:
Kotlin: Hiding internal class com/vmware/chameleon/http/HttpFunction
It looks like HttpRequest$Serializer
caused a problem with our parser:
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variables array has 3 entries ('LocalVariableTableAttribute(LocalVariableTableEntry(Name='this', Descriptor='Lkotlinx/serialization/KSerializer;', StartPC=0, Index=0), LocalVariableTableEntry(Name='decoder', Descriptor='Lkotlinx/serialization/Decoder;', StartPC=0, Index=1), LocalVariableTableEntry(Name='old', Descriptor='Lcom/vmware/chameleon/http/HttpRequest;', StartPC=0, Index=2))'); descriptor has 2 entries!\
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variable type descriptor mismatch! Got 'Lkotlinx/serialization/Decoder;'; expected 'Lkotlinx/serialization/KSerializer;'.\
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variable type descriptor mismatch! Got 'Lcom/vmware/chameleon/http/HttpRequest;'; expected 'Lkotlinx/serialization/Decoder;'.\
If you can provide the .jar file we can take a look at what is causing that. But it also looks like it may be a private
/internal
class, in which case it won't be bound even if that gets fixed.
chameleon-android-1.1.0.zip here you go... rename it to .aar
Filed the HttpRequest$Serializer
issue as https://github.com/xamarin/java.interop/issues/788.
When
jar2xml
is selected following are the warnings but few extra classes are generated in binding.
What "extra classes" are present in the binding when $(AndroidClassParser)
=jar2xml? When I create a new binding project that only binds the classes.zip
at xamarin/java.interop#788 (which is the classes.jar
from chameleon-android-1.1.0.zip
), with a Build action of @(EmbeddedJar)
, more types are present in the binding when class-parse
is used vs jar2xml
:
% msbuild /p:AndroidClassParser=jar2xml /v:diag > b-j2x.txt
% mv obj obj.j2x
% mv bin bin.j2x
% msbuild /p:AndroidClassParser=class-parse /v:diag > b-cp.txt
% mv bin bin.cp
% mv obj obj.cp
% find obj.j2x -name \*.cs | wc -l
15
% find obj.cp -name \*.cs | wc -l
17
More C# files are generated when class-parse is used (17 vs 15).
% monodis --typedef bin.j2x/Debug/Scratch.Gji788.dll| wc -l
25
% monodis --typedef bin.cp/Debug/Scratch.Gji788.dll| wc -l
30
More types are present when using class-parse (30 vs 25).
The added types?
% monodis --typedef bin.cp/Debug/Scratch.Gji788.dll | awk '{print $2}' | sort > cp.txt
% monodis --typedef bin.j2x/Debug/Scratch.Gji788.dll | awk '{print $2}' | sort > j2x.txt
% diff -u j2x.txt cp.txt
--- j2x.txt 2021-02-02 20:42:57.000000000 -0500
+++ cp.txt 2021-02-02 20:42:46.000000000 -0500
@@ -3,6 +3,7 @@
Com.Vmware.Chameleon.BuildConfig
Com.Vmware.Chameleon.ChameleonApplication
Com.Vmware.Chameleon.ChameleonContextKt
+Com.Vmware.Chameleon.Configuration
Com.Vmware.Chameleon.ContextDelegate
Com.Vmware.Chameleon.Function.FunctionArg
Com.Vmware.Chameleon.Function.FunctionOutput
@@ -10,11 +11,15 @@
Com.Vmware.Chameleon.Function.IFunctionFactory
Com.Vmware.Chameleon.Function.IFunctionFactoryInvoker
Com.Vmware.Chameleon.Function.IFunctionInvoker
-Com.Vmware.Chameleon.Http.HttpResponse
+Com.Vmware.Chameleon.Http.HttpRequest
+Com.Vmware.Chameleon.Http.HttpRequest/Companion
+Com.Vmware.Chameleon.IChameleonContext
+Com.Vmware.Chameleon.IChameleonContextInvoker
Com.Vmware.Chameleon.Logger.ICustomLogger
Com.Vmware.Chameleon.Logger.ICustomLoggerInvoker
Com.Vmware.Chameleon.Logger.LoggerKt
Com.Vmware.Chameleon.Logger.LoggerLevel
+Com.Vmware.Chameleon.Logger.LoggerLevel/Companion
Java.Interop.__TypeRegistrations
Table
_JniMarshal_PPLLZ_L
While more types are generated, this does show an interesting absence, which may be what you're after: Com.Vmware.Chameleon.Http.HttpResponse
is present when using jar2xml but not class-parse.
Why?
Kotlin: Hiding internal class com/vmware/chameleon/http/HttpResponse (TaskId:35)
It's a public
class as far as Java and the JVM are concerned, but Kotlin wishes it to be an internal
type, and our binding system attempts to "appropriately bind". Thus, HttpResponse
isn't bound.
As the bindings are generated with class-parser there is should be proper errors/warning so that handling can be done properly for getting desired classes in binding.
I'm not entirely sure I understand what is being requested.
An interpretation is that all of the "Error" message emitted, such as those mentioned earlier -- which are currently treated as debug messages, not errors, as they do not appear as MSBuild warnings or errors -- should be displayed as MSBuild warnings or errors.
I am amenable to that suggestion. @jpobst would need to implement it. ;-)
Additionally, we do emit warnings, but you don't appear to like the ones emitted:
obj/Release/api.xml(433, 8) : warning BG8401: Skipping 'Com.vvvvvvv.xxxxxxxx.Http.HttpRequest.Companion' due to a duplicate nested type name. (Java type: 'com.vvvvvvv.xxxxxxxx.http.HttpRequest')
We should improve this warning so that it's actionable. Currently, it isn't directly actionable. A workaround is to rename the field, in Metadata.xml
:
<attr path="//class[@name='HttpRequest']/field[@name='Companion']" name="managedName">CompanionField</attr>
This removes the previous BG8401 warning, and updates the HttpRequest
binding to now contain an HttpRequest.CompanionField
field.
@akalghatgi mentioned:
Type ,missing are HttpFunction, HttpRequest$Serializer etc...
@jpobst addressed why HttpFunction
wasn't bound.
HttpRequest$$serializer
isn't bound because it contains unresolvable interfaces, and we currently skip types which implement interfaces we can't resolve; see also https://github.com/xamarin/java.interop/issues/359 and/or https://github.com/xamarin/java.interop/issues/371.
Error while processing type '[Class] com.vvvvvv.xxxxxx.http.HttpRequest..serializer': Type 'kotlinx.serialization.internal.GeneratedSerializer' was not found.
The interface type kotlinx.serialization.internal.GeneratedSerializer
is implemented by HttpRequest..serializer
, we don't know what it is, so it's skipped.
This can be fixed by "adding" kotlinx.serialization.internal.GeneratedSerializer
to the project, e.g. find the .jar
that defines it, and bind it, and then reference that binding from the chameleon-android-1.1.0.zip
binding…
Unfortunately, it can't be easily worked around via metadata, because HttpRequest..serializer
is not present within obj/Debug/api.xml
.
Alternatively, one could copy the mass of XML from api.xml.class-parse
into Metadata.xml
, as described here: https://github.com/xamarin/java.interop/issues/789
Note that generator
doesn't like type names with ..
in them, so managedName
must be added to give it a bindable name, a'la https://github.com/xamarin/java.interop/issues/789#issuecomment-772175314.
Even then, most of the members are skipped:
warning BG8700: Unknown return type kotlinx.serialization.KSerializer<?>[] in method ChildSerializers in managed type Com.Vmware.Chameleon.Http.HttpRequest._Serializer.
warning BG8800: Unknown parameter type kotlinx.serialization.Decoder in method Deserialize in managed type Com.Vmware.Chameleon.Http.HttpRequest._Serializer
…
After further investigation, I'm not sure why you want/need the HttpRequest$$serializer
type anyway; it appears to be a Kotlin compiler-generated type to support the @Serializable
annotation, and from the samples I could find in https://github.com/Kotlin/kotlinx.serialization, you're not expected to use that type.
"Not expected to use that type" in that there are only three instances of $serializer
in the repo:
% git grep '\$serializer'
README.md:-keep,includedescriptorclasses class com.yourcompany.yourpackage.**$$serializer { *; } # <-- change package name to your app's
core/commonMain/src/kotlinx/serialization/modules/SerializersModuleBuilders.kt: "attempted to register $serializer ($currentName)"
core/jvmMain/src/kotlinx/serialization/internal/Platform.kt: jClass.declaredClasses.singleOrNull { it.simpleName == ("\$serializer") }
None of those are for "normal" end-developer code. (Though README.md
contains ProGuard commands to preserve the $$serializer
types, which is a good idea…. But not code.)
@jonpryor For me when I bind using class-parser I don't see the classes you got with command line.
this is a extract from diagnostic logs..
Task "ClassParse"
Kotlin: Hiding internal class com/vmware/chameleon/http/HttpResponse
Kotlin: Hiding synthetic default constructor in class 'com/vmware/chameleon/Configuration' with signature '([CLjava/lang/String;Ljava/lang/String;[CLjava/lang/String;[CILkotlin/jvm/internal/DefaultConstructorMarker;)V'
Kotlin: Renaming setter parameter com/vmware/chameleon/Configuration - setKeyStoreLoc - <set-?> -> value
Kotlin: Renaming setter parameter com/vmware/chameleon/Configuration - setKeyStorePass - <set-?> -> value
Kotlin: Hiding internal getter method com/vmware/chameleon/Configuration - getModuleLibNames$chameleon_sdk_release
Kotlin: Renaming setter parameter com/vmware/chameleon/Configuration - setTrustStoreLoc - <set-?> -> value
Kotlin: Renaming setter parameter com/vmware/chameleon/Configuration - setTrustStorePass - <set-?> -> value
Kotlin: Hiding internal class com/vmware/chameleon/http/HttpFunction
Kotlin: Renaming parameter com/vmware/chameleon/function/FunctionFactory - create - p0 -> context
Kotlin: Hiding internal class com/vmware/chameleon/ContextDelegate$registerDefaultFunctions$1
Kotlin: Hiding nested internal type com/vmware/chameleon/ContextDelegate$registerDefaultFunctions$1
Kotlin: Renaming parameter com/vmware/chameleon/http/HttpRequest - equals - p0 -> other
Kotlin: Renaming setter parameter com/vmware/chameleon/http/HttpRequest - setBody - <set-?> -> value
Kotlin: Renaming setter parameter com/vmware/chameleon/http/HttpRequest - setHeaders - <set-?> -> value
Kotlin: Renaming setter parameter com/vmware/chameleon/http/HttpRequest - setPinnedPublicKeyIndex - <set-?> -> value
Kotlin: Renaming setter parameter com/vmware/chameleon/http/HttpRequest - setPinnedPublicKeys - <set-?> -> value
Kotlin: Hiding internal class com/vmware/chameleon/http/PublicKeyPinningTrustManager
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - chameleonContextCreate - p0 -> app
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - emitEvent - p0 -> eventId
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - emitEvent - p1 -> eventData
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - emitEvent - p2 -> isJSON
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - evaluateScript - p0 -> script
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - hasEvent - p0 -> eventId
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - registerFunction - p0 -> name
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - registerFunction - p1 -> factory
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - setResourcePathMapping - p0 -> prefix
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - setResourcePathMapping - p1 -> path
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - setStoragePathMapping - p0 -> prefix
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - setStoragePathMapping - p1 -> path
Kotlin: Renaming parameter com/vmware/chameleon/ChameleonContext - startChameleonContext - p0 -> config
Kotlin: Hiding internal class com/vmware/chameleon/http/SecureTlsSocketFactory
Kotlin: Renaming parameter com/vmware/chameleon/logger/CustomLogger - log - p0 -> level
Kotlin: Renaming parameter com/vmware/chameleon/logger/CustomLogger - log - p1 -> log
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variables array has 3 entries ('LocalVariableTableAttribute(LocalVariableTableEntry(Name='this', Descriptor='Lkotlinx/serialization/KSerializer;', StartPC=0, Index=0), LocalVariableTableEntry(Name='decoder', Descriptor='Lkotlinx/serialization/Decoder;', StartPC=0, Index=1), LocalVariableTableEntry(Name='old', Descriptor='Lcom/vmware/chameleon/http/HttpRequest;', StartPC=0, Index=2))'); descriptor has 2 entries!
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variable type descriptor mismatch! Got 'Lkotlinx/serialization/Decoder;'; expected 'Lkotlinx/serialization/KSerializer;'.
class-parse: method com/vmware/chameleon/http/HttpRequest$$serializer.patch(Lkotlinx/serialization/Decoder;Lcom/vmware/chameleon/http/HttpRequest;)Lcom/vmware/chameleon/http/HttpRequest;: Local variable type descriptor mismatch! Got 'Lcom/vmware/chameleon/http/HttpRequest;'; expected 'Lkotlinx/serialization/Decoder;'.
Done executing task "ClassParse".
Missing classes are HttpFunction,, SecureTlsSocketFactory, PublicKeyPinningTrustManager.
This library is a dependency to other Major library. I am only talking about this for convenience... but we have 15-16 Library with similar issues...
What you suggest to solveKotlin: Hiding internal class
?
Unfortunately there are not currently many good options for fixing Kotlin: Hiding internal class
. The "correct" way is to change the Kotlin code to not be internal
if you want to be able call it from outside the Kotlin library. As is, we are respecting the visibility that the Kotlin library author requested.
I filed issue https://github.com/xamarin/java.interop/issues/790 to allow users to modify the visibility of Kotlin internal
types using metadata
, but it will not be available until at least 16.10/8.10.
Other options are downgrading the version you are on, or trying to add the raw api.xml
data for the types/members using <add-node>
metadata.
How we can downgrade to 8.6 where it was building....? we tried add-node
but no success...
I don't know. I would try Googling it, surely it is possible.
@jbpost Why this was closed?
The root issue is https://github.com/xamarin/java.interop/issues/790, so this was closed in favor of that issue.
That issue has been fixed and is available in the 16.10/8.10 previews.
Stuck with compiling binding with no information binding failure
Binding was generated correctly with older versions but after upgrading to 8.8.6.15 bindings few of the classes are missing. When Class-parser is selected very few warnings, no exact error/warning for which class binding is not generated. If we select jar2xml most of the errors/warning are related to Kotlin.
When Class-parser is selected following are the warning. and important classes are missing from generated binding.
When jar2xml is selected following are the warnings but few extra classes are generated in binding.
Expected Behavior
As the bindings are generated with class-parser there is should be proper errors/warning so that handling can be done properly for getting desired classes in binding.
Actual Behavior
No error/warnings for not generating binding for the classes.
Version Information
=== Visual Studio Community 2019 for Mac (Preview) ===
Version 8.9 Preview (8.9 build 1451) Installation UUID: 7a99ac0f-2574-48b1-b44d-6ad8eabcabff GTK+ 2.24.23 (Raleigh theme) Xamarin.Mac 6.18.0.23 (d16-6 / 088c73638)
=== Mono Framework MDK ===
Runtime: Mono 6.12.0.113 (2020-02/4fdfb5b1fd5) (64-bit) Package version: 612000113
=== Roslyn (Language Service) ===
3.9.0-3.20619.14+df59a33fd9beff9790e01a2a1ab21e4a1e6921b3
=== NuGet ===
Version: 5.8.0.6860
=== .NET Core SDK ===
SDK: /usr/local/share/dotnet/sdk/5.0.102/Sdks SDK Versions: 5.0.102 5.0.101 5.0.100 3.1.405 3.1.404 3.1.403 3.1.402 2.1.811 2.1.809 MSBuild SDKs: /Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Sdks
=== .NET Core Runtime ===
Runtime: /usr/local/share/dotnet/dotnet Runtime Versions: 5.0.2 5.0.1 5.0.0 5.0.0-rc.2.20475.5 3.1.11 3.1.10 3.1.9 3.1.8 2.1.23 2.1.22 2.1.21
=== .NET Core 3.1 SDK ===
SDK: 3.1.405
=== Xamarin.Profiler ===
Version: 1.6.15.68 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
=== Updater ===
Version: 11
=== Xamarin.Android ===
Version: 11.2.0.0 (Visual Studio Community) Commit: xamarin-android/d16-9/f908d16 Android SDK: /Users/akalghatgi@xxxxxx.com/Library/Developer/Xamarin/android-sdk-macosx Supported Android versions: 8.1 (API level 27)
SDK Tools Version: 26.1.1 SDK Platform Tools Version: 30.0.4 SDK Build Tools Version: 30.0.2
Build Information: Mono: 5e9cb6d Java.Interop: xamarin/java.interop/d16-9@1d382be ProGuard: Guardsquare/proguard/v7.0.1@912d149 SQLite: xamarin/sqlite/3.32.2@cfe06e0 Xamarin.Android Tools: xamarin/xamarin-android-tools/main@ad80a42
=== Microsoft OpenJDK for Mobile ===
Java SDK: /Users/akalghatgi@xxxxxx.com/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_1.8.0.25 1.8.0-25 Android Designer EPL code available here: https://github.com/xamarin/AndroidDesigner.EPL
=== Android SDK Manager ===
Version: 16.9.0.21 Hash: 57e40ba Branch: remotes/origin/main Build date: 2021-01-08 01:57:14 UTC
=== Android Device Manager ===
Version: 16.9.0.14 Hash: 0fdccda Branch: remotes/origin/main Build date: 2021-01-08 01:57:36 UTC
=== Xamarin Designer ===
Version: 16.9.0.266 Hash: c4842c761 Branch: remotes/origin/c4842c761b9b6a95407f72278ca7fb42f8f7fdf0 Build date: 2021-01-07 06:17:08 UTC
=== Apple Developer Tools ===
Xcode 12.1 (17222) Build 12A7403
=== Xamarin.Mac ===
Version: 7.3.0.27 (Visual Studio Community) Hash: f4c9327fa Branch: main Build date: 2020-11-19 10:57:31-0500
=== Xamarin.iOS ===
Version: 14.9.0.27 (Visual Studio Community) Hash: f4c9327fa Branch: main Build date: 2020-11-19 10:57:31-0500
=== Build Information ===
Release ID: 809001451 Git revision: cfd15313a6388ef8dada0182e22a058131c46f9d Build date: 2021-01-15 08:42:21-05 Build branch: release-8.9 Xamarin extensions: cfd15313a6388ef8dada0182e22a058131c46f9d
=== Operating System ===
Mac OS X 10.15.7 Darwin 19.6.0 Darwin Kernel Version 19.6.0 Thu Oct 29 22:56:45 PDT 2020 root:xnu-6153.141.2.2~1/RELEASE_X86_64 x86_64
@jonathanpeppers needed your guidance on this.