Java 9 automatic module dependencies cannot be resolved / module not found
Asked Answered
M

1

7

I'm trying to migrate some legacy applications to the new Java 9 module system, to strengthen its encapsulation.

I'm starting from the outside-in, with the assumption that classes on the periphery will have the least external dependencies.

As you'd expect, I've declared a very open module to start with:

module com.example.user {   
    exports com.example.user;
}

This instantly breaks the entire project (inside all classes), when suddenly every import for an external dependency no longer resolves (causing over 1k Java problems):

The import com.otherexample cannot be resolved

The import org.springframework cannot be resolved

etc.

Local packages in the same project com.example.price still work - as do java.util etc.

All of the external dependencies are (were) managed with Maven. In the (Eclipse project) build path, I can still see them as "Classpath" dependencies - but only the JRE system libraries in the "Modulepath".

Can the two concepts co-exist? Currently it seems by having a single module-info.java anywhere in the project, all classpath dependencies stop working?

I did read about using automatic modules, which seemed to imply you could use legacy / non-modular jars by including them in your modulepath, then referring to them by their filename. They use the example:

module com.foo.myapp {
  requires guava;  // guava not yet modularised, so use the filename
}

I couldn't find much other info, but this appears to match the convention Eclipse uses when it auto-generates a module-info.java for example:

spring-core-4.3.8.RELEASE.jar

becomes:

requires spring.core;

However, this still results in a Java error reported by Eclipse:

spring.core cannot be resolved to a module

Maven reports:

[ERROR] module-info.java:[39,16] error: module not found: spring.core

...and every class in the project with an external dependency is still broken.

Menken answered 25/10, 2017 at 18:34 Comment(5)
Do you get these Java import failures inside Eclipse or in Maven build? If you're using an Eclipse version that's not compatible with Java 9 then you might get these errors in Eclipse. Update to the latest one: marketplace.eclipse.org/content/java-9-support-beta-oxygenEskisehir
Both (and I'm using Eclipse Oxgen - with Java 9 support).Menken
Assuming you have spring-core as dependency in your pom, also ensure that you're using maven-compiler-plugin 3.7.0Enticement
To help grok the basics of Java 9, I suggest using the command-line first, then introducing Maven/Gradle, then introducing Eclipse. It will ultimately be quicker, in my experience.Bil
@Mikaveli I'm using Eclipse Oxgen - with Java 9 support .. I hope it's not Eclipse Oxygen 4.7.1a and as well as Java9 support(BETA)...in case you've upgraded Eclipse.. Otherwise, it would be good to see the project structure and its corresponding pom.xml content to see why its not working.Adhesive
M
7

Thanks to Robert Scholte for pointing out the updated maven-compiler-plugin 3.7.0 (I had been using 3.6.1), this really cleaned up the compile goal command-line output (with Java 9 specifics), to help me get to the route of the problem. This narrowed down the reported errors from every requires giving me the error to:

[WARNING] ********************************************************************************************************************
[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *
[WARNING] ********************************************************************************************************************
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 56 source files to ./target/classes
~~~ snip ~~~
[ERROR] module-info.java error: module not found: foo.bar

Matching Eclipse:

foo.bar cannot be resolved to a module

The errors appearing for just six automatic modules / libraries (jar) - rather than all (24) of them. Great.

In my POM, I'd split the output of source directories, to their own output directories (target/classes). However, as the module-info.java referred to dependencies (such as requires spring.core;) that are not used / referenced by the code (classes) in that folder - it couldn't resolve them.

Why? Basic Maven dependency management - I'd scoped those libraries outside of the default goal (to match the output directories split).

A fairly basic outcome - but I'd imagine I will not be the only person to encounter this as Java begins to encroach on some aspects of dependency management that overlap with the traditional use of Maven.

Menken answered 26/10, 2017 at 11:27 Comment(1)
I don't understand what you mean by "In my POM, I'd split the output of source directories, to their own output directories". Can you explain further? Or even better, could you provide an example of how POM should look like?Smashed

© 2022 - 2024 — McMap. All rights reserved.