8

In order to understand the categories we have:

  • platform explicit modules
  • application explicit modules
  • open modules
  • automatic modules
  • unnamed module

All classes and jars within the classpath will be part of the unnamed module. But why is that what we need? Where is the advantage over automatic modules? I could "require" those damn legacy jars to make them to an automatic module. Do I not have included everything with it?

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
Daniel
  • 557
  • 5
  • 17
  • 2
    Listing open modules in that enumeration is a little weird because they are included in "application explicit modules". – Nicolai Parlog Jul 18 '17 at 12:42
  • Can somebody that understands this question please edit it to use proper grammar in the title and body? I don't understand it at all the way it's written. For example, why would there be a dichotomy between "using the classpath" and "abusing auto modules"? – Novaterata Jul 18 '17 at 14:23
  • 1
    The classpath (i.e. unnamed module) remains primarily so that legacy code will still work as before. It would be crazy to ask the massive Java community to deal with the modulepath/automatic modules as a breaking change. – Michael Easter Jul 18 '17 at 14:35
  • 1
    I can update the question. @user3305489: I guess you're asking why Java 9 does not simply turn all JARs on the class path into automatic modules? – Nicolai Parlog Jul 18 '17 at 14:40
  • Finally, I found the edit functionality :D – Daniel Jul 18 '17 at 15:19
  • 1
    And now you have a name, too! Welcome to StackOverflow. :) – Nicolai Parlog Jul 18 '17 at 15:24

2 Answers2

10

There are at least two reasons:

  • Just as regular modules, automatic ones are suspect to certain examinations by the module system, e.g. not splitting packages. Since JARs on the class path can (and occasionally do) split packages, imposing that check on them would be backwards-incompatible and break a number of applications.
  • The unnamed module can read all platform modules, whereas automatic modules can only read those that made it into the module graph. That means a JAR needing the java.desktop module (for example) will work from the class path but not from the module graph unless java.desktop also makes it into the graph (via a dependency or --add-modules).

I have no time right now to check the second but that's what the State of the Module system says:

After a module graph is resolved, therefore, an automatic module is made to read every other named module, whether automatic or explicit

Resolution works on the declared dependencies and an automatic modules declares none.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255
  • That leads me back to the same question that I already wrote in another thread. I repeat it: Alex Buckley told us at devoxxUS (Modular Development with JDK 9) automatic modules: "... Requires everything, they require each other, they require all modules in the jdk image and they require all of your modules as well, and they export their packages..." (The quote is similar what he said). Does it not mean java.desktop is accessible inside the automatic module-a when its need this dependency? – Daniel Jul 18 '17 at 13:48
  • 1
    Maybe he said "reads" instead of "requires"? Anyways, I updated my answer. – Nicolai Parlog Jul 18 '17 at 14:03
  • He said "requires" youtu.be/rfOjch4p0Po?t=31m But the behavior that I can see is what you mean. The automatic-modules declare nothing, but they are ready to use dependencies from the module graph when those were added by an explicit module. – Daniel Jul 18 '17 at 15:39
0

Apart from the items listed in the accepted answer, there is one more difference: unnamed modules can access all packages of modules that come with Java, even is they are not exported. As long the class is public, access will work - the same as before Java 9. But as soon as a jar is run from module path, it will be able to access only exported packages.

For example if some .jar has this code:

com.sun.jmx.remote.internal.ArrayQueue c = new com.sun.jmx.remote.internal.ArrayQueue(10);

it will run normally without any warnings when placed on class path, but when run from module path (as automatic module) it will fail at runtime:

Exception in thread "main" java.lang.IllegalAccessError: class test1.C 
(in module test1) cannot access class com.sun.jmx.remote.internal.ArrayQueue 
(in module java.management) because module java.management does not export 
com.sun.jmx.remote.internal to module test1

Note that this is different from the well known illegal reflective access warning, which is about using reflection to access private fields or methods. Here we are statically (non-reflectively) accessing public class (but from non-exported package).

Ivan
  • 1,552
  • 1
  • 16
  • 25