依赖于外部jar的编译模块

Jos*_*uaD 5 java javac jlink java-module java-11

使用 Java 11.0.1中的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
Run Code Online (Sandbox Code Playgroud)

src / com / greetings / Main.java

package com.greetings;

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

src /模块信息.java

module com.greetings { }
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

所有这些都可以。现在这是问题所在:

接下来要做的是使用一个外部库,因此我在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!");
   }
}
Run Code Online (Sandbox Code Playgroud)

然后,将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
Run Code Online (Sandbox Code Playgroud)

我修改了编译行以在类路径中包括commons jar:

javac -cp lib/commons-cli-1.4.jar:. \
-d mods/com.greetings \
src/module-info.java src/com/greetings/Main.java
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试编译它时,出现以下错误:

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
Run Code Online (Sandbox Code Playgroud)

如何修改项目,以便可以对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
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 2

您已将 jar 放在类路径上,因此它会生成未命名的模块。

未命名的模块导出其所有包。...

但是,这并不意味着命名模块中的代码可以访问未命名模块中的类型。...

此限制是有意为之的,因为允许命名模块依赖于类路径的任意内容将使可靠的配置变得不可能。

相反,尝试将相同的 jar 放在模块路径上,从那里可以将其推断为自动模块


您还需要确保模块的模块声明相应更新,以定义对新添加的模块的依赖关系来访问其导出的包。

module com.greetings { 
    requires commons.cli;
}
Run Code Online (Sandbox Code Playgroud)

编辑:在您的情况下尝试完整的build.sh仍然会失败,链接步骤中,因为存在自动模块