How to use modularized jars in a not modularized application?

597 views Asked by At

In various places i saw the following information: The classes inside the the unnamed module are allowed to read exported packages on the module path.

Inside the directory src/calculators i have the module-info.java file:

module calculators {
  exports calculators;
}

Inside the directory src/calculators/calculators i have the InterestCalculator.java file:

package calculators;

public interface InterestCalculator {

  public double calculate(double principle, double rate, double time);
}

I have compiled the module with the following command:

java --module-source-path src --module calculators -d out

And then i have packaged the compiled module with the following command:

jar --create --file calculators.jar -C out/calculators/ .

Now my not modularized application have the following classes ( in the same dir ):

import calculators.InterestCalculator;

class SimpleInterestCalculator implements InterestCalculator {

  public double calculate(double principle, double rate, double time){
    return principle * rate * time;
  }
}
import calculators.InterestCalculator;

class Main {
  public static void main(String[] args) {
    InterestCalculator interestCalculator = new SimpleInterestCalculator();

  }
}

When i try to compile my application using the module with the command:

javac --module-path calculators.jar  *.java

I got the error:

Main.java:1: error: package calculators is not visible
import calculators.InterestCalculator;
       ^
  (package calculators is declared in module calculators, which is not in the module graph)
SimpleInterestCalculator.java:1: error: package calculators is not visible
import calculators.InterestCalculator;
       ^
  (package calculators is declared in module calculators, which is not in the module graph)
2 errors

Why? Should not the application classes be able to read the exported packages? What am i doing wrong here?

2

There are 2 answers

0
Slaw On BEST ANSWER

Since your application code is not a module there's nothing in the environment telling Java to resolve the calculators module. This results in the classes not being found despite placing the JAR file on the module-path. If you want to continue using the module-path for your library, you need to use:

javac --module-path calculators.jar --add-modules calculators <rest-of-command>

Notice the --add-modules calculators argument. This makes the calculators module a root, forcing it and all its requires dependencies (transitively) into the module graph. If your application was to be made modular:

module app {
  requires calculators;
}

Then you would no longer need --add-modules because the app module would be a root and it requires the calculators module.

0
Gustavo Passini On

Short answer

Your last command line should be:

javac --class-path calculators.jar  *.java

instead of:

javac --module-path calculators.jar  *.java

Why?

If you are compiling a non-modular application, you should not use --module-path option, but --class-path (or the shorter version: -cp).

Remember that a modular JAR still works like a regular JAR. It just contains some more information for modular applications.