Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Java.Lang.ClassNotFoundException: Didn't find class "<..>" on path: DexPathList #10081

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kerams opened this issue Apr 26, 2025 · 9 comments · May be fixed by #10121
Open

Java.Lang.ClassNotFoundException: Didn't find class "<..>" on path: DexPathList #10081

kerams opened this issue Apr 26, 2025 · 9 comments · May be fixed by #10121
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. need-attention A xamarin-android contributor needs to review
Milestone

Comments

@kerams
Copy link

kerams commented Apr 26, 2025

Android framework version

net10.0-android (Preview)

Affected platform version

10.0.100-preview.3.25201.16

Description

I'm inheriting from MediaDataSource in order to play audio in Android.Media.MediaPlayer from an in-memory mp3.

internal class StreamMediaDataSource(byte[] data) : Android.Media.MediaDataSource
{
    // ...
}

It worked just fine with 10.0.100-preview.2.25164.34, but with 10.0.100-preview.3.25201.16 I now get an exception during the instantiation of this class:

Java.Lang.ClassNotFoundException: Didn't find class "crc64467b05f37239e7a6.StreamMediaDataSource" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]]
   at Java.Interop.JniEnvironment.Types.TryFindClass(String classname, Boolean throwOnError)
   at Java.Interop.JniType..ctor(String classname)
   at Java.Interop.JniPeerMembers.JniInstanceMethods..ctor(Type declaringType)
   at Java.Interop.JniPeerMembers.JniInstanceMethods.GetConstructorsForType(Type declaringType)
   at Java.Interop.JniPeerMembers.JniInstanceMethods.StartCreateInstance(String constructorSignature, Type declaringType, JniArgumentValue* parameters)
   at Android.Media.MediaDataSource..ctor()
   at Plugin.Maui.Audio.StreamMediaDataSource..ctor(Byte[] data)
   at Plugin.Maui.Audio.AudioPlayer.Play(Byte[] data)

If I use global.json to pin the SDK to Preview 2, the problem disappears.

Steps to Reproduce

I failed to reproduce it in an empty project, so at the moment I'm in the dark with respect to what exactly might be the thing that makes a difference.

@kerams kerams added Area: App Runtime Issues in `libmonodroid.so`. needs-triage Issues that need to be assigned. labels Apr 26, 2025
@grendello grendello added Area: App+Library Build Issues when building Library projects or Application projects. and removed Area: App Runtime Issues in `libmonodroid.so`. needs-triage Issues that need to be assigned. labels Apr 28, 2025
@jonathanpeppers
Copy link
Member

Can you share more of the code example on how StreamMediaDataSource is used? The top of the stacktrace shows Plugin.Maui.Audio.AudioPlayer.Play(Byte[] data), so can you share a more complete example? (sample app would be best)

Thanks!

@jonathanpeppers jonathanpeppers added the need-info Issues that need more information from the author. label Apr 28, 2025
@kerams
Copy link
Author

kerams commented Apr 28, 2025

This is the only call site, player is Android.Media.MediaPlayer.

public void Play(byte[] data)
{
	if (!(data?.Length > 0))
	{
		return;
	}

	player.Reset();
	player.SetDataSource(new StreamMediaDataSource(data));
	player.Prepare();
	player.Start();
	stopwatch.Restart();
	isPlaying = true;
}

This is located in a net10.0-android;net10.0-ios;net10.0 SingleProject assembly, in the same solution as the Avalonia Android entry project.

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels Apr 28, 2025
@jonathanpeppers
Copy link
Member

Is there some code in StreamMediaDataSource that sets up the byte[]?

@jonathanpeppers jonathanpeppers added this to the .NET 10 milestone Apr 28, 2025
@kerams
Copy link
Author

kerams commented Apr 28, 2025

I'm not sure what that means exactly

internal class StreamMediaDataSource(byte[] data) : MediaDataSource
{
    public override long Size => data.Length;

    public override int ReadAt(long position, byte[]? buffer, int offset, int size)
    {
        if (position >= data.Length)
            return -1;

        var toRead = Math.Min(size, data.Length - (int)position);
        data.AsSpan((int)position, toRead).CopyTo(buffer.AsSpan(offset, toRead));
        return toRead;
    }

