我研究了Java 11.0.1中的simple example using Project Jigsaw,该语言是在Ubuntu 18.04上使用oracle JDK 11构建的。
在该示例之后,我创建了一个简单的项目,该项目可编译为模块,将该模块打包到jar中,然后使用jlink
创建独立的发行版。一切正常-最终结果是一个很小的文件夹,其中包含简化的JRE和我的模块。
该项目仅由三个文件和一些文件夹组成:
.:
build.sh src
./src:
com module-info.java
./src/com:
greetings
./src/com/greetings:
Main.java
src / com / greetings / Main.java
package com.greetings;
public class Main {
public static void main(String[] args) {
System.out.println("Greetings!");
}
}
src / 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
我修改了编译行,以在类路径中包含commons jar:
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
答案 0 :(得分:2)
您已将jar放在类路径上,因此它会导致生成unnamed module.。
未命名的模块将导出其所有软件包。 ...
但这并不意味着已命名模块中的代码可以访问未命名模块中的类型。 ...
此限制是有意的,因为允许命名模块依赖于类路径的任意内容将使 可靠的配置是不可能的。
相反,请尝试将相同的jar放在 modulepath 上,从那里可以将其推断为automatic module。
您还需要确保相应地更新模块的模块声明,以定义对新添加的模块的依赖以访问其导出的软件包。
module com.greetings {
requires commons.cli;
}
编辑 :在您的情况下尝试完整的 build.sh 仍然会失败,但但是 链接步骤,because of the presence of an automatic module。