Compile Module that Depends on an External Jar

给你一囗甜甜゛ 提交于 2021-02-19 01:49:28

问题


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

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

All of that works. Now here's the problem:

The next thing I want to do is use an external library, so I added a few lines to Main.java:

Main.java - Updated

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!");
   }
}

I then placed commons-cli-1.4.jar in a new directory named lib.

Which created this file structure:

.:
build.sh  lib  src

./lib:
commons-cli-1.4.jar

./src:
com  module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java

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

How do I modify my project so I can compile against commons-cli-1.4.jar?


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

回答1:


You've placed the jar on the classpath because of which it results into an 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.

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;
}

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.



来源:https://stackoverflow.com/questions/53246066/compile-module-that-depends-on-an-external-jar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!