Android : load(getClass().getClassLoader(),classLoadingStrategy) throws java.lang.IllegalStateException

1.7k views Asked by At

Im trying to create byteBuddy object under method proxy(...) in Android and then call on the byteBuddy object some methods:

<T> T proxy(Class<T> clz, InvocationHandler invocationHandler) {
    ByteBuddy byteBuddy = null;
    try {
        byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V6);
    } catch (Throwable e) {
        //e.printStackTrace();
    }
    if(byteBuddy!=null) {
        Class<?> enhanced = byteBuddy
                .subclass(clz, ConstructorStrategy.Default.IMITATE_SUPER_TYPE)
                .method(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class)))
                .intercept(InvocationHandlerAdapter.of(invocationHandler))
                .make().load(getClass().getClassLoader(), classLoadingStrategy)
                .getLoaded();

        ...

But on line with:

load(getClass().getClassLoader(), classLoadingStrategy)

ByteBuddy throws exception :

06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ java.lang.IllegalStateException: Cannot load class pdl.transport.overlay.fissione.FissioneTransport$FissioneHandler$ByteBuddy$vhLwLk79 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:138) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:3380) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.Messenger.proxy(Messenger.java:320) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.Messenger.async(Messenger.java:382) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.Messenger.async(Messenger.java:373) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.overlay.fissione.FissioneTransport.join(FissioneTransport.java:221) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.overlay.fissione.FissioneTransport.open(FissioneTransport.java:202) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.overlay.util.DHT.(DHT.java:37) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at pdl.transport.overlay.util.DHT.main(DHT.java:117) 06-11 21:29:23.351 12028-12028/com.example.AndroidOverlay W/System.err﹕ at com.example.AndroidOverlay.MyActivity_newbie.onCreate(MyActivity_newbie.java:72) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.Activity.performCreate(Activity.java:6289) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.ActivityThread.access$900(ActivityThread.java:177) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.os.Looper.loop(Looper.java:145) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5942) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ Caused by: java.lang.ClassNotFoundException: Didn't find class "pdl.transport.overlay.fissione.FissioneTransport$FissioneHandler$ByteBuddy$vhLwLk79" on path: DexPathList[[zip file "/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.jar"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:136) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 22 more 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ Suppressed: java.io.IOException: Failed to open dex file '/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.jar' from memory: Unrecognized version number in /data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.jar: 0 3 6 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexFile.openDexFileNative(Native Method) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexFile.openDexFile(DexFile.java:295) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexFile.(DexFile.java:111) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexFile.loadDex(DexFile.java:151) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexPathList.loadDexFile(DexPathList.java:265) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexPathList.makeDexElements(DexPathList.java:231) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexPathList.(DexPathList.java:109) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:48) 06-11 21:29:23.361 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.DexClassLoader.(DexClassLoader.java:57) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at net.bytebuddy.android.AndroidClassLoadingStrategy$DexProcessor$ForSdkCompiler.makeClassLoader(AndroidClassLoadingStrategy.java:257) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:132) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 22 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ Caused by: java.io.IOException: Failed execv(/system/bin/dex2oat --runtime-arg -classpath --runtime-arg --instruction-set=arm --instruction-set-features=div --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --dex-file=/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.jar --oat-fd=64 --art-fd=-1 --oat-location=/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.dex --runtime-arg -Xms64m --runtime-arg -Xmx512m) because non-0 exit status 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 33 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ Caused by: java.io.IOException: Failed to find dex file '/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.jar' in oat location '/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.dex': Failed to find existing oat file at /data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.dex: File size of 0 bytes not large enough to contain ELF header of 52 bytes: '/data/data/com.example.AndroidOverlay/app_TnUR5LUb/1Gzh1FCI.dex' 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 33 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ Suppressed: java.lang.ClassNotFoundException: Didn't find class "pdl.transport.overlay.fissione.FissioneTransport$FissioneHandler$ByteBuddy$vhLwLk79" on path: DexPathList[[zip file "/data/app/com.example.AndroidOverlay-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 24 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ Suppressed: java.lang.ClassNotFoundException: pdl.transport.overlay.fissione.FissioneTransport$FissioneHandler$ByteBuddy$vhLwLk79 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.Class.classForName(Native Method) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 25 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

Im using dx-1.7.jar from http://central.maven.org/maven2/com/google/android/tools/dx/1.7/dx-1.7.jar and byte-buddy-0.6.8.jar,byte-buddy-android-0.6.8.jar

Am I missing something? I get also Could not run Dynamic type.(Failed resolution of: Lorg/objectweb/asmType;) on yours android example application, it seems like Im missing something, some library or I dont know... Thank you for answers.

EDIT1: Im using Lollipop and this is how I setup AndroidClassLoadingStrategy:

final File dir = this.getDir("dexgen", Context.MODE_PRIVATE);
    Messenger.setClassLoadingStrategy(new AndroidClassLoadingStrategy(dir));

which sets to class Messenger where I have method proxy(...)

public static void setClassLoadingStrategy(ClassLoadingStrategy cls) {
    classLoadingStrategy = cls;
}

and classLoadingStrategy is defined as

private static ClassLoadingStrategy classLoadingStrategy;

Edit 2: After All I took ByteBuddy example application, tried lines for Android lollipop replacing

File file = TestActivity.this.getDir(RandomString.make(), Context.MODE_PRIVATE);

for one of theese which should be replacement, tried them all and all gives same exception, just from different class-activity

File file = getCodeCacheDir(); //NOT WORKING
// File file = getApplicationContext().getCodeCacheDir(); //NOT WORKING
// File file = getBaseContext().getCodeCacheDir(); //NOT WORKING
// File file = TestActivity.this.getCodeCacheDir(); //NOT WORKING

Exception still:

06-12 23:18:57.916    1947-1947/net.bytebuddy.android.test W/net.bytebuddy﹕ java.lang.IllegalStateException: Cannot load class net.bytebuddy.renamed.java.lang.Object$ByteBuddy$uSYJ5787$auxiliary$MBywjCuh

I created and putted on my website sources for future possibility to reproduce error here:

bashism.com/shared/ByteBuddyTest.tar.gz

Edit 3:

Android version: 5.0.1 Lollipop

Device: Samsung galaxy S4

IDE: IntelliJ Idea 14.1.3

Edit 4: After changing inside Main Activity:

File file = TestActivity.this.getDir(RandomString.make(), Context.MODE_PRIVATE);

and inside net.bytebuddy.android.AndroidClassLoadingStrategy

public ForSdkCompiler(DexOptions dexFileOptions, CfOptions dexCompilerOptions) {
dexFileOptions.targetApiLevel = 13;
this.dexFileOptions = dexFileOptions;
this.dexCompilerOptions = dexCompilerOptions;

}

Seems working/stable, further debugging soon

1

There are 1 answers

2
Jeff On

As I alluded to in my above comment, the issue is that the DEX file generated is currently too new (the newer version apparently introduces "extended opcodes") for the underlying ART machinery to handle. The actual issue likely stems from different devices having different default DexOptions.targetApiLevel values (that likely ignore actual API build targets). To fix this, any class loading strategy involving classes.dex files should specifically set this value to 13 or lower to ensure that the proper dex files are generated. For example, in @raphw's AndroidClassLoadingStrategy, the DexProcessor.ForSdkCompiler constructor could be modified to specifically set this value e.g.:

public ForSdkCompiler(DexOptions dexFileOptions, CfOptions dexCompilerOptions) {
    dexFileOptions.targetApiLevel = 13;
    this.dexFileOptions = dexFileOptions;
    this.dexCompilerOptions = dexCompilerOptions;
}