【问题标题】:Noname module issue with gradle dependency (Java 9)gradle 依赖的 Noname 模块问题(Java 9)
【发布时间】:2021-07-01 08:21:37
【问题描述】:

我正在尝试将现有的 JavaFX 应用程序移植到 Java 9。

这里是 build.gradle

plugins {
    id 'application'
    id 'java'
    id 'org.openjfx.javafxplugin' version '0.0.9'
}

repositories {
    mavenLocal()
    maven {
        url = uri('https://repo.maven.apache.org/maven2/')
    }
    flatDir {
        dirs 'libs'
    }
}

group = 'ru.mydomain.myapp.fx'
version = '0.7'
description = 'myAppFX'
java.sourceCompatibility = JavaVersion.VERSION_1_9

java {
    modularity.inferModulePath = true
}

sourceSets {
    main {
        java {
            srcDirs("src/common/java", "src/fx/java")
        }
        resources {
            srcDirs = ['src/fx/resources']
        }
    }
}

dependencies {
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'com.j256.ormlite:ormlite-jdbc:5.0'
    //blah-blah
}

javafx {
    version = "15.0.1"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.swing']
}
application {
    mainModule = 'mymodule.javafx'
    mainClass = 'ru.mydomain.myapp.fx.Main'
}

我的模块声明:

module mymodule.javafx {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.swing;
    requires slf4j.api;
    requires ormlite.jdbc;

    // Export the package (needed by JavaFX to start the Application)
    // Replace "exports" with "opens" if "@FXML" is used in this module
    opens ru.mydomain.myapp.fx;

}

问题出在 gradle 依赖项中声明的库生成的未命名模块中。在这种特殊情况下使用slf4j。是的,每当我使用带有声明 module-info.java 的新库时,它都是可以解决的,但如果我使用没有 module-info.java 的旧库时,我会收到如下错误消息:

错误:找不到模块:slf4j.api/ormlite.jdbc/etc...

据我了解,问题出在所谓的自动/未命名模块中。

任何想法,如何解决依赖库生成的无名模块的这个问题?

更新

探索com.j256.ormlite:ormlite-jdbc:5.0的依赖

  1. 清单中不包含任何Automatic-Module-Name
  2. 确切的 jar 名称是:ormlite-jdbc-5.0.jar
  3. 双重检查 - 它在编译类路径中
  4. 确切的错误信息是:
    module-info.java:7: error: module not found: ormlite.jdbc
    requires ormlite.jdbc;
                    ^

【问题讨论】:

    标签: java gradle javafx module java-9


    【解决方案1】:

    让我们把问题分解为最基本的问题:这是一个 Java 模块问题,它与 Gradle 或 JavaFX 几乎无关。所以我们只需要检查 Java 模块文档来找出我们能做什么。

    我读到的是:总是有一个模块名称。如果 jar 完全没有提供任何内容,则模块的名称就是没有 .jar 扩展名的 jar 文件的名称。不过还有更多内容,名称派生的确切规则可以在here 中找到。我会引用它以防万一链接断开:

    “.jar”后缀被删除。

    如果名称与正则表达式“-(\d+(\.|$))”匹配,则 模块名称将派生自连字符之前的子序列 的第一次出现。连字符后的子序列被解析为 一个版本,如果它不能被解析为一个版本,则忽略它。

    模块名称中的所有非字母数字字符 ([^A-Za-z0-9]) 都是 替换为一个点(“.”),所有重复的点都替换为一个 点,并且所有前导和尾随的点都被删除。

    例如,名为“foo-bar.jar”的 JAR 文件将派生一个模块 名称“foo.bar”并且没有版本。一个名为的 JAR 文件 “foo-bar-1.2.3-SNAPSHOT.jar”将派生一个模块名称“foo.bar”和 “1.2.3-SNAPSHOT”作为版本。

    所以你需要改变那个 requires 语句来匹配自动命名规则。

    但当然最好使用不属于古代历史的 jar 版本...

    这里有一个nice blog关于自动模块命名,如果还有疑问。

    【讨论】:

    • 所以根据这些规则,依赖 com.j256.ormlite:ormlite-jdbc:5.0 应该被翻译成名为 ormlite.jdbc 的模块,对吗?
    • 从表面上看,这是我的解释。
    • 嗯...但它不起作用,编译器报告模块 ormlite.jdbc 不存在
    • 确实如此。相当的僵局。当然,找不到模块的另一种解释是因为 jar 实际上不在类路径中......也许更新您的问题以提供您收到的实际和完整的错误消息。
    • 也许还可以查看罐子本身,看看它们是否不包含链接文章提到的清单中的那个鬼鬼祟祟的“Automatic-Module-Name”行?
    猜你喜欢
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2013-06-14
    相关资源
    最近更新 更多