Android class java-library module classpath NoClassDefFoundError

My project was launched, and I decided to break it into separate modules - gui and domain . My domain module should not know that it is part of an Android project, so I created a java-library module and put several classes there. It works like a charm, but there is a problem when I add some other dependencies inside my java-library module like RxJava. I created the Main class to just check my code. It creates passes, but when it tries to call RxJava classes, it crashes out:

  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 

My main class:

 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)); } } 

My build.gradle file:

 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) If I use com.android.library , it works

2) If I add the RxJava library to the .jar file, it will not change anything

EDIT:

I looked at the Domain.iml file and found something strange:

 <?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> 

The strange part is the scope attribute in orderEntry node

 <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" /> 

If I delete it manually:

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

It works like a charm.

Unfortunately, if I synchronize my build.gradle file, it overrides my modifications.

How to make it work constantly and why does it work like that?

+12
java android module android-studio gradle
source share
1 answer

The strange part is the area attribute in the orderEntry node

 <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" /> 

If I delete it manually:

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

It works like a charm.

Unfortunately, if I synchronize my build.gradle file, it overrides my modification.

Have you tried changing the scope using the Android Studios project structure?

File → Project Structure, then select the Dependencies tab and add the dependency for the required module. In your case, it will be a java library , I believe.

As far as I know, you cannot change the dependency area after adding. So if you have already added it, try deleting and adding it again. Be sure to assign an implementation scope and see if it works.

I hope this was helpful

0
source share

All Articles