Как использовать модульные банки в не модульном приложении?

В разных местах я видел следующую информацию: Классы внутри безымянного модуля могут читать экспортированные пакеты по пути к модулю.

Внутри каталога src/calculators у меня есть файл module-info.java:

module calculators {
  exports calculators;
}

Внутри каталога src/calculators/calculators у меня есть файл InterestCalculator.java:

package calculators;

public interface InterestCalculator {

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

Я скомпилировал модуль с помощью следующей команды:

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

Затем я упаковал скомпилированный модуль с помощью следующей команды:

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

Теперь мое не модульное приложение имеет следующие классы (в том же каталоге):

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();

  }
}

Когда я пытаюсь скомпилировать свое приложение, используя модуль с командой:

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

Я получил ошибку:

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

Почему? Разве классы приложений не должны иметь возможность читать экспортированные пакеты? Что я здесь делаю неправильно?


person krionz    schedule 07.03.2020    source источник


Ответы (2)


Поскольку код вашего приложения не является модулем, в среде нет ничего, что говорило бы Java о разрешении модуля calculators. Это приводит к тому, что классы не обнаруживаются, несмотря на то, что файл JAR помещен в путь к модулю. Если вы хотите продолжить использовать путь к модулю для своей библиотеки, вам нужно использовать:

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

Обратите внимание на аргумент --add-modules calculators. Это делает модуль calculators корневым, принудительно помещая его и все его requires зависимости (транзитивно) в граф модуля. Если ваше приложение должно было быть модульным:

module app {
  requires calculators;
}

Тогда вам больше не понадобится --add-modules, потому что модуль app будет корневым, а для него требуется модуль calculators.

person Slaw    schedule 07.03.2020

Короткий ответ

Ваша последняя командная строка должна быть:

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

вместо:

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

Почему?

Если вы компилируете немодульное приложение, вам следует использовать не --module-path, а --class-path (или более короткую версию: -cp).

Помните, что модульный JAR по-прежнему работает как обычный JAR. Он просто содержит дополнительную информацию для модульных приложений.

person Gustavo Passini    schedule 07.03.2020