Skip to content

.NET11 RC2 AndroidTypeMapImplementation trimmable doesn't generate java callable wrappers for classes marked with Register attribute #13205

Open

Description

@pramitp

We have been using Register attribute on Java.Lang.Object derived classes and Export attribute on its methods to generate Java callable wrappers for Android. E.g.

[Register("AndroidFeatures.FeaturesLib")]
public class FeaturesLib : Java.Lang.Object
{
    private MutableLiveData _data = new MutableLiveData(new Intent());
    
    [Export("Initialize")]
    public void Initialize(MutableLiveData data)
    {
        _data = data;
    }
    
    [Export("GetFeatureStr")]
    public string GetFeatureStr(string jString)
    {
        return jString;
    }

    [Export("GetDigitalValue")]
    public int GetDigitalValue()
    {
        return -999;
    }
}

I tried to use .NET11's new trimmable typemap using trimmable. The resulting build output doesn't contain the Java callable wrappers for the classes.

Can this be addressed?
@jonathanpeppers

Activity

  1. changed the title [-].NET11 RC2 AndroidTypeMapImplementation trimmable removes callable wrappers for classes marked with Register attribute[/-] [+].NET11 RC2 AndroidTypeMapImplementation trimmable doesn't generate java callable wrappers for classes marked with Register attribute[/+] on Oct 19, 2026
  2. dotnet-policy-service commented on Oct 19, 2026

    @dotnet-policy-service

    Tagging subscribers to this area: @agocke, @dotnet/illink
    See info in area-owners.md if you want to be subscribed.

  3. simonrozsival commented on Oct 20, 2026

    @simonrozsival
    Member

    Hey @pramitp, thanks for reporting this issue. I'll have a look today. What you're describing should work and I'll see if I can reproduce this on my side based on your report first.

  4. simonrozsival commented on Oct 20, 2026

    @simonrozsival
    Member

    I tried the same [Register("AndroidFeatures.FeaturesLib")] type and all three [Export] methods, including the MutableLiveData parameter. The trimmable typemap generator produced the expected Java callable wrapper:

    obj/<Configuration>/net11.0-android/typemap/java/AndroidFeatures/FeaturesLib.java

    The generated file contained Initialize(MutableLiveData), GetFeatureStr(String), GetDigitalValue(), and their corresponding native callbacks. Note that trimmable typemap JCWs are generated under typemap/java, rather than the legacy Java source directory.

    Could you check whether the wrapper exists at that location? If it is absent, could you share:

    • The output of dotnet --info and dotnet workload list
    • A binary log from dotnet build -bl:build.binlog
    • A minimal project reproducing the issue, including the obj directory produced by the failing build

    That should help us determine whether this depends on the exact RC2 workload build, another project setting, or a referenced assembly.

  5. added this to the .NET 11 milestone on Oct 20, 2026
  6. dotnet-policy-service commented on Oct 20, 2026

    @dotnet-policy-service

    Hi @pramitp. We have added the "need-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

  7. simonrozsival commented on Oct 20, 2026

    @simonrozsival
    Member

    I did an additional APK-level test to verify that the generated Java callable wrapper is not only emitted under obj, but is also compiled into classes.dex and can successfully call back into managed code at runtime.

    The test app contained these files:

    • FeaturesLib.cs — the reported shape, using [Register ("AndroidFeatures.FeaturesLib")] and exported Initialize, GetFeatureStr, and GetDigitalValue methods. GetFeatureStr returns its input and GetDigitalValue returns -999.

    • MutableLiveData.cs — a minimal managed Java peer registered as androidx/lifecycle/MutableLiveData. This preserved the JNI signature from the report without requiring the full AndroidX dependency graph in this manually wired test app. I had already separately verified generation using the actual AndroidX MutableLiveData type.

    • MainActivity.java — a handwritten Java launcher activity which does the following:

      FeaturesLib features = new FeaturesLib ();
      String text = features.GetFeatureStr ("called from Java");
      int value = features.GetDigitalValue ();
      Log.i ("Issue13205", text + "; value=" + value);
    • AndroidManifest.xml — declares com.example.issue13205.MainActivity as the launcher activity.

    • Issue13205.csproj — includes the two C# files, the Java source via AndroidJavaSource, and the manifest. The relevant settings were:

      <RuntimeIdentifier>android-arm64</RuntimeIdentifier>
      <EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
      <AndroidLinkMode>None</AndroidLinkMode>
      <AndroidTypeMapImplementation>trimmable</AndroidTypeMapImplementation>
      <UseMonoRuntime>false</UseMonoRuntime>

    My local development workload registration was incomplete, so this particular project manually imported the locally built .NET/Android SDK targets and injected the matching CoreCLR and Android runtime-pack assets. That extra wiring is specific to my local SDK checkout and should not be necessary in a normal installed-workload project.

    I built and signed it with the locally built SDK using:

    ./dotnet-local.sh build /path/to/Issue13205.csproj \
      -t:Build,SignAndroidPackage \
      -c Debug \
      -p:MSBuildEnableWorkloadResolver=false

    The build succeeded. I then extracted classes.dex from the signed APK and inspected it with Android build-tools dexdump. It contained:

    LAndroidFeatures/FeaturesLib;
      GetDigitalValue
      GetFeatureStr
      Initialize
      n_GetDigitalValue
      n_GetFeatureStr
      n_Initialize
    
    Lcom/example/issue13205/MainActivity;
      onCreate
    

    Finally, I installed the signed APK on an arm64 emulator and launched the Java activity. The Java code successfully constructed the generated FeaturesLib wrapper and invoked the managed exported methods. Logcat showed:

    I/Issue13205: called from Java; value=-999
    

    The app remained running without a crash. So in this test the wrapper was generated, included in the final APK's classes.dex, registered with the runtime, and successfully callable from handwritten Java code.

  8. pramitp commented on Oct 20, 2026

    @pramitp
    Author

    Thanks @simonrozsival
    I was earlier looking inside android/src. That explains why I didn't see any Java callable wrappers. I see the wrappers under typemap/java and typemap/linked-java.
    It looks like if I use trimmer then the trimmed version of wrappers go under typemap/linked-java. I noticed that when I set TrimMode to full it doesn't produce wrappers under typemap/linked-java.
    It works fine if I use TrimMode of partial.

  9. added
    need-attentionA xamarin-android contributor needs to review
    and removed
    need-infoIssues that need more information from the author.
    on Oct 20, 2026
  10. simonrozsival commented on Oct 20, 2026

    @simonrozsival
    Member

    I noticed that when I set TrimMode to full it doesn't produce wrappers under typemap/linked-java.
    It works fine if I use TrimMode of partial.

    Interesting. I will take a look. I'm wondering if the registered C# class is trimmed away.

  11. simonrozsival commented on Oct 22, 2026

    @simonrozsival
    Member

    Fixed in #13224

  12. pramitp commented on Oct 22, 2026

    @pramitp
    Author

    Thank you @simonrozsival! So this will be available in the release in Nov?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

need-attentionA xamarin-android contributor needs to reviewneeds-triageIssues that need to be assigned.

Type

No type

Projects

  • Status
    No status

Relationships

None yet

Development

No branches or pull requests

Issue actions