16

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?

Naman
  • 27,789
  • 26
  • 218
  • 353
learner
  • 332
  • 2
  • 6
  • 22
  • 1
    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). – Naman Aug 17 '18 at 04:38
  • 1
    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. – learner Aug 17 '18 at 06:05
  • 3
    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](https://bugs.openjdk.java.net/browse/JDK-8233524). – Marcono1234 Oct 24 '21 at 16:20

1 Answers1

13

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.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 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? – learner Aug 17 '18 at 06:09
  • 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? – learner Aug 17 '18 at 06:16
  • 1
    @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](https://stackoverflow.com/a/46501811/1746118) from me. – Naman Aug 17 '18 at 06:16
  • 1
    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.. – learner Aug 17 '18 at 06:26
  • 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 ? – learner Aug 17 '18 at 06:46
  • 1
    *"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. – Naman Aug 17 '18 at 18:57
  • 1
    *"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. – Naman Aug 17 '18 at 18:59
  • 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? – learner Aug 18 '18 at 04:29
  • @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. – Naman Aug 18 '18 at 05:10
  • 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. – learner Aug 18 '18 at 07:53
  • *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. – Naman Aug 18 '18 at 10:33
  • 1
    Yes my doubt is clear now. Thanks a lot. But yeah facing some different issue.will open a diff thread. – learner Aug 18 '18 at 12:41