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?