Reflection using DexClassLoader when connecting to an external JAR library

I am trying to build a plugin architecture for an Android app. I have a host application that will check the directory for apk "plugin" files, load them into DexClassLoader and call the method to get the DerivedLibraryObjects array.

I think the problem is that DerivedLibraryObject extends the base class that is contained in the external JAR library. Thus, the host and the plugin reference this JAR. When I try to get an array of DerivedLibraryObjects, I get the following exception:

04-01 14:26:57.996: ERROR/AndroidRuntime(23386): java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation 

From what I am compiling, this means that the object in the plugin does not match the object in the host. However, the host and plugin applications reference a copy of the same exact jar file. If I return an object that simply extends Object, then the code works fine, but as soon as I start working with DerivedLibraryObject, it throws this error.

Does anyone have any suggestions?

+4
source share
2 answers

I can answer my question - the problem is that both the host and the plugin contain an external jar library, so when the class loader detects that there are two versions of the same class, it is freed.

What you can do is create your plugin manually by compiling all the class files (I will let Eclipse do this) and then build jar / apk using dex using:

 dx --dex --output=<outputdir>\plugin.jar <projectpath>\bin\ 

projectpath is the root of your Android project. Your class files should be found when entering the bin directory.

If someone can post an ant script to do this, it would be nice to add to this question.

+4
source

I have the same problem with maven. The trick is to include the shared library only in the host application, and not include it in the plugin.

here is part of my projects.

pom shared library

build it as an andriod library (using apklib packaging) and install an additional jar file with build-helper-maven-plugin

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>attach-artifacts</id> <phase>package</phase> <goals> <goal>attach-artifact</goal> </goals> <configuration> <artifacts> <artifact> <file>${basedir}/target/${project.build.finalName}.jar</file> <type>jar</type> </artifact> </artifacts> </configuration> </execution> </executions> </plugin> 

host-application pom include shared library dependency

 <dependency> <groupId>group.id</groupId> <artifactId>artifact-id</artifactId> <version>common-library-version</version> <type>apklib</type> </dependency> 

pom plugin use .jar dependency with scope provided. Apklib dependency does not support the provided scope.

 <dependency> <groupId>your.common.library.group</groupId> <artifactId>Your-common-lib-id</artifactId> <version>your-common-lib-version</version> <scope>provided</scope> </dependency> 

Finaly create some kind of assembler project and include all three projects in the pom file.

It works great for me with maven3 and Android-maven-plugin 3.2.0

0
source

Source: https://habr.com/ru/post/1346284/


All Articles