【问题标题】:NoClassDefFoundError for dependent library projects in Android app project (using maven as build tool)Android应用项目中依赖库项目的NoClassDefFoundError(使用maven作为构建工具)
【发布时间】:2014-09-07 01:11:32
【问题描述】:

我开发了两个 Android 库项目:Project A (MyBaseA)Project B(MyBaseB)

我使用 maven 作为构建工具,MyBaseAMyBaseB<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项目的库项目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图书馆项目A & B都成功了。

项目Btarget/目录下,有MyBaseB.ap_MyBaseB.apklibMyBaseB.jar 文件。

此时,我创建了一个新的 Android 应用项目,其中我将上述 MyBaseB.jar 包含到了我的新 Android 应用项目的构建路径中,并使用了 MyBaseB 项目,依次调用 MyBaseA 项目中定义的函数。

但是当我运行我的新 Android 应用项目时,我遇到了异常:

java.lang.NoClassDefFoundError: com.my.base.a.ProjectAClass

我的 android 应用找不到在 项目 A 中定义的 java 类。然后我查看了MyBaseB.jar的内容,库项目A的所有类都包含在MyBaseB.jar中>。为什么?我认为 MyBaseB.jar 应该包含 project A 类,因为 pom 已包含 project A 作为&lt;dependency&gt;。为什么会出现这个错误?

====================更新=====================强>

在我将 library project A 的 pom 的 &lt;packaging&gt; 部分从 jar 更改为 apklib 后,并将 &lt;type&gt;apklib&lt;/type&gt; 添加到项目B (MyBaseB)的依赖:

  <dependency>
        <groupId>com.my.base.a</groupId>
        <artifactId>MyBaseA</artifactId>
        <version>1.0</version>
        <type>apklib</type>
   </dependency>

现在MyBaseB.jar 包含项目A 的类。上面的问题解决了(我检查了MyBaseB.jar的内容,现在,它包含了project A的所有类,以前没有。

但新的问题是,当我运行我的 Android 应用程序时,每当实例化一个 project A 类时,就会出现java.lang.NoClassDefFoundError。那是应用程序到达的时候:

ProjectAClass projAclass = new ProjectAClass();

我收到了java.lang.NoClassDefFoundError。为什么?为什么它现在仍然抱怨 MyBaseB.jar 包含 ProjectAClass.class。

【问题讨论】:

    标签: java android maven maven-2 maven-3


    【解决方案1】:

    发生这种情况是因为依赖项仅用于编译您的库。在这种情况下,Maven 不会再做任何事情,并假定该库将与所需的依赖项一起部署。

    你想要的是:

    • MyBaseA 库部署到库类路径可用的位置(可能不可能,因为您在 android 上进行部署,但我还没有真正探索到足以得出结论的问题) , 或

    • 隐藏库中的依赖项。

    使用 ma​​ven-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>
    

    该插件会将 compile 范围(默认)上的所有依赖项与您的项目一起添加到最终的 über-jar 中。

    更多详情和示例请访问the maven-shade-plugin website

    希望这会有所帮助。

    【讨论】:

    • 谢谢,但我不认为这是我应该走的路,请检查我的更新(将项目 A 的 从 jar 更改为 apklib 后,项目 B jar 包含所有类项目 A 已经。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    相关资源
    最近更新 更多