简体   繁体   English

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

[英]NoClassDefFoundError for dependent library projects in Android app project (using maven as build tool)

I developed two Android library projects: Project A (MyBaseA) & Project B(MyBaseB) . 我开发了两个Android库项目: Project A(MyBaseA)Project B(MyBaseB)

I am using maven as build tool, MyBaseA is a <dependency> of MyBaseB . 我使用行家作为构建工具,MyBaseA是一个<dependency> MyBaseB的。

I also have an Android app project which uses the built MyBaseB.jar as library, this jar is added to the build path of the Android app project. 我还有一个Android应用程序项目,该项目使用内置的MyBaseB.jar作为库,此jar添加到了Android应用程序项目的构建路径中。

For library project A , the maven coordinate definition in pom.xml is: 对于库项目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>
    ...

For library project B which is dependent on above library project A project, the pom.xml is: 对于依赖于上述库项目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>

I mvn clean install library project A & B which are all successful. mvn clean install库项目AB都成功。

Under target/ directory of project B , there are MyBaseB.ap_ , MyBaseB.apklib & MyBaseB.jar files. 项目B的 target/目录下,有MyBaseB.ap_MyBaseB.apklibMyBaseB.jar文件。

At this point, I created a new Android app project, in which I included the above MyBaseB.jar to the build path of my new Android app project, and used java classes defined in MyBaseB project, which in turns call functions defined in MyBaseA project. 此时,我创建了一个新的Android应用程序项目,其中将上面的MyBaseB.jar包含在我的新Android应用程序项目的构建路径中,并使用了MyBaseB项目中定义的java类, 该类又调用了MyBaseA项目中定义的函数。 。

But when I run my new Android app project, I got exception: 但是,当我运行新的Android应用程序项目时,出现异常:

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

My android app can not find the java class defined in project A . 我的Android应用程序找不到项目A中定义的Java类。 Then I checked the content of MyBaseB.jar , all classes of library project A are not included in MyBaseB.jar . 然后我检查MyBaseB.jar的内容, 库项目A的所有类包括在MyBaseB.jar。 Why? 为什么? I think the MyBaseB.jar should include project A classes, because the pom has included project A as a <dependency> . 我认为MyBaseB.jar应该包含项目A类,因为pom包含了项目A作为<dependency> Why this error happen? 为什么会发生此错误?

==================== Update ===================== ====================更新=====================

After I changed library project A 's <packaging> section of pom from jar to apklib , and added the <type>apklib</type> in the dependency of project B (MyBaseB) : 库项目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>

now the MyBaseB.jar contains classes of project A . 现在MyBaseB.jar包含项目A的类。 The above problem solved ( I checked the content of MyBaseB.jar , now, it contains all classes of project A , previously, it didn't. 上面的问题解决了(我检查了MyBaseB.jar的内容,现在,它包含项目A的所有类,以前没有。

But the new problem is that, when I run my Android app, the java.lang.NoClassDefFoundError occurs whenever a class of project A is instantiated. 但是新的问题是,当我运行Android应用程序时,每当实例化项目A的类时,都会发生java.lang.NoClassDefFoundError That's when app reaches : 那就是应用到达的时间:

ProjectAClass projAclass = new ProjectAClass();

I got java.lang.NoClassDefFoundError . 我得到了java.lang.NoClassDefFoundError Why? 为什么? Why it complains even now the MyBaseB.jar contains the ProjectAClass.class. 为什么它现在甚至抱怨MyBaseB.jar仍包含ProjectAClass.class。

This happens because the dependency is only used to compile your library. 发生这种情况是因为依赖项仅用于编译您的库。 Maven will not do anything more in this case and will presume that the library will be deployed along with the required dependencies. 在这种情况下,Maven将不做任何事情,并将假定将与所需的依赖项一起部署该库。

What you want is either: 您想要的是:

  • Deploy the MyBaseA library to a location available to your library classpath (probably not possible since you are deploying on android, but I haven't really explored the matter enough to be conclusive), or MyBaseA库部署到您的库类路径可用的位置(由于您是在android上进行部署,因此可能无法实现,但是我对此事的探讨还不足以得出结论),或者

  • Shade the dependencies inside your library. 在库中着色依赖项。

Shading is done using the maven-shade-plugin , by adding it the pom of your MyBaseB project: 通过将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>

The plugin will add all dependencies on the compile scope (the default), along with your project, inside a final über-jar. 该插件将在最终的über-jar中添加所有与编译范围相关的依赖项(默认)以及您的项目。

More detail and examples are available on the maven-shade-plugin website . 更多详细信息和示例可在maven-shade-plugin网站上找到

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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