我开发了两个Android库项目:项目A(MyBaseA)& 项目B(MyBaseB)。
我使用maven作为构建工具, MyBaseA 是 MyBaseB 的<dependency>
。
我还有一个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 &amp; B 都是成功的。
在项目B 的target/
目录下,有 MyBaseB.ap _ , MyBaseB.apklib &amp; MyBaseB.jar 文件。
此时,我创建了一个新的Android应用程序项目,其中我将上面的 MyBaseB.jar 包含到我的新Android应用程序项目的构建路径中,并使用了 MyBaseB 项目,它又调用 MyBaseA 项目中定义的函数。
但是当我运行我的新Android应用程序项目时,我得到了例外:
java.lang.NoClassDefFoundError: com.my.base.a.ProjectAClass
。
我的Android应用找不到项目A 中定义的java类。然后我检查了 MyBaseB.jar 的内容, MyBaseB.jar 中包含库项目A 的所有类 >。为什么?我认为 MyBaseB.jar 应该包含项目A 类,因为pom已将项目A 包含为<dependency>
。为什么会发生这种错误?
====================更新=====================
我将库项目的<packaging>
部分pom从 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 的所有类,之前,它没有&#t;
但新问题在于,当我运行Android应用时,只要实例化了一类项目A ,就会出现java.lang.NoClassDefFoundError
。应用到达时的那个:
ProjectAClass projAclass = new ProjectAClass();
我得到了java.lang.NoClassDefFoundError
。为什么?为什么即使现在抱怨 MyBaseB.jar 包含ProjectAClass.class。
答案 0 :(得分:0)
这是因为依赖项仅用于编译您的库。在这种情况下,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中添加编译范围(默认)以及项目的所有依赖项。
the maven-shade-plugin website上提供了更多详细信息和示例。
希望这有帮助。