1

I am using JavaAssist in Android to make dynamic classes for a purpose. ClassPool get() method throw NotFoundException when trying to get java.lang.String.

It works fine in JUnit Test. But if I run same in the device, it throws exception.

Here is the code snippet I'm trying.

ClassPool classPool = ClassPool.getDefault();
CtClass ctClass=classPool.get("java.lang.String");

The 2nd line throws an exception.

Please help.

  • What does your `get(String str)` method in your ClassPool.java return? How is it implemented? You could edit your original code and add its code... Shouldn´t the object `classPool` of type `ClassPool` be created like this: `ClassPool classPool = new ClassPool();` How do your contructors / does your constructor in your ClassPool.java class look like? – Noureddine Ouertani Jan 23 '17 at 11:57
  • get Method returns instance of CtClass. If not found it throws NotFoundException. ClassPool is a predefined class in javassist hence I cannot modify the code. ClassPool.getDefault() returns the singleton instance of ClassPool class. – user7409419 Jan 23 '17 at 12:24

3 Answers3

1

Try to change the string "java.lang.String" with "Ljava.lang.String" or "Ljava.lang.String;" and it should work.

Since you are loading classes that are embedded into Java is possible that your machine does not recognize the standar name of the string but needs the name that is used internally by the JVM to identify this specific object.

To know more about this "L" subject I suggest you to read the JVM specs focusing in particular on the chapter 4.3 and is also quite easy to understand and shorter to just read this question that talks about array but includes also this notation.

Community
  • 1
  • 1
rakwaht
  • 3,666
  • 3
  • 28
  • 45
0

Try this code:

ClassPool classPool = new ClassPool();
classPool.getDefault();
  • Not working. Can it be a issue of JVM vs DVM. Because my JUnit test case runs successfully and on device it doesn't. – user7409419 Jan 23 '17 at 12:25
0

Android is using a different class file representation where Java byte code was transformed into the Dalvik class format. This format is not processable by any Java byte code manipulation tool which is why Javassist does not work.

Internally, Javassist calls classLoader.getResourceAsStream("java/lang/String.class") which returns null on a Dalvik VM due to the inexistance of the class file at runtime.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • I get that. Is there some solution to it? – user7409419 Jan 24 '17 at 09:35
  • You cannot use Javassist on Android. You can have a look at Byte Buddy if you want to create runtime subclasses, but there is no way of manipulating classes at runtime; Android does not even offer an instrumentation API. – Rafael Winterhalter Jan 24 '17 at 09:56