错误:";包被声明为';javafx.beans.value';模块内';foo.bar'&引用;

错误:";包被声明为';javafx.beans.value';模块内';foo.bar'&引用;,java,java-module,java-platform-module-system,java-11,javafx-11,Java,Java Module,Java Platform Module System,Java 11,Javafx 11,我开发了一个库,module info.java如下所示: module foo.bar { requires org.apache.commons.lang3; requires javafx.base; requires java.validation; exports foo.bar; } 此库用于另一个项目,其中模块info.java包含以下内容: module other.project { requires org.apache.commons.lang3;

我开发了一个库,
module info.java
如下所示:

module foo.bar {
  requires org.apache.commons.lang3;
  requires javafx.base;
  requires java.validation;
  exports foo.bar;
}
此库用于另一个项目,其中
模块info.java
包含以下内容:

module other.project {
  requires org.apache.commons.lang3;
  requires javafx.base;
  requires javafx.graphics;
  requires javafx.fxml;
  requires foo.bar;
}
当我尝试使用
导入javafx.beans.value.WritableValue时我得到了错误

javafx.beans.value
是在
foo.bar
中声明的,它没有 将其导出到模块
other.project

更新:我创建了两个重现问题的示例项目。请找到他们下载


我不明白这是为什么,但我找不到解决方案。

根据发布的项目,打开项目时出现的错误是:

包“javafx.beans.property”在模块“com.example.external.lib”中声明,该模块不会将其导出到模块“example.project”

出现此错误的原因是您正在将
javafx.base
中的一些包添加到外部库中,但这些包没有导出到使用此库的项目中。
javafx.beans.property
包由外部模块在内部使用,但无法导出

因此,这些是一些建议的改变,以使其发挥作用

如果您正在创建一个模块化jar(使用
模块信息
类)作为另一个项目的依赖项,那么您不需要使用shadow插件,也不需要在jar中捆绑JavaFX依赖项

  • 外部图书馆项目
  • 因此,您可以拥有相同的
    module info.java
    文件:

    module com.example.external.lib {
        requires javafx.base;
        requires org.apache.commons.lang3;
    
        exports com.example.external.library;
    }
    
    使用
    build.gradle
    如下所示:

    buildscript {
        repositories {
            jcenter()
        }
    
        dependencies {
            classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
        }
    }
    
    apply plugin: 'com.google.osdetector'
    apply plugin: 'java'
    
    ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os
    
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        compile 'org.apache.commons:commons-lang3:3.8.1'
        compile "org.openjfx:javafx-base:11:$platform"
    }
    
    compileJava {
        doFirst {
            options.compilerArgs = [
                    '--module-path', classpath.asPath,
                    '--add-modules', 'javafx.base'
            ]
        }
    }
    
    现在,当您运行
    gradlebuild
    时,您将生成
    libs/external library.jar
    ,一个2 KB的jar,没有JavaFX依赖项

    请注意,如果您仍然希望在这个外部项目中使用shadowjar,那么可以使用
    compileOnly“org.openjfx:javafx base:11:$platform”
    将javafx依赖项排除在这个jar之外

  • 使用外部库的项目
  • 您可以将该jar添加到项目中

    build.gradle

    buildscript {
        repositories {
            jcenter()
        }
    
        dependencies {
            classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
        }
    }
    
    apply plugin: 'com.google.osdetector'
    apply plugin: 'java'
    
    ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os
    
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        compile files('libs/external-library.jar')
        compile 'org.apache.commons:commons-lang3:3.8.1'
        compile "org.openjfx:javafx-base:11:$platform"
    }
    
    compileJava {
        doFirst {
            options.compilerArgs = [
                    '--module-path', classpath.asPath,
                    '--add-modules', 'javafx.base'
            ]
        }
    }
    
    但是现在您的
    模块信息
    文件应该再次包含
    javafx.base
    依赖项:

    module example.project {
        requires javafx.base;
        requires com.example.external.lib;
    
        exports com.example.project;
    }
    
    您可以运行
    gradlebuild
    来生成一个jar,IntelliJ就不会再抱怨了

    如果希望在末尾有一个阴影jar,还可以应用:

    buildscript {
        repositories {
            mavenCentral()
            maven {
                url "https://plugins.gradle.org/m2/"
            }
        }
        dependencies {
            classpath 'com.google.gradle:osdetector-gradle-plugin:1.6.0'
        }
    }
    
    apply plugin: 'application'
    apply plugin: 'com.google.osdetector'
    
    ext.platform = osdetector.os == 'osx' ? 'mac' : osdetector.os == 'windows' ? 'win' : osdetector.os
    
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        compile files('libs/external-library.jar')
        compile 'org.apache.commons:commons-lang3:3.8.1'
        compile "org.openjfx:javafx-base:11:$platform"
    }
    
    compileJava {
        doFirst {
            options.compilerArgs = [
                    '--module-path', classpath.asPath,
                    '--add-modules', 'javafx.base'
            ]
        }
    }
    
    run {
        doFirst {
            jvmArgs = [
                    '--module-path', classpath.asPath,
                    '--add-modules', 'javafx.base'
            ]
        }
    }
    
    mainClassName = "com.example.project.PublicClass"
    
    jar {
        manifest {
            attributes 'Main-Class': 'com.example.project.PublicClass'
        }
        from {
            configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
        }
    }
    
    因此,您可以使用外部lib.jar运行
    java-jarbuild/libs/project
    。注意,这个jar将包含JavaFX类


    执行shadow jar不是分发项目的推荐方式,但是由于您有自动模块(commons-lang3),因此您不能使用
    jlink
    ,除非您将其转换为显式模块(参见此)。

    您能发布完整的异常吗?您是否设法使每个模块都独立运行,而它们之间没有依赖关系?@JoséPereda我没有任何例外,这只是IDEA提供的信息-请参阅,您是否尝试将您的模块作为独立模块运行?你正常构建/运行它们吗?模块'foo.bar'独立工作,另一个我无法测试,因为'foo.bar'是一个严格的依赖项。是的,HelloFX对我来说很好。一旦我删除了其他lib的依赖项,我就可以使用JFX libs了。但是,如果我的项目和外部库都需要相同的外部模块,显然会出现问题。谢谢你的回答-在这个小示例项目中,这对我来说是可行的。但是,我不太确定如何使用我的大型代码库,这取决于大量尚未模块化的外部库。有什么想法吗?关于这一点,我提出了另一个问题:我想说,您可以为所有非模块依赖项组合一个胖jar,通过jlink为所有模块依赖项组合一个定制JRE。Jpackager即将面世,这将允许为您的应用程序创建安装程序,无论它是否具有非模块依赖关系。顺便说一句,在内部,is使用jlink,所以它的工作原理与我之前描述的差不多。正如我在回答的最后提到的,还有一些“棘手”的方法可以从非模块化JAR生成模块。看,还有这个。这可能会帮助你模块化那些永远不会模块化的罐子。好吧,我相信我被卡住了。。。如果您有一个或两个依赖项,那么这种巧妙的方法是很好的,但是对于大量的库来说,不可能保持这种依赖项。是否有任何路线图,如果和什么时候jpacker将可用?有一个解决方案,最初的目标是Java12,但它可能无法按时完成。无论如何,Gluon正在为Java11开发ea版本。