Skip to content
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

java.lang.NoClassDefFoundError: androidx/lifecycle/LifecycleOwner (J2X9001) #47

Closed
hadigityat opened this issue Jan 23, 2020 · 18 comments
Closed
Assignees

Comments

@hadigityat
Copy link

Xamarin.Android Version (eg: 6.0):

Xamarin.Android
Version: 10.1.3.7 (Visual Studio Community)
Commit: xamarin-android/d16-4/d66aed0

Operating System & Version (eg: Mac OSX 10.11):

Mac OS X 10.15.2
Darwin 19.2.0 Darwin Kernel Version 19.2.0

Support Libraries Version (eg: 23.3.0):

Xamarin.AndroidX.Lifecycle.Common(2.1.0-preview06)
also tried (2.1.0-rc1)

Describe your Issue:

JARTOXML: Warning J2X9001: Couldn't load class ...: java.lang.NoClassDefFoundError: androidx/lifecycle/LifecycleOwner (J2X9001)

JARTOXML: Warning J2XA006: missing class error was raised while reflecting ... : androidx/lifecycle/LifecycleOwner (J2XA006)

Steps to Reproduce (with link to sample solution if possible):

Create a xamarin bindings project and bind java lib using jar2xml

Include any relevant Exception Stack traces, build logs, adb logs:

@moljac moljac self-assigned this Jan 23, 2020
@moljac
Copy link
Contributor

moljac commented Jan 23, 2020

@hadigityat
Investigating generated code.

Another one:
Could you try using class-parse instead of jar2xml?

@hadigityat
Copy link
Author

@moljac
Thanks for investigating the issue, I have tried class-parse but it results in even more classes being skipped due to generic types and protected/private classes, methods etc. and changing attributes in metadata doesn't help in many cases.

It doesn't complain about the LifecycleOwner class when using class-parse but is it because class-parse is using bytecode directly?

@moljac
Copy link
Contributor

moljac commented Jan 23, 2020

@hadigityat
So, you are doing your own bindings?

I think (if I recall correctly) that jar2xml is using java reflection and class-parse parses bytecode via C#/.NET.

@moljac
Copy link
Contributor

moljac commented Jan 23, 2020

java LifecycleOwner is ILifecycleOwner in .Net.

Can you disable linking?

@hadigityat
Copy link
Author

@moljac
That is correct. But I am not binding my own library, so I can't make changes to the native code.

Bindings project doesn't allow you to change the linking through project options. How can I disable it?

@moljac
Copy link
Contributor

moljac commented Jan 24, 2020

@hadigityat

Do you have application? Unit tests?
When do you get java.lang.NoClassDefFoundError?

I think I'll need minimal repro sample for this issue.

@hadigityat
Copy link
Author

@moljac

I get it when I create a Bindings Library and build the project with an aar file. No unit tests.

Not sure if I can share the code, it is a third party library. The interesting thing is I do not see LifeCycleOwner being referenced anywhere. I just few other builds and the lifecycle warnings are gone.

Would the LifecycleOwner vs ILifecycleOwner create issues?

@moljac
Copy link
Contributor

moljac commented Jan 26, 2020

@hadigityat

Would the LifecycleOwner vs ILifecycleOwner create issues?

LifecycleOwner is java interface and in .NET we rename it to ILifecycleOwner

https://developer.android.com/reference/androidx/lifecycle/LifecycleOwner

Not sure if I can share the code, it is a third party library.

I get it, but it would be easier to analyze.

The interesting thing is I do not see LifeCycleOwner being referenced anywhere

Library could use it (in java world).

If you cannot provide sample I will have to close this issue.

@moljac
Copy link
Contributor

moljac commented Feb 3, 2020

@hadigityat

We are preparing stable release. If this issue persist create new one and provide minimal sample (maybe private repo if you want).

@moljac moljac closed this as completed Feb 3, 2020
@matheusouz
Copy link

I am having this problem too. I'm trying to port a library made on AndroidX and I'm getting this error.

JARTOXML: Warning J2X9001: Couldn't load class com/combateafraude/documentdetector/DocumentDetectorActivity : java.lang.NoClassDefFoundError: androidx/lifecycle/LifecycleOwner

@matheusouz
Copy link

matheusouz commented Feb 14, 2020

Archive.zip
Its here the sample project, its just run to simulate the error.

@moljac

@moljac
Copy link
Contributor

moljac commented Feb 14, 2020

@matheussouza97
This Archive.zip contains only bindings project and is not migrated to AndroidX. Am I right?

@moljac
Copy link
Contributor

moljac commented Feb 14, 2020

forget it. My bad. Wrong project. Too much to do.

@moljac
Copy link
Contributor

moljac commented Feb 14, 2020

I cannot repro this issue:

Xamarin.Android
Version: 10.2.0.84 (Visual Studio Community)
Commit: xamarin-android/d16-5/ac3f71f
Android SDK: /Users/Shared/Projects/d/system-installed/macosx/sdk
	Supported Android versions:
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
		5.1    (API level 22)
		6.0    (API level 23)
		7.0    (API level 24)
		7.1    (API level 25)
		8.0    (API level 26)
		8.1    (API level 27)

