1

I have a standard monolithic Spring Java project which gets packaged as a war (with our code in class files within the war, not in a single jar) and deployed into a Tomcat. We have different Spring profiles allowing the same war to be deployed on different instances for different use cases. The project is built with Maven with all source in src/main/java.

As part of the work to move away from the legacy structure, we are hoping to start using Java modules for new code, and over time refactor stuff out of the legacy structure into new modules covering core and profile-specific functions.

I am trying to add new code to a new folder src/main/v2, to which I have also added a module-info.java file. I have done the same for v2-util, which gives:

src/main/java/com/mycompany/MyClass.java
src/main/v2/com/mycompany/MyV2Class.java
src/main/v2/module-info.java
src/main/v2-util/com/mycompany/v2-util/MyV2UtilityClass.java
src/main/v2-util/module-info.java
pom.xml

Note that src/main/java doesn't have a module-info.java file. This is because the dependency graph for the legacy project is complicated and is full of things that become automatic modules or have split packages. Putting in place a src/main/java/module-info.java declaration has proved impossible and time-consuming, due mainly to split packages on third-party jars from the same provider.

Trying to compile the above structure works: Maven finds the new Java classes, but it seems that the v2/module-info.java declaration is forcing the compiler to insist on a module for the legacy stuff in java/. I'm seeing lots of "package X is declared in the unnamed module, but module X does not read it", meaning the build fails.

What I want to happen is that new code in module v2 above can access:

  • anything in the legacy code
  • only what is exposed by the v2-util module.

My guess is that I'm misunderstanding how the module system works, and what I want to do is impossible.

One important point: I haven't set up any kind of Maven module system, I have simply used the build-helper-maven-plugin to tell it about the new source folders.

What is the best way to proceed?

Rich
  • 15,602
  • 15
  • 79
  • 126

1 Answers1

0

I did not understand the module-system either. From what I can tell is that the runtime is currently ignoring the module-system for the compatiblity-reasons. So lets check the compilation-process.

I have a spring (non-springboot) application and made some adjustments to the compiler in maven:

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
(...)
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.0</version>
                <configuration>
                    <compilerArgs>
                        <arg>--add-exports</arg>
                        <arg>java.base/sun.security.rsa=ALL-UNNAMED</arg>
                        <arg>--add-exports</arg>
                        <arg>java.base/sun.security.util=ALL-UNNAMED</arg>
                        <arg>--add-exports</arg>
                        <arg>java.base/sun.security.x509=ALL-UNNAMED</arg>
                        <arg>--add-opens</arg>
                        <arg>java.base/java.lang=ALL-UNNAMED</arg>
                    </compilerArgs>
                </configuration>
            </plugin>

For libraries that was part of the JDK in the past and has been excluded from the JDK 9> there are module-replacement as official dependencies in maven (see Replacements for deprecated JPMS modules with Java EE APIs ).

Make sure those module-replacements have the scope "provided" to avoid having classcastexceptions.

Grim
  • 1,938
  • 10
  • 56
  • 123