I have a Java/Kotlin project with multiple sub-projects (modules). This is module-info.java for the base module:
module ir.openuniverse {
requires java.desktop;
requires kotlin.stdlib;
requires transitive org.apache.logging.log4j;
requires org.apache.logging.log4j.core;
exports ir.openuniverse; // Base module has exported here.
}
And for a consumer module, I have:
module ir.openuniverse.watchservice {
requires kotlin.stdlib;
requires gson;
requires ir.openuniverse; // Base module has imported here
exports ir.openuniverse.watchservice;
}
Now I insert a test file in consumer module:
package ir.openuniverse.watchservice;
import ir.openuniverse.UtilKt;
import ir.openuniverse.JUtil;
import ir.openuniverse.Entry;
public class Test {}
and then try to compile it:
> Task :watch-service:compileJava FAILED
[...]\watch-service\src\main\ir\openuniverse\watchservice\Test.java:3: error: cannot find symbol
import ir.openuniverse.UtilKt;
^
symbol: class UtilKt
location: package ir.openuniverse
[...]\watch-service\src\main\ir\openuniverse\watchservice\Test.java:5: error: cannot find symbol
import ir.openuniverse.Entry;
^
symbol: class Entry
location: package ir.openuniverse
2 errors
FAILURE: Build failed with an exception.
All three classes (UtilKt, JUtil, Entry) are in the base module. But JUtil is in Java (JUtil.java) and two others in Kotlin (Util.kt and Entry.kt).
As you can see there is no problem with importing JUtil, but the classes that their sources in Kotlin, can't be resolved. (Without importing two Kotlin classes I can compile the module, successfully).
Also, there is no problem if I don't use Java 9 module system totally.
I use Gradle and tested with these two plugins:
gradle.plugin.org.gradle.java:experimental-jigsaw:0.1.1
xor:
gradle.plugin.rgoldberg:experimental-jigsaw:0.4.1-SNAPSHOT
UPDATE 1:
Due to @nullpointer's comment, I tried to check classpaths. This is a part of executing the task with --debug option that shows -classpath is empty and --module-path has correct values (Especially see these two: D:\Devel\IdeaProjects\Tinifier\base\build\classes\java\main;D:\Devel\IdeaProjects\Tinifier\base\build\classes\kotlin\main;):
05:40:29.575 [DEBUG] [org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler] Compiler arguments: -source 11 -target 11 -d D:\Devel\IdeaProjects\Tinifier\watch-service\build\classes\java\main -g -sourcepath -proc:none -XDuseUnsharedTable=true -classpath --module-path D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk8\1.3.10\71d0fa967493eb76648b575edf1762cb2d0c7f10\kotlin-stdlib-jdk8-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\com.google.code.gson\gson\2.8.5\f645ed69d595b24d4cf8b3fbb64cc505bede8829\gson-2.8.5.jar;D:\Devel\IdeaProjects\Tinifier\base\build\classes\java\main;D:\Devel\IdeaProjects\Tinifier\base\build\classes\kotlin\main;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk7\1.3.10\4d147bf43060dc43d61b096e24da1e67dfe0c032\kotlin-stdlib-jdk7-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.3.10\b178c1501609c6e4ee8be635513cb023a466457d\kotlin-stdlib-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.1\268f0fe4df3eefe052b57c87ec48517d64fb2a10\log4j-api-2.11.1.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-common\1.3.10\1b19d99229dcedad7caf50534dce38fe82845269\kotlin-stdlib-common-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\13.0\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\annotations-13.0.jar;D:\Devel\IdeaProjects\Tinifier\watch-service\build\classes\kotlin\main D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\module-info.java
05:40:29.576 [INFO] [org.gradle.api.internal.tasks.compile.JdkJavaCompiler] Compiling with JDK Java compiler API.
05:40:30.138 [ERROR] [system.err] D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java:3: error: cannot find symbol
05:40:30.139 [ERROR] [system.err] import ir.openuniverse.UtilKt;
05:40:30.139 [ERROR] [system.err] ^
05:40:30.139 [ERROR] [system.err] symbol: class UtilKt
05:40:30.139 [ERROR] [system.err] location: package ir.openuniverse
05:40:30.142 [ERROR] [system.err] D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java:5: error: cannot find symbol
05:40:30.142 [ERROR] [system.err] import ir.openuniverse.Entry;
05:40:30.143 [ERROR] [system.err] ^
05:40:30.143 [ERROR] [system.err] symbol: class Entry
05:40:30.143 [ERROR] [system.err] location: package ir.openuniverse
05:40:30.164 [ERROR] [system.err] 2 errors
Unfortunately, even though I know Compiler arguments from above logs, I don't know how to manually compile the source. Simply running javac <compiler-arguments> doesn't work.
UPDATE 2:
Making a copy of Kotlin .class files to the path of Java .class files solved the issue. See my answer for a simple Gradle's configuration to do this. But I know this is not a fundamental solution.
UPDATE 3:
I found a more fundamental issue! If I remove all Java sources from a module (even if it's not depended on another; like my base module) and just stay Kotlin sources, then the compilation of that module throws at where that package (that includes only Kotlin sources) exported (in module-info.java) and says the package is empty!!:
> Task :base:compileJava FAILED
D:\Devel\IdeaProjects\Tinifier\base\src\main\module-info.java:9: error: package is empty or does not exist: ir.openuniverse
exports ir.openuniverse;
^
1 error
FAILURE: Build failed with an exception.