编译依赖于外部 Jar 的模块 [英] Compile Module that Depends on an External Jar

查看:33
本文介绍了编译依赖于外部 Jar 的模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Java 11.0 中完成了一个使用 Project Jigsaw 的简单示例.1、在 Ubuntu 18.04 上使用 oracle JDK 11 构建.

I worked through a simple example using Project Jigsaw in Java 11.0.1, built using the oracle JDK 11 on Ubuntu 18.04.

按照那个例子,我创建了一个简单的项目,它编译成一个模块,将模块打包成一个 jar,然后使用 jlink 创建一个独立的发行版.一切正常——最终结果是一个带有精简 JRE 和我的模块的小文件夹.

Following that example, I have created a simple project which compiles to a module, packages the module into a jar, and then uses jlink to create a standalone distribution. Everything works -- the end result is a smallish folder with a stripped down JRE and my module.

该项目仅由三个文件和一些文件夹组成:

The project is made of only three files and some folders:

.:
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 中添加了几行:

The next thing I want to do is use an external library, so I added a few lines to 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 的新目录.

I then placed commons-cli-1.4.jar in a new directory named 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:

I modified the compile line to include the commons jar in the classpath:

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

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

However, when I try to compile it, I get this error:

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 进行编译?

编辑,在用户空指针的建议下,我尝试将 -cp 标志更改为 -p 标志,因此外部 jar 被添加到模块路径中.不幸的是,这也不起作用.以下是我尝试过的各种 javac 命令也不起作用:

Edit, at the suggestion of the user nullpointer, I tried changing the -cp flag to just a -p flag, so the external jar is added to the module path instead. Unfortunately, that also doesn't work. Here are the various javac command I tried that also do not work:

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 放在类路径上,因此它会生成一个 未命名模块..

You've placed the jar on the classpath because of which it results into an unnamed module..

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

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

这个限制是有意的,因为允许命名模块依赖于类路径的任意内容会使可靠的配置是不可能的.

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

Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.

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

You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.

module com.greetings { 
    requires commons.cli;
}

<小时>

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

这篇关于编译依赖于外部 Jar 的模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