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

查看:168
本文介绍了依赖于外部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 进行编译?

编辑,根据用户nullpointer的建议,我尝试将-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..

未命名的模块将导出其所有软件包. ...

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

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

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 上,从中可以将其推断为

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 仍然会失败,但但是 链接步骤由于存在自动模块.


Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.

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

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