Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 543766

Summary: Java module not found at runtime even with requires transitive
Product: z_Archived Reporter: Sam Peters <eclipse-devel>
Component: m2eAssignee: Till Brychcy <register.eclipse>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: b.michael, f.rajchenbach, fbricon, register.eclipse
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
See Also: https://git.eclipse.org/r/137086
https://git.eclipse.org/c/m2e/m2e-core.git/commit/?id=da6ee5f46781db27c9775f765ebffcc30bac036f
Whiteboard:

Description Sam Peters CLA 2019-01-24 03:04:28 EST
While migrating our project from Java 8 to Java 11 modules, I found a possible a bug in Eclipse 2018-12, especially related to the Java Module System (JPMS) and the required transitive directive (see my original post on SO: https://stackoverflow.com/questions/54215858/java-module-not-found-at-runtime-even-with-requires-transitive).

Lets assume we have four simple projects A, B, C and D with the following module declarations in module-info.java:

====================
Project A
====================

open module a {
    exports a;
}

====================
Project B
====================

open module b {
    exports b;
    requires transitive a;
}

====================
Project C
====================

open module c {
    exports c;
    requires transitive b;
}

====================
Project D
====================

open module d {
    requires transitive c;
}

Using Maven, we declared the dependencies D depends on C, C depends on B and B depends on A in the corresponding pom.xml files. Besides, each project contains a class file with the following content (the files for projects A, B and C are equivalent):

package d;
public class D {
    public static void main(String[] args) { 
        System.out.println("D");
    }
}

When running the classes using the default runtime configuration of Eclipse 2018-12, only class A, B and C runs without errors. But when I run class D I get: Error occurred during initialization of boot layer java.lang.module.FindException: Module a not found, required by b

In my understanding module a should be known to module b, module c and also module d due to applied requires transitive directives. But as you can see, at runtime this is not the case since module a is not set in the module-path (-p) but on the classpath of the generated command line:

C:\me\jdk-11.0.1\bin\javaw.exe
-Dfile.encoding=UTF-8 
-p "C:\me\workspace\d\target\classes;C:\me\workspace\c\target\classes;C:\me\workspace\b\target\classes"
-classpath "C:\me\workspace\a\target\classes"
-m d/d.D

So my question is: Why project A (C:\me\workspace\a\target\classes) has been added to the classpath and not to the module-path? Is this intended behaviour, and what do I have to change to get project D running in Eclipse?

If I move C:\me\workspace\a\target\classes to the -p argument list, everything works as I would expect but that's surely not the preferred way to go.
Comment 1 Till Brychcy CLA 2019-01-24 04:07:06 EST
I guess org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference.isTransitive() needs to be handled in org.eclipse.m2e.jdt.internal.InternalModuleSupport.getRequiredModules(File, int)

Moving to m2e.
Comment 2 Sam Peters CLA 2019-01-24 05:07:32 EST
@Till Brychcy: I installed http://subclipse.tigris.org/m2eclipse/latest/ (Maven Integration for Subclipse) via Install New Software, but NOT m2e (Maven Integration for Eclipse) via Eclipse Marketplace. Could you reproduce my problem with m2e as well? Perhaps it's not m2e related...
Comment 3 Till Brychcy CLA 2019-01-24 05:34:15 EST
Are you sure? m2eclipse is the predecessor of m2e and AFAIK not at all supported anymore, so I strongly doubt it supports configuring the module path.

Can you reproduce the problem in a pure eclipse workspace (without any pom.xml involved, projects created in eclipse and buildpath directly configured in eclipse)?
Comment 4 Sam Peters CLA 2019-01-24 07:38:13 EST
@Till Brychcy: Ok, I looked in the Eclipse installation details and searched for "Maven": There are only m2e entries (along with one m2e entry under "Maven SCM handler for Subclipse" that we use for "Checkout as Maven project..." from the SCM view). So I think you are right, we are talking about a problem in m2e. Sorry for the confusion.

> Can you reproduce the problem in a pure eclipse workspace (without any pom.xml involved, projects created in eclipse and buildpath directly configured in eclipse)?

I created four Java Projects with main classes and build-info's, added the depending modules to Java Build Path > Projects > Modulepath of the project settings (e. g., for project D I added C and so on) and run class D. I don't get any errors at runtime with this setup. So, it's likely a problem with m2e.
Comment 5 Till Brychcy CLA 2019-02-17 06:29:52 EST
(In reply to Till Brychcy from comment #1)
> I guess
> org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference.
> isTransitive() needs to be handled in
> org.eclipse.m2e.jdt.internal.InternalModuleSupport.getRequiredModules(File,
> int)
> 

That guess was wrong, as required transitive dependencies are needed for runtime anyway.

Bug is in the recursive invocation in org.eclipse.m2e.jdt.internal.InternalModuleSupport.collectTransitiveRequiredModules(Set<String>, Set<String>, Map<String, IClasspathEntryDescriptor>, IProgressMonitor, int).
The first arg contains the final result, to passing the local variable transitiveModules as first arg is wrong.
Comment 6 Eclipse Genie CLA 2019-02-17 06:31:56 EST
New Gerrit change created: https://git.eclipse.org/r/137086
Comment 7 Till Brychcy CLA 2019-02-17 10:00:00 EST
In patch set 2, I've re-optimised the implementation so the inner iteration is not over the incrementally computed result set, but just over the transitive modules computed in the last outer iteration (as was probably intended in the original implementation, where the outer iteration was done via recursion).

I haven't found any example tests with module-info. Is there any test-infrastructure for Java 9-related tests at all?
Comment 9 Fred Bricon CLA 2019-02-19 17:03:57 EST
Thanks for the fix Till.
Indeed I forgot we still don't have the test framework for Java 9+ projects. It's on my todo list.
Comment 10 Till Brychcy CLA 2019-07-10 12:35:32 EDT
*** Bug 525930 has been marked as a duplicate of this bug. ***
Comment 11 Denis Roy CLA 2021-04-19 13:23:16 EDT
Moved to https://github.com/eclipse-m2e/m2e-core/issues/