Java 9 migration issue - package com.mymodule is declared in unnamed module , module 'newmodule' does not read it
Asked Answered
R

1

20

I have created a multimodule project with the following structure

    myproject
      |- mymodule
         |- src
            |- main
               |- java
                  |- com
                     |- mymodule
                        |- Util.java

      |-newmodule
         |-src
           |-main
             |-java
               |-com
                 |-newmodule
                    |- Main.java
             |-module-info.java

Now i want to use Util.java which is a non modularized code in a modularized module newmodule. i have declared following in newmodule

module newmodule {
    requires mymodule;
}

Project is compiling fine, but Intellij is showing module not found and package com.mymodule is declared in unnamed module , module 'newmodule' does not read it.

How to resolve this issue?

And one more question does all the old non modular code is by default turn into automatic-module in java 9 if i don't even modularized legacy modules?

Righthander answered 17/8, 2018 at 4:0 Comment(3)
by any chance, are these maven sub-modules? and both of them are compiled using IntelliJ? The reason, why I am asking this is, one clear way to resolve this is to make the mymodule as an explicit module with module-info.java in it as well(exports the package as well).Oiler
Hi, Actually I don't want to modularize the module named "mymodule" as this is a legacy code. but i want to use Util.java from mymodule in newmodule which is modularized. And yes this is a maven project and i have also declared automatic-module-name for the mymodule in its pom.xml. Sorry i forgot to mention these earlier.Righthander
Note: Depending on the JDK version you are using the javac error might incorrectly use the package name as module name as well, e.g. "package mypackage is declared in the unnamed module, but module mypackage does not read it", see JDK-8233524.Forwards
O
15

One clear way to resolve this is to make the mymodule as an explicit module as well. This would just be the ideal world of modules I would say.

You can do that by including a module-info.java in mymodule as well, something like -

module mymodule {
    exports com.mymodule;
}

does all the old non modular code is by default turn into automatic-module in java 9 if i don't even modularized legacy modules?

The concept of both the unnamed module and automatic module is to aid the migration and provide the compatibility with the existing classpath techniques.

On one hand, the dependencies of your module which are still not themselves modular and you would still rely on them being one, can be used on the module path for the module system to implicitly define them, when treated as automatic modules and bridge the bottom-up migration expected by JPMS.

The unnamed modules on the other hand relies on the type that is not defined in any module and is resolved to be still found on the classpath. This ensures that every type resolved is part of some module(if nothing then the unnamed module) and also provides the compatibility such that code of existing applications relying on the classpath shall compile and run similarly on module system as well.


The reason, why you would fail to declare an explicit dependence in your code is stated clearly in the doc:-

The unnamed module exports all of its packages. This enables flexible migration, as we shall see below. It does not, however, mean that code in a named module can access types in the unnamed module. A named module cannot, in fact, even declare a dependence upon the unnamed module. This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.

Oiler answered 17/8, 2018 at 4:41 Comment(12)
okay so. if i want to use my non modularized legacy code as utility in my new modular code, i won't be able to use that as that is defined in unnamed module. But if i want to make those legacy code as automatic-module without doing the modularization. Then how to do that?Righthander
And how java identified a module as automatic-module ? As per i know java takes the automatic-module-name if mentioned else creates the name from jar file. So how does it know that it has be considered as automatic-module?Righthander
@user10237300 Simplest way that I know of is to create a jar out of your existing code and introduce that as a dependency to your modular code. "How does JPMS know"... is explained in detail in the link shared in the answer. Related to making sure the artifact is used with correct automatic module name refer to this answer from me.Oiler
Okay.. so basically if i mention the automatic-module-name in the pom.xml (mymodule) within the maven-jar-plugin and mention the maven dependency in the pom.xml of the new_module which is modularized infact, then the mymodule should be imported as automatic-module in new_module. Is my notion correct? Thank you so much for your help. Because i did the same in my project i mentioned earlier and it compiled fine through cmd, but through intellij it is giving error..Righthander
So basically every old legacy code from unnamed module will be turned into automatic-module if i mentioned that i do manifest entry while creating the jar file ?Righthander
"So basically every old legacy code from unnamed module will be turned into automatic-module if i mentioned that i do manifest entry while creating the jar file"...only when that jar file is available at the modulepath of your application relying on it.Oiler
"mention the maven dependency in the pom.xml of the new_module which is modularized infact, then the mymodule should be imported as automatic-module in new_module. Is my notion correct? "...correct unless you've explicitly made that mymodule as a modular application itself.Oiler
I have another more doubt, if I don't mention the automatic module name in manifest then also the the jar is imported as automatic module in the modular application. Then what is the difference between automatic module or unnamed? Does only mentioning in the manifest will suffice for the non modular module work with many modular one?Righthander
@user10237300 The jar on module path would anyway be treated as automatic module, just that the entry in the Manifest would be a determined way of declaring something like this would be my module's name whenever it becomes modular...or else, the module system would still try to derive the name from the jar name. And the difference between the unnamed module and automatic module has been clearly stated in the answer, please re-read. I suggest understanding the doc linked in the answer, would help you a lot understanding the concept.Oiler
thanks for your help.But i still didn't get my doubt cleared. If i have a non modular code and one modular code which depends on the non modular one, then how can i turn the non modular code into automatic module so that i can use it in the modular code . I understand that if i don't even mention that in manifest for jar plugin jdk will automatically infer the module name , but how to do that through maven? how to place it on module path through maven ? I don't want to do it from cmd actually. Using maven i am getting error through intellij ..Please help.Righthander
but how to do that through maven?.. just include the non-modular code as a dependency in your modular code's pom.xml...*how to place it on module path through maven?*... in your modular code once you introduce the module-info.java, you would get the dependencies on the module-path... and ideally when you face further some issue you should open another thread on StackOverflow :) if the current doubts were clear by the answer, would suggest accepting the answer and then go ahead and try out things further.Oiler
Yes my doubt is clear now. Thanks a lot. But yeah facing some different issue.will open a diff thread.Righthander

© 2022 - 2024 — McMap. All rights reserved.