Class resolved by unexpected DEX;
Asked Answered
J

3

3

I am developing a application which automatically load class from external dex from external apk file (external apk file is stored in internal storage of application). The external apk file have class using com.google.gson.

The source code of the application

// Internal storage where the DexClassLoader writes the optimized dex file to.
    final File optimizedDexOutputPath = mContext.getDir("optimize_offload", Context.MODE_PRIVATE);

    // Initialize the class loader with the s dex file.
    DexClassLoader dexClassLoader = new DexClassLoader(apkPath,  optimizedDexOutputPath.getAbsolutePath(),
            null,  mContext.getClassLoader());

    // Load the apk class from the class loader.
    Class<?> apkProviderClass = dexClassLoader.loadClass(className);        

    Object obj = apkProviderClass.newInstance();   

    // call method wrappers
    java.lang.reflect.Method method = apkProviderClass.getDeclaredMethod("R_" + methodName, String.class);
    System.out.println(method.getName());

    method.setAccessible(true); 

    Object result = method.invoke(obj, params); // Exception here

Class in external apk file has following methods

public long R_catalanSum(String params) {

    Gson gson = new Gson();

    StartedSumLooperService_catalanSum param = 
            gson.fromJson(params, StartedSumLooperService_catalanSum.class);

    // Call local implementation
    return catalanSum(param.n); 
}

public long R_fiboSum(String params) {

    Gson gson = new Gson();

    StartedSumLooperService_fiboSum param = 
            gson.fromJson(params, StartedSumLooperService_fiboSum.class);

    // Call local implementation
    return fiboSum(param.n); 
}

But I face a following problem while running:

03-05 17:10:59.479: W/dalvikvm(5433): Class resolved by unexpected DEX: Lorg/vkedco/android/startedsumlooperservice/StartedSumLooperService;(0x40f007d8):0x56f3a000 ref [Lcom/google/gson/Gson;] Lcom/google/gson/Gson;(0x40eabac0):0x56daa000

03-05 17:10:59.479: W/dalvikvm(5433): (Lorg/vkedco/android/startedsumlooperservice/StartedSumLooperService; had used a different Lcom/google/gson/Gson; during pre-verification)

According to the Android build process, dex file along with 3rd party library (such as gson here) are bundled into dex files (classes.dex). Hence, I do not need to manual specify all 3rd library when initialize the class loader using DexClassLoader. Am I correct or not?

Johnettajohnette answered 5/3, 2014 at 9:32 Comment(6)
do you have solved this?Izmir
You can find my own below answer for this problem (marked)Johnettajohnette
I donot what's your means about 'class loader' or 'loaded class' in 'only use gson in either class loader or loaded class.', can you give me more codeIzmir
The code is above (in my question). Assume that class A (in A.apk) invokes a remote method in class B (class B is in external B.apk file). Hence, class A is loader class and class B is loaded class. In my previous work, class B uses Gson library (gson.jar is exported and added in B's classpath) and class A also uses same Gson library (gson.jar is also added in A's classpath). That introduces the error: "had used a different Lcom/google/gson/Gson; during pre-verification". The solution is that, remove gson.jar in A.apk and used in B.apk only. Hope this will help you.Johnettajohnette
But if remove gson.jar in A.apk, It will compile error.Izmir
Try to modify your code so that A.apk does not use gson.jarJohnettajohnette
J
2

The answer for this problem is that DEX find 2 versions of gson in class loader and loaded class. The solution is: only use gson in either class loader or loaded class.

Johnettajohnette answered 24/3, 2014 at 7:0 Comment(0)
D
1

There seems to be a solution to the problem on a google forum for this https://groups.google.com/forum/#!topic/android-platform/IP9BuSXgTdQ.

Daydream answered 5/3, 2014 at 10:20 Comment(1)
Thanks fotr your answer, but it did not work for my case. The thing is that DEX loader could not find gson lib.Johnettajohnette
F
0

I had the same problem.

But now solved it. We can use the lib in both loader and loading class. I use eclipse.

In loader and loading project added jsoup.jar to libs folder and lib reference

enter image description here

enter image description here

Then we can use the same lib in both class loader and loading.

Fawnfawna answered 12/4, 2015 at 8:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.