6

问题

你如何创建一个java库jar:

  • 是java模块(有module-info
  • 有一个依赖的遗留(非模块)jar。(如commons-exec)?

依赖项是一个实现细节 - 不应导出。

来源

具有以下build.gradle(使用gradle-6.8):

plugins {
    id 'java-library'
}

group = 'test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'

repositories {
    mavenCentral()
}
java {
    modularity.inferModulePath = true
}

dependencies {
    implementation 'org.apache.commons:commons-exec:1.3'
}

以及以下内容module-info.java

module test.module {
    requires commons.exec;
}

错误

我收到以下编译错误:

module-info.java:2: error: module not found: commons.exec
    requires commons.exec;
                    ^

如果我不包括requires commons.exec,则错误变为:

error: package org.apache.commons.exec is not visible
import org.apache.commons.exec.CommandLine;
                         ^
  (package org.apache.commons.exec is declared in the unnamed module,
   but module test.module does not read it)

commons.exec模块名称?

运行jar --file=commons-exec-1.3.jar --describe-module 确实输出:

No module descriptor found. Derived automatic module.

commons.exec@1.3 automatic
requires java.base mandated
contains org.apache.commons.exec
contains org.apache.commons.exec.environment
contains org.apache.commons.exec.launcher
contains org.apache.commons.exec.util

所以commons.exec看起来像一个有效的模块名称commons-exec-1.3.jar。Intelij Idea 似乎同意并在module-info.java. 虽然它在构建时失败。

4

1 回答 1

7

我设法使用java-module-info插件克服了同样的问题。

该插件允许您将模块信息添加到没有任何模块信息的 Java 库中。如果你这样做了,你可以给它一个正确的模块名称,Gradle 可以在编译、测试和执行期间将它拾取并放在模块路径上。

plugins {
   id 'java-library'
   id("de.jjohannes.extra-java-module-info") version "0.6"
}

将此部分添加到您的build.gradle以添加commons-exec模块信息

  extraJavaModuleInfo {
    module("commons-exec-1.3.jar", "org.apache.commons.exec", "1.3") {
        exports("org.apache.commons.exec")
    }
}

添加requires org.apache.commons.exec;到您的module-info.java

编辑 1

Gradle 7.0完全支持Java模块系统。用户现在可以通过Gradle构建、测试和运行 Java模块。仅仅存在就会让Gradle推断您的 jar 是一个模块,并且必须放在模块路径而不是传统的类路径上。module-info.java

使用不是模块的库

于 2021-03-28T19:08:21.660 回答