繁体   English   中英

Android应用程序项目中的依赖库项目的NoClassDefFoundError(使用maven作为构建工具)

[英]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项目的库项目Bpom.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库项目AB都成功。

项目B的 target/目录下,有MyBaseB.ap_MyBaseB.apklibMyBaseB.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM