Skip to content

.NET 10 Android: DexGuard-protected AAR fails to load encrypted classes (regression from .NET 9) #10615

@seth-govalidate

Description

@seth-govalidate

Full transparency, I had Cursor / AI generate issue content to match this template and a repro project to hopefully provide better information and speed up the process for you.

Android framework version

net10.0-android (Preview)

Affected platform version

.NET Version: 10.0.100 (fails), 9.0.306 (works) Android SDK: API 21-36 (tested multiple versions) MAUI Version: 10.0.0/10.0.100 OS: macOS Darwin 25.1.0

Description

AAR files using DexGuard asset encryption fail to load dynamically-decrypted classes at runtime in .NET 10 Android. This is a regression - the same code and AAR work correctly in .NET 9.

The Problem

The FaceTec SDK (versions 9.7.79, 9.7.97) uses DexGuard to encrypt and protect their implementation. Some obfuscated classes are encrypted and stored in asset files, which should be dynamically decrypted and loaded at runtime by DexGuard's ClassLoader.

In .NET 9, this works perfectly. In .NET 10, the encrypted classes fail to load, causing immediate crashes.

Root Cause Evidence

The missing class doesn't exist in classes.jar:

unzip -p facetec-sdk-9.7.97.aar classes.jar | jar tf | grep "ipB21035"
# Result: (empty) - because it's encrypted in assets

The encrypted assets ARE in the AAR and APK:

unzip -l facetec-sdk-9.7.97.aar | grep "assets/com/facetec/sdk"
# Shows encrypted asset files: 8ece9efb0c7e6bd9a-, a5b5981bf398ec36b-, etc.

DexGuard configuration confirms asset encryption:

unzip -p facetec-sdk-9.7.97.aar dexguard.txt
# Shows:
# -encryptassetfiles !assets/com/facetec/sdk/...
# -keepresourcefiles assets/com/facetec/sdk/...

Steps to Reproduce

I've created a minimal reproduction project with complete setup files.

Reproduction Project Structure:

repro-net10-dexguard/
├── FaceTecNet10Repro.sln          # Solution with both projects
├── global.json                     # Pins SDK to 10.0.100
├── workload.json                   # Workload versions for reproducibility
├── FaceTecBinding/                 # Minimal Android binding
│   ├── FaceTecBinding.csproj       # IsTrimmable=false, TrimMode=copy
│   └── facetec-sdk-9.7.97.aar      # DexGuard-protected AAR (included)
└── FaceTecMinimalRepro/            # Multi-targeted MAUI app
    ├── FaceTecMinimalRepro.csproj  # Targets: net9.0-android + net10.0-android
    └── MainActivity.cs              # Simply references FaceTec type

Steps:

  1. Open the reproduction project:

    cd repro-net10-dexguard
    open FaceTecNet10Repro.sln
  2. Build and run with .NET 10:

    dotnet build -f net10.0-android
    dotnet publish -f net10.0-android
    # Install APK on device and launch

    Result: Immediate crash with ClassNotFoundException

  3. Build and run with .NET 9:

    dotnet build -f net9.0-android
    dotnet publish -f net9.0-android
    # Install APK on device and launch

    Result: Runs successfully, no crash

Expected Behavior

When running with .NET 10, the app should:

  • Load the FaceTec native library successfully
  • Decrypt and load DexGuard-protected classes from asset files at runtime
  • Initialize without errors (as it does in .NET 9)

Actual Behavior

With .NET 10, the app crashes immediately on launch:

JNI DETECTED ERROR IN APPLICATION: JNI RegisterNatives called with pending exception 
java.lang.ClassNotFoundException: Didn't find class "com.facetec.sdk.ipB21035" 
on path: DexPathList[[zip file "/data/app/.../base.apk"],nativeLibraryDirectories=[...]]
    at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String)
    at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean)
    at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String)
    at java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader, java.lang.Class)

The class com.facetec.sdk.ipB21035 is an obfuscated class name that exists only as an encrypted asset, not in the APK's DEX files.

facetec-net10-regression-repro.zip

Did you find any workaround?

No. We attempted all standard configurations:

  • IsTrimmable=false + TrimMode=copy in binding project
  • AndroidLinkMode=None (disabled linking completely)
  • AndroidEnableMultiDex=true
  • AndroidIncludeAllJavaLibraries=true
  • ✅ ProGuard/R8 keep rules for FaceTec classes
  • LinkDescription.xml to preserve assemblies

None of these configurations fixed the issue.

The only workaround is to stay on .NET 9.

Relevant log output

11-25 16:37:38.575 F/DEBUG (31893): Abort message: 'JNI DETECTED ERROR IN APPLICATION: JNI RegisterNatives called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.facetec.sdk.ipB21035" on path: DexPathList[[zip file "/data/app/~~pDs2zlceVA8osMf97aioIg==/com.appname-xJaTMS9iCm6pFTZctgYmgg==/base.apk"],nativeLibraryDirectories=[/data/app/~~pDs2zlceVA8osMf97aioIg==/com.appname-xJaTMS9iCm6pFTZctgYmgg==/lib/arm64, /data/app/~~pDs2zlceVA8osMf97aioIg==/com.appname-xJaTMS9iCm6pFTZctgYmgg==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
11-25 16:37:38.575 F/DEBUG (31893):     at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:259)
11-25 16:37:38.575 F/DEBUG (31893):     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:637)
11-25 16:37:38.575 F/DEBUG (31893):     at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:573)
11-25 16:37:38.575 F/DEBUG (31893):     at java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader, java.lang.Class) (Runtime.java:-2)

Metadata

Metadata

Labels

need-attentionA xamarin-android contributor needs to review

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions