【问题标题】:Android Studio java-library module classpath NoClassDefFoundErrorAndroid Studio java-library 模块类路径 NoClassDefFoundError
【发布时间】:2018-05-02 10:08:48
【问题描述】:

我的项目开始变得很大,所以我决定将其拆分为单独的模块 - guidomain。我的domain 模块一定不知道它是Android 项目的一部分,所以我创建了java-library 模块并将一些类放在那里。它就像一个魅力,但是当我在我的 java-library 模块(如 RxJava)中添加一些其他依赖项时出现问题。我创建了一个Main 类来简单地测试我的代码。构建通过,但是当它尝试调用 RxJava 类时,它会崩溃并出现异常:

    Exception in thread "main" java.lang.NoClassDefFoundError: io/reactivex/Observable
    at com.example.domain.Main.main(Main.java:13)
    Caused by: java.lang.ClassNotFoundException: io.reactivex.Observable
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

我的主要课程:

package com.example.domain;

import io.reactivex.Observable;

public class Main {

    public static void main(String[] args) {
        Observable.just(1)
                .subscribe(integer -> System.out.println(integer));
    }

}

我的build.gradle 文件:

apply plugin: 'java-library'

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    api 'io.reactivex.rxjava2:rxjava:2.1.2'
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

1) 如果我改用com.android.library,它会起作用

2) 如果我将 RxJava 库添加为 .jar 文件,它不会改变任何内容

编辑:

我查看了Domain.iml 文件,发现了一些奇怪的东西:

<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":Domain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
  <component name="FacetManager">
    <facet type="android-gradle" name="Android-Gradle">
      <configuration>
        <option name="GRADLE_PROJECT_PATH" value=":Domain" />
      </configuration>
    </facet>
    <facet type="java-gradle" name="Java-Gradle">
      <configuration>
        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
        <option name="BUILDABLE" value="true" />
      </configuration>
    </facet>
  </component>
  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
    <output url="file://$MODULE_DIR$/build/classes/java/main" />
    <output-test url="file://$MODULE_DIR$/build/classes/java/test" />
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="library" exported="" scope="PROVIDED" name="rxjava-2.1.2" level="project" />
    <orderEntry type="library" exported="" scope="PROVIDED" name="reactive-streams-1.0.0" level="project" />
  </component>
</module>

奇怪的部分是orderEntry节点中的scope属性

<orderEntry type="library" exported="" scope="PROVIDED" name="rxjava-2.1.2" level="project" />
<orderEntry type="library" exported="" scope="PROVIDED" name="reactive-streams-1.0.0" level="project" />

如果我手动删除它:

<orderEntry type="library" exported="" name="rxjava-2.1.2" level="project" />
<orderEntry type="library" exported="" name="reactive-streams-1.0.0" level="project" />

它就像一个魅力。

不幸的是,如果我同步我的 build.gradle 文件,它会覆盖我的修改。

如何使其永久运行以及为什么会这样?

【问题讨论】:

  • 您使用的是什么版本的 java-library 插件?是不是插件过时了,无法识别“api”依赖类型?
  • 将“api”更改为“实现”甚至“编译”没有任何改变
  • 冒着问题显而易见的风险,您已将Observable 导入您的班级,对吧?
  • @Lau 谢谢。我正在使用相同的版本。我现在已经在“主”外部模块中添加了依赖项。这是一种解决方法,但目前有效。
  • 我知道这没有多大帮助,但我也在大型生产应用程序中看到了这一点。我认为这是一个多索引问题,但我现在不确定,因为我已经遵循了所有正确的步骤来实施它。我从另一个分支添加了一些模块,并且一切都在测试中工作,但是当实际运行它时,当访问 Foo.class 时,我得到了同样的错误。

标签: java android android-studio gradle module


【解决方案1】:

奇怪的部分是 orderEntry 节点中的范围属性

<orderEntry type="library" exported="" scope="PROVIDED" name="rxjava-2.1.2" level="project" />
<orderEntry type="library" exported="" scope="PROVIDED" name="reactive-streams-1.0.0" level="project" />

如果我手动删除它:

<orderEntry type="library" exported="" name="rxjava-2.1.2" level="project" />
<orderEntry type="library" exported="" name="reactive-streams-1.0.0" level="project" />

它就像一个魅力。

不幸的是,如果我同步我的 build.gradle 文件,它会覆盖我的 修改。

您是否尝试通过 Android Studios 项目结构更改范围?

File -> Project Structure 然后选择 Dependencies 选项卡并添加所需模块的 Dependency。在你的情况下,我相信 java-library

据我所知,一旦添加,您就无法更改依赖项的范围。因此,如果您已经添加了它,请尝试删除并重新添加它。不过一定要分配实现范围,看看它是否有效。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 2014-11-29
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    相关资源
    最近更新 更多