19

I have 3rd party jar (which I can't change) that uses java.beans.Introspector, java.beans.BeanInfo and java.beans.PropertyDescriptor.

How can I use that jar in my android application?

It fails loading the class (which uses Introspector) from the 3th party jar:

WARN/dalvikvm(780): VFY: unable to resolve static method 6325: Ljava/beans/Introspector;.getBeanInfo (Ljava/lang/Class;)Ljava/beans/BeanInfo;
WARN/dalvikvm(780): VFY: unable to resolve exception class 962 (Ljava/beans/IntrospectionException;)
WARN/dalvikvm(780): Verifier rejected class Lorg/thirdpartyjar/SomeClass;
Seunghoon
  • 5,632
  • 5
  • 35
  • 41
Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • If changing the 3th party jar is allowed, it's possible to use [openbeans](http://code.google.com/p/openbeans/), although that's not available on [maven central](http://search.maven.org/#search|ga|1|openbeans). – Geoffrey De Smet Feb 25 '13 at 12:40
  • 2
    Looks like there is no workaround, so I 've created [an android issue to support java.beans](http://code.google.com/p/android/issues/detail?id=51642). – Geoffrey De Smet Mar 04 '13 at 12:27

2 Answers2

18

It's clear java.beans package is not complete on android. And common solution is to repackage both java.beans and jar dependent on them to use different package name instead of java.beans. This is exactly what previously mentioned openbeans do. And an interesting qoute from android error message states: If you find that you cannot do this, then that is an indication that the path you are on will ultimately lead to pain, suffering, grief, and lamentation.

To avoid this path i would start by looking into options of actually using openbeans and trying to force 3rd party into using those. From what your are writing it's not clear if jar can't be changed or is not allowed to be changed(you mention both). I don't know legal implications of changing jars, but technically it's always possible, e.g. trying reverse engineer classes, do some build time instrumentation with something like aspectj. If this is not allowed i think runtime instrumentation can be done, e.g. dexmaker can create proxy for your third party class, which is using java.beans and you can reimplement part of this class.

Also googling a little on the topic i saw this. They just use java.beans package and compile it for android. This seems fragile for me, but looks like it's working.

Unfortunately this is not a solution, just ideas i wanted to share. Hope you find those useful.

efan
  • 968
  • 6
  • 11
  • 2
    Interesting idea's btw. Android's official message is really shortsighted, as they basically prohibit the use of JSR standardized java libraries (such as JAXB, JAXRS, JPA, DI, ...). So basically importing javax.inject (used by google guice) doesn't work either? – Geoffrey De Smet Mar 05 '13 at 14:40
  • 2
    Thanks. Well, guice also uses com.google.inject. But i think you are probably right as googling shows people just use --core-library option ignoring warning in error message, e.g. before mentioned [javax.inject](https://code.google.com/p/google-guice/issues/detail?id=674) – efan Mar 05 '13 at 20:04
  • 1
    Hmm, maybe "give dx the --core-library flag" is indeed a workaround for the entire problem. Interesting :) – Geoffrey De Smet Mar 06 '13 at 11:09
11

The only solution is a maintenance nightmare: Fork all 3th party jars from source and rewrite them so they don't use java.beans.* classes (possibly by replacing them for openbeans).

Then, every time one of those 3th party jars releases a hotfix (for example for a critical security bug), do that all over again.

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120