错误:";包被声明为';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版本。