【发布时间】:2018-11-11 05:22:15
【问题描述】:
我在 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
【问题讨论】:
-
如果您已将 jar 指定在模块路径上并将其从类路径中删除,则理想情况下它不应保留在未命名的模块中。你能用你的新 javac 命令行更新这个问题吗?
-
确保您的模块声明现在需要该模块 ...尝试一下,注意到
commons-cli:commons-cli:1.4的模块名称需要requires commons.cli;,你能看看这个? -
您这样做是为了学习还是为了完成任务?对于实际使用的工作,采用 Maven 还是 Gradle?
-
Chrylis:现在学习。下一步是转换一个现有的大型项目,我现在正在熟悉构建模块。每次我在那里遇到问题时,我都会把它提炼到这个测试环境中,理解它,然后将它应用到大型项目中。该项目目前使用 Ant,但我可能正在过渡到 Gradle。
-
@JoshuaD 将
jlink与自动模块一起使用的最后一步恐怕是我到目前为止还没有看到人们采用的方法。除此之外,其余部分应该可以正常工作。我尝试了您的设置并且可以使用它,因此made an answer。
标签: java javac java-module java-11 jlink