[dotnet11 preview 6] ClientWebSocket doesn't work with NativeAOT on Android
- Dominant language
- C#
- Stars
- 23.3k
- Forks
- 2k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 290
Description
### Description
ClientWebSocket works correctly when the application is built and run with standard CoreCLR (without PublishAot enabled). However, when the application is built and run with `PublishAot=true`, it fails at runtime with an error indicating a missing JNI implementation related to certificate handling:
'No implementation found for
boolean net.dot.android.crypto.DotnetProxyTrustManager.verifyRemoteCertificate (...)'
I have not tested other WebSocket endpoints yet, but since the same code works correctly without AOT enabled, I suspect the issue is related to NativeAOT.
The issue also reproduces on Android with .NET 11 Preview 4 and Preview 5 withNativeAot enabled
The same functionality works correctly:
- on Android with the older Mono AOT runtime,
- on Windows in a Release build.
The sample project was created using `dotnet new maui`. I manually removed the iOS/macOS-related entries and added a minimal `ClientWebSocket` usage example to reproduce the issue.
I tested it on device with Android 14 and emulator with android 17.
dotnet --info
```
.NET SDK:
Version: 11.0.100-preview.6.26359.118
Commit: ba53d0ed33
Workload version: 11.0.100-preview.6.26364.2
MSBuild version: 18.9.0-preview-26359-118+ba53d0ed3
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26200
OS Platform: Windows
RID: win-x64
Base Path: d:\dev\envs\dotnet\dotnet11\sdk\11.0.100-preview.6.26359.118\
.NET workloads installed:
[maui-android]
Installation Source: SDK 11.0.100-preview.6
Manifest Version: 11.0.0-preview.6.26360.8/11.0.100-preview.6
Manifest Path: d:\dev\envs\dotnet\dotnet11\sdk-manifests\11.0.100-preview.6\microsoft.net.sdk.maui\11.0.0-preview.6.26360.8\WorkloadManifest.json
Install Type: FileBased
[maui-windows]
Installation Source: SDK 11.0.100-preview.6
Manifest Version: 11.0.0-preview.6.26360.8/11.0.100-preview.6
Manifest Path: d:\dev\envs\dotnet\dotnet11\sdk-manifests\11.0.100-preview.6\microsoft.net.sdk.maui\11.0.0-preview.6.26360.8\WorkloadManifest.json
Install Type: FileBased
Configured to use workload sets when installing new manifests.
Host:
Version: 11.0.0-preview.6.26359.118
Architecture: x64
Commit: ba53d0ed33
.NET SDKs installed:
11.0.100-preview.6.26359.118 [d:\dev\envs\dotnet\dotnet11\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 11.0.0-preview.6.26359.118 [d:\dev\envs\dotnet\dotnet11\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 11.0.0-preview.6.26359.118 [d:\dev\envs\dotnet\dotnet11\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 11.0.0-preview.6.26359.118 [d:\dev\envs\dotnet\dotnet11\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
None
Environment variables:
DOTNET_ROOT [d:/dev/envs/dotnet/dotnet11]
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
`https://aka.ms/dotnet/download`
```
### Steps to Reproduce
1. run attached project targeting android device or emulator with PublishAot = true (it is set in mauiaot.csproj)
2. observe logcat and there will be error: no implementation found for ... (log added in section below)
3. if run with PublishAot = false everything works.
[mauiaot.zip](https://github.com/user-attachments/files/30049509/mauiaot.zip)
### Link to public reproduction project repository
https://github.com/user-attachments/files/30049509/mauiaot.zip
### Version with bug
11.0.0-preview.5
### Is this a regression from previous behavior?
Not sure, did not test other versions
### Last version that worked well
Unknown/Other
### Affected platforms
Android
### Affected platform versions
dotnet 11 preview6, testing on device Android 14 and android emulator with android 17.1
### Did you find any workaround?
It works on Android with PublishAot = false, and older sdk with Mono Aot
### Relevant log output
```shell
logcat:
07-15 14:55:21.453 9697 9725 E anyname.mauiaot: No implementation found for boolean net.dot.android.crypto.DotnetProxyTrustManager.verifyRemoteCertificate(long) (tried Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate and Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate__J) - is the library loaded, e.g. System.loadLibrary?
07-15 14:55:21.453 9697 9725 W System.err: java.lang.UnsatisfiedLinkError: No implementation found for boolean net.dot.android.crypto.DotnetProxyTrustManager.verifyRemoteCertificate(long) (tried Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate and Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate__J) - is the library loaded, e.g. System.loadLibrary?
07-15 14:55:21.453 9697 9725 W System.err: at net.dot.android.crypto.DotnetProxyTrustManager.verifyRemoteCertificate(Native Method)
07-15 14:55:21.453 9697 9725 W System.err: at net.dot.android.crypto.DotnetProxyTrustManager.checkServerTrusted(DotnetProxyTrustManager.java:32)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:339)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.verifyCertificateChain(ConscryptEngine.java:1560)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:685)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:997)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataHeap(ConscryptEngine.java:1017)
07-15 14:55:21.453 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:989)
07-15 14:55:21.454 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:776)
07-15 14:55:21.454 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:647)
07-15 14:55:21.454 9697 9725 W System.err: at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:612)
07-15 14:55:21.454 9697 9725 W System.err: at com.android.org.conscrypt.Java8EngineWrapper.unwrap(Java8EngineWrapper.java:223)
07-15 14:55:25.501 9697 9796 D ProfileInstaller: Installing profile for com.companyname.mauiaot
07-15 14:55:41.457 9697 9725 D DOTNET : DetachThreadFromJNI: Detaching thread from JNI
```
Contributor guide
Research direction
The reproduction is in the attached mauiaot.csproj project and uses ClientWebSocket on Android; start by running it with PublishAot=true and inspecting logcat for DotnetProxyTrustManager.verifyRemoteCertificate. Compare with PublishAot=false and confirm that the WebSocket connection and certificate handling work under NativeAOT without the JNI implementation error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, csharp
- Domain
- mobile-dev, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100