[英]NoClassDefFoundError for dependent library projects in Android app project (using maven as build tool)
我开发了两个Android库项目: Project A(MyBaseA)和Project B(MyBaseB) 。
我使用行家作为构建工具,MyBaseA是一个<dependency>
MyBaseB的。
我还有一个Android应用程序项目,该项目使用内置的MyBaseB.jar作为库,此jar添加到了Android应用程序项目的构建路径中。
对于库项目A ,pom.xml中的maven坐标定义为:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.base.a</groupId>
<artifactId>MyBaseA</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>MyBaseA</name>
...
对于依赖于上述库项目A项目的库项目B , pom.xml为:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.base.b</groupId>
<artifactId>MyBaseB</artifactId>
<version>1.0</version>
<packaging>apklib</packaging>
<name>MyBaseB</name>
<dependencies>
<!--include library project A as dependency-->
<dependency>
<groupId>com.my.base.a</groupId>
<artifactId>MyBaseA</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
我mvn clean install
库项目A和B都成功。
在项目B的 target/
目录下,有MyBaseB.ap_ , MyBaseB.apklib和MyBaseB.jar文件。
此时,我创建了一个新的Android应用程序项目,其中将上面的MyBaseB.jar包含在我的新Android应用程序项目的构建路径中,并使用了MyBaseB项目中定义的java类, 该类又调用了MyBaseA项目中定义的函数。 。
但是,当我运行新的Android应用程序项目时,出现异常:
java.lang.NoClassDefFoundError: com.my.base.a.ProjectAClass
。
我的Android应用程序找不到项目A中定义的Java类。 然后我检查MyBaseB.jar的内容, 库项目A的所有类不包括在MyBaseB.jar。 为什么? 我认为MyBaseB.jar应该包含项目A类,因为pom包含了项目A作为<dependency>
。 为什么会发生此错误?
====================更新=====================
将库项目A的pom的<packaging>
部分从jar更改为apklib之后 ,并在项目B(MyBaseB)的依赖项中添加了<type>apklib</type>
:
<dependency>
<groupId>com.my.base.a</groupId>
<artifactId>MyBaseA</artifactId>
<version>1.0</version>
<type>apklib</type>
</dependency>
现在MyBaseB.jar包含项目A的类。 上面的问题解决了(我检查了MyBaseB.jar的内容,现在,它包含项目A的所有类,以前没有。
但是新的问题是,当我运行Android应用程序时,每当实例化项目A的类时,都会发生java.lang.NoClassDefFoundError
。 那就是应用到达的时间:
ProjectAClass projAclass = new ProjectAClass();
我得到了java.lang.NoClassDefFoundError
。 为什么? 为什么它现在甚至抱怨MyBaseB.jar仍包含ProjectAClass.class。
发生这种情况是因为依赖项仅用于编译您的库。 在这种情况下,Maven将不做任何事情,并将假定将与所需的依赖项一起部署该库。
您想要的是:
将MyBaseA库部署到您的库类路径可用的位置(由于您是在android上进行部署,因此可能无法实现,但是我对此事的探讨还不足以得出结论),或者
在库中着色依赖项。
通过将maven-shade-plugin添加到MyBaseB项目的pom中来完成着色 :
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<!-- Exclude cryptographic signatures from dependencies,
almost always mandatory (can cause security errors otherwise) -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
该插件将在最终的über-jar中添加所有与编译范围相关的依赖项(默认)以及您的项目。
更多详细信息和示例可在maven-shade-plugin网站上找到 。
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.