SDK Tools Version: 26.1.1
SDK Platform Tools Version: 29.0.5
SDK Build Tools Version: 29.0.2

Build Information: 
Mono: df42020
Java.Interop: xamarin/java.interop/d16-5@c0cc770
ProGuard: xamarin/proguard/master@905836d
SQLite: xamarin/sqlite/3.28.0@46204c4
Xamarin.Android Tools: xamarin/xamarin-android-tools/master@9f4e

@moljac
Copy link
Contributor

moljac commented Feb 14, 2020

OK. Found it. But it is a warning. Does it produce a crash?

@jpobst Can you look at it, please? Repro sample is here.

@moljac
Copy link
Contributor

moljac commented Feb 14, 2020

@hadigityat @matheussouza97

Guys switch to class-parse do not use jar2xml

@jonpryor
Copy link
Member

@matheussouza97 wrote:

I am having this problem too. I'm trying to port a library made on AndroidX and I'm getting this error.

JARTOXML: Warning J2X9001: Couldn't load class com/combateafraude/documentdetector/DocumentDetectorActivity : java.lang.NoClassDefFoundError: androidx/lifecycle/LifecycleOwner

The problem is twofold:

  1. This project is using jar2xml:

    <AndroidClassParser>jar2xml</AndroidClassParser>
  2. In order for jar2xml to work, all types referenced must be "findable".

Look at the complete error message:

JARTOXML : warning J2X9001: Couldn't load class com/combateafraude/documentdetector/controller/DocumentDetectorController : java.lang.NoClassDefFoundError: com/combateafraude/helpers/camera/CameraHelperCallback [/Volumes/Xamarin-Work/tmp/gax-47/Binding.CAF.DocumentDetector.csproj]
  java.lang.NoClassDefFoundError: com/combateafraude/helpers/Helper$StatusCode (TaskId:62)
        at java.lang.Class.getDeclaredMethods0(Native Method) (TaskId:62)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) (TaskId:62)
        at java.lang.Class.getDeclaredMethods(Class.java:1975) (TaskId:62)
        at jar2xml.JavaClass.doAppendToDocument(JavaClass.java:635) (TaskId:62)
        at jar2xml.JavaClass.appendToDocument(JavaClass.java:561) (TaskId:62)
        at jar2xml.JavaPackage.appendToDocument(JavaPackage.java:72) (TaskId:62)
        at jar2xml.Start.main(Start.java:134) (TaskId:62)
  Caused by: java.lang.ClassNotFoundException: com.combateafraude.helpers.Helper$StatusCode (TaskId:62)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382) (TaskId:62)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424) (TaskId:62)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357) (TaskId:62)
        ... 7 more (TaskId:62)

In particular, note the Caused by line:

  Caused by: java.lang.ClassNotFoundException: com.combateafraude.helpers.Helper$StatusCode 

The problem is that jar2xml needs com.combateafraude.helpers.Helper$StatusCode to work, but it's not present:

% jar tf Jars/document-detector-1.0.0/classes.jar | grep Status
# no output

The fix is to use class-parse, which doesn't require that every possible dependency be available:

    <AndroidClassParser>class-parse</AndroidClassParser>

This has also been the default for new projects for...years? (Awhile.)

This allows com/combateafraude/documentdetector/controller/DocumentDetectorController to be found; obj/Debug/api.xml.class-parse contains:

    <class
      abstract="false"
      deprecated="not deprecated"
      jni-extends="Ljava/lang/Object;"
      extends="java.lang.Object"
      extends-generic-aware="java.lang.Object"
      final="false"
      name="DocumentDetectorController"
      jni-signature="Lcom/combateafraude/documentdetector/controller/DocumentDetectorController;"
      source-file-name=""
      static="false"
      visibility="public">
      <implements
        name="com.combateafraude.helpers.camera.CameraHelperCallback"
        name-generic-aware="com.combateafraude.helpers.camera.CameraHelperCallback"
        jni-type="Lcom/combateafraude/helpers/camera/CameraHelperCallback;" />
...

Unfortunately, that's not enough for it to be bound; we get a different build message:

Error while processing type '[Class] com.combateafraude.documentdetector.controller.DocumentDetectorController': Type 'com.combateafraude.helpers.camera.CameraHelperCallback' was not found.

This is the "same" error as with jar2xml, just "different": DocumentDetectorController implements CameraHelperCallback, but CameraHelperCallback could not be found. As such, we don't know what possible interface methods should be implemented. (Though this itself is arguably a bug; see dotnet/java-interop#371)

...then we hit other complexities ("bugs") in our toolchain, such that api.xml still lacks DocumentDetectorController, and api.xml is what's used by generator, not api.xml.class-parse.

Still, the J2X9001 warning isn't emitted...

@matheusouz
Copy link

Sorry for taking your time, switching to class-parse worked perfectly!

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

No branches or pull requests

4 participants