编译依赖于外部 Jar 的模块

Compile Module that Depends on an External Jar

我在 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 放在类路径中,因此它会生成 unnamed module.

The unnamed module exports all of its packages. ...

It does not, however, mean that code in a named module can access types in the unnamed module. ...

This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.

而是尝试将相同的 jar 放在 modulepath 上,从那里可以推断出它是 automatic module.


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

module com.greetings { 
    requires commons.cli;
}

Edit:在你的情况下尝试完整的 build.sh仍然失败,但是链接步骤