Error: “Package is declared 'javafx.beans.value' in module 'foo.bar'”
up vote
2
down vote
favorite
I've developed a library which module-info.java
looks like that:
module foo.bar {
requires org.apache.commons.lang3;
requires javafx.base;
requires java.validation;
exports foo.bar;
}
This library is used in another project where the module-info.java
contains the following:
module other.project {
requires org.apache.commons.lang3;
requires javafx.base;
requires javafx.graphics;
requires javafx.fxml;
requires foo.bar;
}
When I try to use import javafx.beans.value.WritableValue;
I get the error
Package
javafx.beans.value
is declared infoo.bar
, which does not
export it to moduleother.project
.
UPDATE: I created two example projects which reproduce the problem. Please find them here to download.
I do not understand why that is and yet I could not find a solution.
java java-module jigsaw java-11 javafx-11
|
show 9 more comments
up vote
2
down vote
favorite
I've developed a library which module-info.java
looks like that:
module foo.bar {
requires org.apache.commons.lang3;
requires javafx.base;
requires java.validation;
exports foo.bar;
}
This library is used in another project where the module-info.java
contains the following:
module other.project {
requires org.apache.commons.lang3;
requires javafx.base;
requires javafx.graphics;
requires javafx.fxml;
requires foo.bar;
}
When I try to use import javafx.beans.value.WritableValue;
I get the error
Package
javafx.beans.value
is declared infoo.bar
, which does not
export it to moduleother.project
.
UPDATE: I created two example projects which reproduce the problem. Please find them here to download.
I do not understand why that is and yet I could not find a solution.
java java-module jigsaw java-11 javafx-11
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
1
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51
|
show 9 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I've developed a library which module-info.java
looks like that:
module foo.bar {
requires org.apache.commons.lang3;
requires javafx.base;
requires java.validation;
exports foo.bar;
}
This library is used in another project where the module-info.java
contains the following:
module other.project {
requires org.apache.commons.lang3;
requires javafx.base;
requires javafx.graphics;
requires javafx.fxml;
requires foo.bar;
}
When I try to use import javafx.beans.value.WritableValue;
I get the error
Package
javafx.beans.value
is declared infoo.bar
, which does not
export it to moduleother.project
.
UPDATE: I created two example projects which reproduce the problem. Please find them here to download.
I do not understand why that is and yet I could not find a solution.
java java-module jigsaw java-11 javafx-11
I've developed a library which module-info.java
looks like that:
module foo.bar {
requires org.apache.commons.lang3;
requires javafx.base;
requires java.validation;
exports foo.bar;
}
This library is used in another project where the module-info.java
contains the following:
module other.project {
requires org.apache.commons.lang3;
requires javafx.base;
requires javafx.graphics;
requires javafx.fxml;
requires foo.bar;
}
When I try to use import javafx.beans.value.WritableValue;
I get the error
Package
javafx.beans.value
is declared infoo.bar
, which does not
export it to moduleother.project
.
UPDATE: I created two example projects which reproduce the problem. Please find them here to download.
I do not understand why that is and yet I could not find a solution.
java java-module jigsaw java-11 javafx-11
java java-module jigsaw java-11 javafx-11
edited Nov 12 at 20:58
asked Nov 11 at 12:28
Hannes
1,52951729
1,52951729
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
1
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51
|
show 9 more comments
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
1
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
1
1
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51
|
show 9 more comments
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Based on the project posted here, the error that you get when you open the project is:
Package 'javafx.beans.property' is declared in module 'com.example.external.lib', which does not export it to module 'example.project'
The reason for this error is that you are adding some packages from javafx.base
to your external library, but those are not exported to the project that uses this library. The javafx.beans.property
package is internally used by the external module, but it can't be exported.
So these are some proposed changes to make it work.
If you are creating a modular jar (using a module-info
class) as a dependency for another project, you don't need to use the shadow plugin, and you don't need to bundle the JavaFX dependencies in your jars.
- External-library project
So you can have the same module-info.java
file:
module com.example.external.lib {
requires javafx.base;
requires org.apache.commons.lang3;
exports com.example.external.library;
}
with a build.gradle
like this:
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'
]
}
}
Now, when you run gradle build
, you will generate libs/external-library.jar
, a 2 KB jar, without JavaFX dependencies.
Note that if you still want to do shadow jar with this external project, you can use compileOnly "org.openjfx:javafx-base:11:$platform"
to keep the JavaFX dependencies out of this jar.
- Project-using-external-lib
You can add that jar to the project.
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'
]
}
}
But now your module-info
file should include again the javafx.base
dependency:
module example.project {
requires javafx.base;
requires com.example.external.lib;
exports com.example.project;
}
You can run gradle build
to generate a jar, and IntelliJ won't complain anymore.
If you want to have a shadow jar at the end, you can also apply:
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) }
}
}
so you would be able to run java -jar build/libs/project-using-external-lib.jar
. Note that this jar will contain the JavaFX classes.
Doing a shadow jar is not to the recommended way to distribute your project, but since you have automatic modules (commons-lang3) you can't use jlink
, unless you convert that into an explicit module (see this answer).
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Based on the project posted here, the error that you get when you open the project is:
Package 'javafx.beans.property' is declared in module 'com.example.external.lib', which does not export it to module 'example.project'
The reason for this error is that you are adding some packages from javafx.base
to your external library, but those are not exported to the project that uses this library. The javafx.beans.property
package is internally used by the external module, but it can't be exported.
So these are some proposed changes to make it work.
If you are creating a modular jar (using a module-info
class) as a dependency for another project, you don't need to use the shadow plugin, and you don't need to bundle the JavaFX dependencies in your jars.
- External-library project
So you can have the same module-info.java
file:
module com.example.external.lib {
requires javafx.base;
requires org.apache.commons.lang3;
exports com.example.external.library;
}
with a build.gradle
like this:
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'
]
}
}
Now, when you run gradle build
, you will generate libs/external-library.jar
, a 2 KB jar, without JavaFX dependencies.
Note that if you still want to do shadow jar with this external project, you can use compileOnly "org.openjfx:javafx-base:11:$platform"
to keep the JavaFX dependencies out of this jar.
- Project-using-external-lib
You can add that jar to the project.
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'
]
}
}
But now your module-info
file should include again the javafx.base
dependency:
module example.project {
requires javafx.base;
requires com.example.external.lib;
exports com.example.project;
}
You can run gradle build
to generate a jar, and IntelliJ won't complain anymore.
If you want to have a shadow jar at the end, you can also apply:
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) }
}
}
so you would be able to run java -jar build/libs/project-using-external-lib.jar
. Note that this jar will contain the JavaFX classes.
Doing a shadow jar is not to the recommended way to distribute your project, but since you have automatic modules (commons-lang3) you can't use jlink
, unless you convert that into an explicit module (see this answer).
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
add a comment |
up vote
2
down vote
accepted
Based on the project posted here, the error that you get when you open the project is:
Package 'javafx.beans.property' is declared in module 'com.example.external.lib', which does not export it to module 'example.project'
The reason for this error is that you are adding some packages from javafx.base
to your external library, but those are not exported to the project that uses this library. The javafx.beans.property
package is internally used by the external module, but it can't be exported.
So these are some proposed changes to make it work.
If you are creating a modular jar (using a module-info
class) as a dependency for another project, you don't need to use the shadow plugin, and you don't need to bundle the JavaFX dependencies in your jars.
- External-library project
So you can have the same module-info.java
file:
module com.example.external.lib {
requires javafx.base;
requires org.apache.commons.lang3;
exports com.example.external.library;
}
with a build.gradle
like this:
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'
]
}
}
Now, when you run gradle build
, you will generate libs/external-library.jar
, a 2 KB jar, without JavaFX dependencies.
Note that if you still want to do shadow jar with this external project, you can use compileOnly "org.openjfx:javafx-base:11:$platform"
to keep the JavaFX dependencies out of this jar.
- Project-using-external-lib
You can add that jar to the project.
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'
]
}
}
But now your module-info
file should include again the javafx.base
dependency:
module example.project {
requires javafx.base;
requires com.example.external.lib;
exports com.example.project;
}
You can run gradle build
to generate a jar, and IntelliJ won't complain anymore.
If you want to have a shadow jar at the end, you can also apply:
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) }
}
}
so you would be able to run java -jar build/libs/project-using-external-lib.jar
. Note that this jar will contain the JavaFX classes.
Doing a shadow jar is not to the recommended way to distribute your project, but since you have automatic modules (commons-lang3) you can't use jlink
, unless you convert that into an explicit module (see this answer).
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Based on the project posted here, the error that you get when you open the project is:
Package 'javafx.beans.property' is declared in module 'com.example.external.lib', which does not export it to module 'example.project'
The reason for this error is that you are adding some packages from javafx.base
to your external library, but those are not exported to the project that uses this library. The javafx.beans.property
package is internally used by the external module, but it can't be exported.
So these are some proposed changes to make it work.
If you are creating a modular jar (using a module-info
class) as a dependency for another project, you don't need to use the shadow plugin, and you don't need to bundle the JavaFX dependencies in your jars.
- External-library project
So you can have the same module-info.java
file:
module com.example.external.lib {
requires javafx.base;
requires org.apache.commons.lang3;
exports com.example.external.library;
}
with a build.gradle
like this:
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'
]
}
}
Now, when you run gradle build
, you will generate libs/external-library.jar
, a 2 KB jar, without JavaFX dependencies.
Note that if you still want to do shadow jar with this external project, you can use compileOnly "org.openjfx:javafx-base:11:$platform"
to keep the JavaFX dependencies out of this jar.
- Project-using-external-lib
You can add that jar to the project.
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'
]
}
}
But now your module-info
file should include again the javafx.base
dependency:
module example.project {
requires javafx.base;
requires com.example.external.lib;
exports com.example.project;
}
You can run gradle build
to generate a jar, and IntelliJ won't complain anymore.
If you want to have a shadow jar at the end, you can also apply:
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) }
}
}
so you would be able to run java -jar build/libs/project-using-external-lib.jar
. Note that this jar will contain the JavaFX classes.
Doing a shadow jar is not to the recommended way to distribute your project, but since you have automatic modules (commons-lang3) you can't use jlink
, unless you convert that into an explicit module (see this answer).
Based on the project posted here, the error that you get when you open the project is:
Package 'javafx.beans.property' is declared in module 'com.example.external.lib', which does not export it to module 'example.project'
The reason for this error is that you are adding some packages from javafx.base
to your external library, but those are not exported to the project that uses this library. The javafx.beans.property
package is internally used by the external module, but it can't be exported.
So these are some proposed changes to make it work.
If you are creating a modular jar (using a module-info
class) as a dependency for another project, you don't need to use the shadow plugin, and you don't need to bundle the JavaFX dependencies in your jars.
- External-library project
So you can have the same module-info.java
file:
module com.example.external.lib {
requires javafx.base;
requires org.apache.commons.lang3;
exports com.example.external.library;
}
with a build.gradle
like this:
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'
]
}
}
Now, when you run gradle build
, you will generate libs/external-library.jar
, a 2 KB jar, without JavaFX dependencies.
Note that if you still want to do shadow jar with this external project, you can use compileOnly "org.openjfx:javafx-base:11:$platform"
to keep the JavaFX dependencies out of this jar.
- Project-using-external-lib
You can add that jar to the project.
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'
]
}
}
But now your module-info
file should include again the javafx.base
dependency:
module example.project {
requires javafx.base;
requires com.example.external.lib;
exports com.example.project;
}
You can run gradle build
to generate a jar, and IntelliJ won't complain anymore.
If you want to have a shadow jar at the end, you can also apply:
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) }
}
}
so you would be able to run java -jar build/libs/project-using-external-lib.jar
. Note that this jar will contain the JavaFX classes.
Doing a shadow jar is not to the recommended way to distribute your project, but since you have automatic modules (commons-lang3) you can't use jlink
, unless you convert that into an explicit module (see this answer).
edited Nov 14 at 0:32
answered Nov 14 at 0:18
José Pereda
24.6k33765
24.6k33765
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
add a comment |
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
Thank you for your answer - that worked out for me on the small example project. But I am not quite sure how to progress with my large codebase depending on a larger number of external libraries which have not been modularized yet. Any thoughts on that? I opened another question regarding this: stackoverflow.com/questions/53314512/…
– Hannes
Nov 18 at 22:09
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
I'd say you can do a combination of a fat jar for all non-modular dependencies, with a custom JRE with all the modular dependencies via jlink. Jpackager is around the corner, and that will allow creating an installer for your app, no matter if it has non-modular dependencies. Internally, by the way, is uses jlink, so it works pretty much as I described before.
– José Pereda
Nov 18 at 22:40
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
As mentioned at the end of my answer, there are also some "tricky" ways to generate modules out of non modular jars. See this, and this repo. This might help you to modularize jars that won't be ever modularized.
– José Pereda
Nov 18 at 22:48
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
Well, I believe I am stuck ... that tricky way is nice if you have one or two dependencies but it is not possible to maintain that for a larger amount of libraries. Is there any roadmap if and when jpacker will be available?
– Hannes
Nov 20 at 11:52
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
There is a JEP for it, the initial target is Java 12, but it might not make it on time. Anyway, Gluon is working on a ea release for Java 11.
– José Pereda
Nov 20 at 12:06
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53248763%2ferror-package-is-declared-javafx-beans-value-in-module-foo-bar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you post the full exception? Did you manage to get each of the modules running standalone, without having dependencies between them?
– José Pereda
Nov 11 at 13:35
@JoséPereda I do not get an exception as such, it is just a info provided by IDEA - please see img.picload.org/image/dcoogipr/snippet.png
– Hannes
Nov 11 at 14:05
And did you try your modules as standalone? Do you build/run them normally?
– José Pereda
Nov 11 at 14:13
module 'foo.bar' works stand-alone, the other one I cannot test since 'foo.bar' is a strict dependency.
– Hannes
Nov 11 at 14:21
1
Yes, the HelloFX works fine for me. As soon as I remove the dependency of my other lib I can use the JFX libs. But apparently there is a problem if both my project and the external lib requires the same external module.
– Hannes
Nov 11 at 14:51