Модуль компиляции, который зависит от внешнего JAR - PullRequest
0 голосов
/ 11 ноября 2018

Я рассмотрел простой пример , используя Project Jigsaw в Java 11.0.1, созданный с использованием Oracle JDK 11 в Ubuntu 18.04.

Следуя этому примеру, я создал простой проект, который компилируется в модуль, упаковывает модуль в jar, а затем использует jlink для создания автономного дистрибутива. Все работает - конечный результат - небольшая папка с урезанным JRE и моим модулем.

Проект состоит только из трех файлов и нескольких папок:

.:
build.sh  src

./src:
com  module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java

SRC / COM / приветствия / Main.java

package com.greetings;

public class Main {
   public static void main(String[] args) {
      System.out.println("Greetings!");
   }
}

ЦСИ / module-info.java

module com.greetings { }

build.sh

#/bin/bash

#clean up from last build
rm -rf greetingsapp mlib mods

#compile
javac -d mods/com.greetings src/module-info.java src/com/greetings/Main.java

#Make module jar
mkdir mlib
jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .

#build distribution
jlink --module-path /usr/lib/jvm/java-11-oracle/jmods/:mlib --add-modules com.greetings --output greetingsapp --strip-debug --no-header-files --no-man-pages --launcher greetings=com.greetings

#run
greetingsapp/bin/greetings

Все это работает. Теперь вот проблема:

Следующее, что я хочу сделать, это использовать внешнюю библиотеку, поэтому я добавил несколько строк в Main.java:

Main.java - Обновлено

package com.greetings;

import org.apache.commons.cli.CommandLine; //new line

public class Main {

   CommandLine line; //new line

   public static void main(String[] args) {
      System.out.println("Greetings!");
   }
}

Затем я поместил commons-cli-1.4.jar в новый каталог с именем lib.

Который создал эту файловую структуру:

.:
build.sh  lib  src

./lib:
commons-cli-1.4.jar

./src:
com  module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java

Я изменил строку компиляции, чтобы включить jar commons в classpath:

javac -cp lib/commons-cli-1.4.jar:. \
-d mods/com.greetings \
src/module-info.java src/com/greetings/Main.java

Однако, когда я пытаюсь его скомпилировать, я получаю эту ошибку:

src/com/greetings/Main.java:10: error: package org.apache.commons.cli is not visible
import org.apache.commons.cli.CommandLine;
                     ^
   (package org.apache.commons.cli is declared in the unnamed module, but module org.apache.commons.cli does not read it)
1 error

Как мне изменить мой проект, чтобы я мог скомпилировать с помощью commons-cli-1.4.jar ?


Редактировать, по предложению пользователя nullpointer, я попытался изменить флаг -cp просто на флаг -p, поэтому вместо этого в путь к модулю добавляется внешний jar. К сожалению, это тоже не работает. Вот различные команды javac, которые я пробовал, которые также не работают:

javac -p lib -d mods/com.greetings \
src/module-info.java src/com/greetings/Main.java

javac --module-path=lib -d mods/com.greetings \
src/module-info.java src/com/greetings/Main.java

javac -p lib/commons-cli-1.4.jar -d mods/com.greetings \
src/module-info.java src/com/greetings/Main.java

1 Ответ

0 голосов
/ 11 ноября 2018

Вы поместили банку в путь к классам, из-за чего он превратился в безымянный модуль. .

Безымянный модуль экспортирует все свои пакеты . ...

Это, однако, не означает, что код в названном модуле может обращаться к типам в неназванном модуле. ...

Это ограничение является преднамеренным, поскольку разрешение именованных модулей зависеть от произвольного содержимого пути к классу приведет к надежная конфигурация невозможна.

Вместо этого попробуйте поставить тот же сосуд на modulepath , откуда он может быть выведен как автоматический модуль .


Вам также необходимо убедиться, что объявление модуля вашего модуля соответствующим образом обновлено, чтобы определить зависимость от вновь добавленного модуля для доступа к его экспортированным пакетам.

module com.greetings { 
    requires commons.cli;
}

Редактировать : проверка полного build.sh в вашем случае все равно не удалась бы, , но при соединении шаг , из-за наличия автоматического модуля .

...