6

I'm trying to use Byte Buddy library in Android but I get an error:

java.lang.IllegalStateException: This JVM's version string does not seem to be valid: 0

I have coded nothing yet, just:

ByteBuddy test = new ByteBuddy();

in my App.java

I have imported:

<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>0.7.7</version>
</dependency>

but it didn't work, to I tried with:

<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy-android</artifactId>
    <version>0.7.7</version>
</dependency>

but I still get same error.

EDIT

I have put this line before initialize ByteBuddy:

  System.setProperty("java.version", "1.7.0_51");

But now I get this another error:

Caused by: java.lang.UnsupportedOperationException: can't load this type of class file.

for this code:

Class<?> dynamicType = new ByteBuddy(ClassFileVersion.JAVA_V6)
            .subclass(Object.class)
            .method(ElementMatchers.named("toString"))
            .intercept(FixedValue.value("Hello World!"))
            .make()
            .load(getClass().getClassLoader(), AndroidClassLoadingStrategy.Default.WRAPPER)
            .getLoaded();
Héctor
  • 24,444
  • 35
  • 132
  • 243
  • 1
    On Android, try adding the class file version explicitly: new ByteBuddy(ClassFileVersion.JAVA_6), the Android dependency contains an Android specific ClassLoadingStrategy. – Rafael Winterhalter Dec 26 '15 at 09:01
  • I have changed the class loading strategy to the Android one and specified the ClassFileVersion but I still get the same error. – Héctor Jan 07 '16 at 14:10
  • 1
    You are not using the Android class loading strategy. The Default strategies do not work there. Instantiate one using "new". – Rafael Winterhalter Jan 07 '16 at 15:22
  • `AndroidClassLoadingStrategy` constructor need a "privateDirectory" `File`. What should I pass? – Héctor Jan 07 '16 at 15:31
  • It works!! In AndroidClassLoadingStrategy I have passed `context.getDir("dexgen", Context.MODE_PRIVATE)`. Thanks!! – Héctor Jan 07 '16 at 15:46
  • It depends on the API version used but what you do is correct. Alternatively, use the code cache directory. See the javadoc for more information. – Rafael Winterhalter Jan 07 '16 at 15:57

1 Answers1

3

The error is because java.version returns 0 in Android (See section System Properties here - Comparison of Java and Android API)

Also, if you observe ByteBuddy ClassFileVersion

forCurrentJavaVersion() : This method checks for versionString which should return any valid Java/JDK version else it

throws IllegalStateException("This JVM's version string does not seem to be valid: " + versionString);

& since java.version is returning 0, it's throwing IllegalStateException.

Try to log this value:

String versionString = System.getProperty(JAVA_VERSION_PROPERTY);
Log.d(TAG, versionString);//retruns 0 here

hence workaround for this issue is to add

 System.setProperty(JAVA_VERSION_PROPERTY, "1.7.0_79");//add your jdk version here

before calling

ByteBuddy test = new ByteBuddy();

where JAVA_VERSION_PROPERTY is declared as:

 private static final String JAVA_VERSION_PROPERTY = "java.version";

Also dependency to use is:

<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>0.7.7</version>
</dependency>

Else if you are using studio, you can add

compile 'net.bytebuddy:byte-buddy:0.7.7'

to your app build.gradle.

Hope this will help solve your issue.

Amrit Pal Singh
  • 7,116
  • 7
  • 40
  • 50