    public override void Close() { }
}

@jonathanpeppers
Copy link
Member

I had some time to try to repro this, and I found Gerald has a sample using Plugin.Maui.Audio:

I found the "Stream Audio" button works fine on .NET 10 Preview 4 (unreleased nightly builds):

Image

Image

Is this sample similar enough to what you're doing here to cause the problem?

@jonathanpeppers jonathanpeppers added need-info Issues that need more information from the author. and removed need-attention A xamarin-android contributor needs to review labels May 5, 2025
@jonathanpeppers
Copy link
Member

Here were my changes to target .NET 10:

@kerams
Copy link
Author

kerams commented May 5, 2025

Thanks for looking into it. No, it's quite different. Mine is an Avalonia application where the shared and Android "shell" projects are F#. My modified version of Plugin.Maui.Audio is in the same solution and referenced by both projects. Guess I have no other choice but to start whittling the solution down until I have a small enough repro to share.

@dotnet-policy-service dotnet-policy-service bot added need-attention A xamarin-android contributor needs to review and removed need-info Issues that need more information from the author. labels May 5, 2025
@kerams
Copy link
Author

kerams commented May 5, 2025

Alright, here you go https://github.com/kerams/repro-and

When I run Mobile.Android in Debug in Pixel 7 Android 14 emulator, I see a toast message with the aforementioned exception after I press the play button.

When I switch to Preview 2, I get an expected error from the media player itself (input data is garbage).

jonpryor added a commit that referenced this issue May 7, 2025
Fixes: #10081
Fixes: #10118

Context: 18ca528
Context: dotnet/java-interop@5852e6e

dotnet/java-interop@5852e6e3 updated `JniEnviroment.Types.FindClass()`
to begin using [`Class.forName(String, bool, ClassLoader)`][0] to load
Java types instead of `ClassLoader.loadClass()`.

This broke type registration on non-Java threads under NativeAOT;
attempting to load a non-Android Java type from a managed thread:

	var t = new System.Threading.Thread(() => {
	    using var c = new ClassFromThisAssembly();
	});
	t.Start();
	t.Join();

would fail with a `ClassNotFoundException`:

	E NUnit   : Java.Lang.ClassNotFoundException: Didn't find class "from.NewManagedThreadOne" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]]
	E NUnit   :    at Java.Interop.JniEnvironment.Types.TryFindClass(String, Boolean) + 0x3f4
	E NUnit   :    at Java.Interop.JniPeerMembers.JniInstanceMethods..ctor(Type) + 0x130
	E NUnit   :    at Java.Interop.JniPeerMembers.JniInstanceMethods.GetConstructorsForType(Type) + 0x94
	E NUnit   :    at Java.Interop.JniPeerMembers.JniInstanceMethods.StartCreateInstance(String, Type, JniArgumentValue*) + 0x1c
	E NUnit   :    at Java.Lang.Object..ctor() + 0x108
	E NUnit   :    at Java.InteropTests.JnienvTest.<>c__DisplayClass6_0.<RegisterTypeOnNewManagedThread>b__0() + 0x24
	E NUnit   :   --- End of managed Java.Lang.ClassNotFoundException stack trace ---
	E NUnit   : java.lang.ClassNotFoundException: Didn't find class "from.NewManagedThreadOne" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]]
	E NUnit   : 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
	E NUnit   : 	at java.lang.ClassLoader.loadClass(ClassLoader.java:637)
	E NUnit   : 	at java.lang.ClassLoader.loadClass(ClassLoader.java:573)

Fix this by setting `NativeAotRuntimeOptions.ClassLoader` to the
`context.getClassLoader()` value within
`NativeAotRuntimeProvider.attachInfo()`.  This ensures that we use
a `ClassLoader` that knows about the app's `classes.dex`.

[0]: https://developer.android.com/reference/java/lang/Class#forName(java.lang.String,%20boolean,%20java.lang.ClassLoader)
@jonpryor jonpryor linked a pull request May 7, 2025 that will close this issue
@jonathanpeppers
Copy link
Member

@kerams were you having this issue while using NativeAOT (PublishAot=true) or Mono (default settings)?

The sample looks like Mono:

If that's the case, #10121 won't fix this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. need-attention A xamarin-android contributor needs to review
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants