12

Is it possible to have 2 modules with the exact same name (but with slightly different contents) on the module path?

As far as I can tell, the Java 9 compiler does not complain about it. I have 2 modules declared as follows:

module com.dj.helper {
    exports com.dj.helper;
}

Both contain the com.dj.helper package but within the package the contents are different. Then in my main application, I am looking to import this module:

module com.dj {
    requires com.dj.helper;
}

Both modules with the same name are on my module path.

I was hoping that when compiling my com.dj module that the compiler would complain about the same module existing twice but it does not. Does this effectively mean you could have 2 versions of the same jar on your module path and Java will not know which one to use?

Naman
  • 27,789
  • 26
  • 218
  • 353
DJ180
  • 18,724
  • 21
  • 66
  • 117

2 Answers2

8

No

It is not possible to have two modules of the same name in the same directory on the module path. The official documentation is not putting that information in a particularly prominent spot - it's the Javadoc of ModuleFinder::of that gives it away:

It is an error if a directory contains more than one module with the same name.

I've created a small demo project for the module system and it covers that case by creating two versions of the same module...

jar --create
    --file mods/monitor.observer.beta-1.0.jar
    --module-version 1.0
    -C classes/monitor.observer.beta .
jar --create
    --file mods/monitor.observer.beta-2.0.jar
    --module-version 2.0
    -C classes/monitor.observer.beta .

... and then referencing the folder in the next compilation ...

javac
    --module-path mods
    -d classes/monitor.statistics
    $(find monitor.statistics -name '*.java')

... which as expected leads to the following error message:

error: duplicate module on application module path
module in monitor.observer.beta
1 error

Note that I said in the same directory. Across directories multiple modules are possible.

Yes

The module system only enforces uniqueness within directories. Once again from ModuleFinder::of (emphasis mine):

The module finder locates modules by searching each directory, exploded module, or packaged module in array index order. It finds the first occurrence of a module with a given name and ignores other modules of that name that appear later in the sequence.

That makes it possible to have the same module in different directories.

kaartic
  • 523
  • 6
  • 24
Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • Could it be because the restriction only applies to same modules only in the same directory? This is how I understood the spec in both the JEP and the page you linked. – M A Oct 04 '17 at 21:15
  • 1
    Shouldn't your monitor.statistics module have a dependency on monitor.observer.beta? – DJ180 Oct 04 '17 at 21:35
  • @manouti Oh, you're absolutely right! I forgot about that. Will update the answer. – Nicolai Parlog Oct 05 '17 at 06:02
  • @DJ180 The fun part is that it breaks even without that dependency. – Nicolai Parlog Oct 05 '17 at 06:02
  • That is what confuses me! – DJ180 Oct 05 '17 at 12:18
  • Can you explain why it failed with the error message in your example? – DJ180 Oct 05 '17 at 14:26
  • You mean why it failed even though the module is not required? Because the module systems wants each folder to be unambiguous. One technical reason is service binding, which can lead to modules being resolved that are not directly required. But I think the philosophical reason that a folder containing the same module twice surely being a mistake is the more important one. – Nicolai Parlog Oct 05 '17 at 15:06
5

JEP 261 of the module system describes the module path as follows:

A module path is a sequence, each element of which is either a module definition or a directory containing module definitions. Each module definition is either

  • A module artifact, i.e., a modular JAR file or a JMOD file containing a compiled module definition, or else

  • An exploded-module directory whose name is, by convention, the module's name and whose content is an "exploded" directory tree corresponding to a package hierarchy.

It then describes the module resolution mechanism:

When searching a module path for a module of a particular name, the module system takes the first definition of a module of that name. Version strings, if present, are ignored; if an element of a module path contains definitions of multiple modules with the same name then resolution fails and the compiler, linker, or virtual machine will report an error and exit. It is the responsibility of build tools and container applications to configure module paths so as to avoid version conflicts; it is not a goal of the module system to address the version-selection problem.

As explained, it means that the compiler will complain only if two modules with the same name exist in the same directory.

Community
  • 1
  • 1
M A
  • 71,713
  • 13
  • 134
  • 174
  • 1
    What is meant by a directory in the context of a jar file? I think this line is telling: "module system takes the first definition of a module of that name". Surely this means that we can still have a lot of runtime classpath issues? – DJ180 Oct 04 '17 at 21:33
  • @DJ180 The directory referred to in the spec is a directory that contains module definitions (i.e. a modular Jar, or an exploded directory containing the module definition file and the packages). It remains not clear to me if this would cause runtime issues (I haven't experimented yet with such cases). – M A Oct 05 '17 at 07:28