Search code examples
javajava-module

Java module encapsulation demo


I try to create a demo to illustrate module encapsulation. I have 2 classes a.A and b.B in separate modules. module a requires b, and b is exported to a

package a;
import b.B;
class A{
    public static void main(String[] args){
        B b = new B();
    }
}
package b;
public class B{
    public B(){
        System.out.println("B created");
    }
}
module a {
  requires b;
}
module b {
  exports b to a;
}
├───class
├───jar
└───src
    ├───a
    │   └───module-info.java
    │   └───a
    │       └───A.java
    ├───b
    │   └───module-info.java
    │   └───b
    │       └───B.java

It works

>javac -d class --module-source-path src -m a
>jar -c -f jar/a.jar -e a.A -C class/a .
>jar -c -f jar/b.jar  -C class/b .
>java -p jar -m a
B created

However, why I am able to access b.B from some other class in package default

import b.B;
class C{
    public static void main(String[] a){
        B b = new B();  
    }
} 
>javac -cp ".;jar/b.jar" C.java
>java -cp ".;jar/b.jar" C
B created

openjdk version "17.0.1" 2021-10-19


Solution

  • Firstly, as far as I can see, you didn't explicitly put C in a module. It is therefore in the "unnamed module". The unnamed module can read every observable module.

    An unnamed module reads every observable module

    It is designed this way so that old, non-modular code can still interact with new code.

    Secondly, B is also in the unnamed module when you run C. This is because you put b.jar into the classpath, not the module path (--module-path). In the modular world, you should use the module path to specify where the dependencies are, not the classpath.