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

Ignore super class methods / Classloader issue #1070

Open
cmelchior opened this issue Jan 5, 2016 · 8 comments
Open

Ignore super class methods / Classloader issue #1070

cmelchior opened this issue Jan 5, 2016 · 8 comments

Comments

@cmelchior
Copy link

@cmelchior cmelchior commented Jan 5, 2016

Use case: POJO that extends a 3rd party base class. The base class contains a method whose return type is not available to the ClassLoader.

This seems related to: https://github.com/FasterXML/jackson-databind/pull/785/files and #861

It doesn't look like it is possible to ignore methods/super class methods, only fields using the AnnotationIntrospector.

Example using Realm (https://github.com/realm/realm-java):

public class Foo extends RealmObject {
  private String bar;
  public void setBar(String bar) {
    this.bar = bar;
  }
  public String getBar() {
    return bar;
  }
}

The problematic method is asObservable() in RealmObject that returns an rx.Observable. RxJava is an optional dependency, so rx.Observable might not be available to the ClassLoader: https://github.com/realm/realm-java/blob/master/realm/realm-library/src/main/java/io/realm/RealmObject.java#L278-Lundefined

The stack trace from Jackson looks something like this:

java.lang.NoClassDefFoundError: rx.Observable
at libcore.reflect.InternalNames.getClass(InternalNames.java:55)
at java.lang.Class.getDexCacheType(Class.java:479)
at java.lang.reflect.ArtMethod.getDexCacheType(ArtMethod.java:191)
at java.lang.reflect.ArtMethod.getReturnType(ArtMethod.java:145)
at java.lang.reflect.Method.getReturnType(Method.java:184)
at java.lang.Class.getDeclaredMethods(Class.java:771)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass._findClassMethods(AnnotatedClass.java:1046)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass._addMemberMethods(AnnotatedClass.java:602)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass.resolveMemberMethods(AnnotatedClass.java:431)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass.memberMethods(AnnotatedClass.java:253)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addMethods(POJOPropertiesCollector.java:477)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:284)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:248)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:155)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:142)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:217)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:333)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:315)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:254)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:222)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:142)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:403)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:461)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3838)
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3703)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2005)
at co.moonmonkeylabs.realmsearchview.example.MainActivity.loadBlogData(MainActivity.java:75)

Right now the only fix seems to be to create a dummy rx.Observable class that is empty, but maybe I am missing some configuration?

@cowtowncoder
Copy link
Member

@cowtowncoder cowtowncoder commented Jan 5, 2016

The problem here is that the exception is thrown from very low level code, before actual annotation introspection occurs. So nothing in configuration would help, yet, as Jackson core is simply trying to make sense of methods and fields a Class has.

I wish I had good suggestions for how to tackle the issue. I guess fundamentally it might be possible to add some sort of extension to allow any processing of contents of specific types, similar to existing "ignorable types" (which is used to ignore properties of those types), but applied differently. Sort of like "ignorable parent types".

Other short-term work arounds would involve overriding methods in POJOPropertiesCollector (that is, sub-classing it, replacing with custom one), but since that is not designed as an extension point, I am not sure if that would work easily.

One other alternative would be to add generic MapperFeature for preventing inspection of parent types, at least for deserialization (for Serialization this would be unlikely to work well -- many JDK types have concrete type that only has a small subset of methods needed). But I am not sure whether it would work well in practice.
A combination of sorts would be to have an annotation that would indicate something like "Stop investigating parent types" on Class; or perhaps optionally even list parent types to ignore.
One challenge here is regarding access to annotation inspection; code that gets in trouble occurs before annotation inspection should occur (I think).

@aldodevs
Copy link

@aldodevs aldodevs commented Jun 7, 2016

+1

@BasanthVerma
Copy link

@BasanthVerma BasanthVerma commented Dec 23, 2016

++

@AAverin
Copy link

@AAverin AAverin commented Apr 4, 2017

Have the same exception happening only on Android 5.0.1/5.1.1.
Seems to be related to Jackson

@grennis
Copy link

@grennis grennis commented Jun 13, 2017

Just defining a dummy class as recommended isn't enough anymore, now I also need the OnSubscribe interface like this:

package rx;

public class Observable {
    public interface OnSubscribe {
    }
}

This is making me very nervous, would love a proper fix.

@GitHubMurt
Copy link

@GitHubMurt GitHubMurt commented Jul 18, 2017

It happends me on Nougat and Marshmallow as well

@rogerioit
Copy link

@rogerioit rogerioit commented Oct 9, 2017

Can someone take a look at this problem?!

It really bothers me to create an empty class and define an empty interface.

Thanks in advance.

@cowtowncoder
Copy link
Member

@cowtowncoder cowtowncoder commented Oct 9, 2017

@rogerioit Feel free to go ahead and figure out potential solution if you have itch here.

No one has proposed valid solution here yet, or, the usual starting point, unit test to reproduce the issue. Without one fixes are difficult to verify.
This is not a bug to fix, per se -- if system tries to load a class that refers to another class not found in classpath, it is quite natural that problems occur. It would be nice to have a way to handle this gracefully but it is not clear how this should be approached.
Asking for someone to solve this will not get you very far.

FunkyMuse pushed a commit to FunkyMuse/Regalia that referenced this issue Feb 21, 2020
Updated to work with the latest moshi that relies on Reflection

Tests are not working due to:
FasterXML/jackson-databind#1070
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants