Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Package 'com.example' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'

In module-info.java i get the error

Package 'com.example' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'.

Not only does the migration (Java 8 to Java 11) frustrate me slowly but surely, this error does not make any sense to me.

The dependencies part fo my build.gradle:

def springFrameworkVersion = '5.1.2.RELEASE'
def hibernateVersion = '5.3.7.Final'
def junitJupiterVersion = '5.3.1'

dependencies {
  compile 'org.transentials:cardhouse-commons:1.1.1'
  compile 'ch.qos.logback:logback-classic:1.2.3'
  compile "org.springframework:spring-context:$springFrameworkVersion"
  compile "org.springframework:spring-jdbc:$springFrameworkVersion"
  compile "org.springframework:spring-orm:$springFrameworkVersion"
  compile "org.hibernate:hibernate-core:$hibernateVersion"
  compile 'org.apache.commons:commons-dbcp2:2.5.0'
  compile 'org.apache.commons:commons-lang3:3.8.1'
  compile 'commons-io:commons-io:2.6'
  compile 'com.h2database:h2:1.4.197'
  compile 'javax.xml.bind:jaxb-api:2.3.1'
  compile 'com.google.guava:guava:27.0-jre'
  compile 'org.flywaydb:flyway-core:5.2.1'
  compile 'javax.validation:validation-api:2.0.1.Final'
  compile "org.openjfx:javafx-base:11:$platform"
  compile "org.openjfx:javafx-graphics:11:$platform"
  compile "org.openjfx:javafx-controls:11:$platform"
  compile "org.openjfx:javafx-fxml:11:$platform"
  testCompile 'junit:junit:4.12'

  testCompile 'org.mockito:mockito-core:2.+'
  testCompile 'de.saxsys:jfx-testrunner:1.2'
  testCompile 'org.apache.commons:commons-text:1.6'
  testCompile "org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion"
  testCompile "org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion"
  testCompile 'org.hamcrest:hamcrest-all:1.3'
}

And the module-info.java:

module open.terms.client.jfx {
  requires org.transentials.cardhouse.commons;
  requires com.google.common;
  requires org.apache.commons.lang3;
  requires org.hibernate.orm.core;
  requires java.persistence;
  requires slf4j.api;
  requires javafx.graphics;
  requires javafx.fxml;
  requires java.desktop;
}

Can someone explain to me what the compiler wants to tell me by this?

like image 337
Hannes Avatar asked Nov 29 '18 21:11

Hannes


2 Answers

With the required list of dependencies, if you remove all the required modules from the module-info, the IDE will still complain with the same error:

Module '' reads package 'javafx.beans' from both 'javafx.base' and 'javafx.base'

So the problem is not in your module-info, but in your dependencies. If you comment out all of them, except the JavaFX ones, the problem is gone.

This means that some dependency is carrying some unnecessary JavaFX dependency.

I've managed to isolate the problem by commenting only the first dependency:

compile 'org.transentials:cardhouse-commons:1.1.1'

So the question is why is this happening and how can we fix it.

If you go to Maven Central repo it shows the GitHub repo of the dependency, where you can find the build.gradle file and its module-info.

As expected, it uses JavaFX:

compile "org.openjfx:javafx-base:11:$platform"

and it also requires javafx.base in its module-info.

When you consume this artifact with your dependencies you are importing their javafx.base import, along with yours from your JavaFX dependencies and there is the conflict.

The fastest way to solve the issue is just changing this in your build:

compile 'org.transentials:cardhouse-commons:1.1.1'

to this:

compile ('org.transentials:cardhouse-commons:1.1.1') {
    exclude group: 'org.openjfx'
}

so you will exclude its JavaFX dependencies and will use yours.

A more permanent fix will be changing the artifact org.transentials:cardhouse-commons's module-info to:

`requires transitive javafx.base`

You can read about the use of transitive here.

An issue should be reported to the author.

Note

As an aside, you can use the javafx gradle plugin to take care of all the related JavaFX parts of the build, simplifying it to:

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.5'
}

repositories {
    mavenCentral()
}

dependencies {
    compile ('org.transentials:cardhouse-commons:1.1.1') {
        exclude group: 'org.openjfx'
    }
    compile files('libs/cardhouse-commons-master-1.1.1.jar')
    ...
    compile 'javax.validation:validation-api:2.0.1.Final'
}

javafx {
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'open.terms.client.jfx.Main'

The OpenJFX docs already make use of this plugin.

like image 51
José Pereda Avatar answered Oct 23 '22 14:10

José Pereda


The error reads, that you've ended up placing same module twice in your modulepath for JavaFX.

The chances are that you might have placed both the jmods for the OpenJFX as well as the OpenJFX SDK/lib on your modulepath.

The JavaFX 11 runtime is available as

  • a platform-specific SDK

  • as a number of jmods and

  • as a set of artifacts in maven central.

Either(one) of these three should be sufficient enough to work with further depending on how you are planning to build your application - modular or non-modular.

Edit 1 [Conceptual Improvement]

In your build.gradle, you should just need to have dependencies over

compile "org.openjfx:javafx-controls:11:$platform"
compile "org.openjfx:javafx-fxml:11:$platform"

since the module, javafx.base and javafx.graphics are transitively present in the module path via javafx-controls anyway. Also, you must ensure, given these dependencies you are not adding any libraries under Project Settings > Libraries.

Edit 2 [Extensible improvement]

Following the documentation at OpenJFX, you can make use of the plugin and get rid of the openjfx dependencies

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.5'
}

javafx {
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

dependencies {
    // all dependencies except openjfx
}

Edit 3 [Hands on]

The actual culprit in your example is the dependency

compile 'org.transentials:cardhouse-commons:1.1.1'

disabling this fixes the issue. You might want to raise it to the library owner(or fix this if you own it) to ensure that it doesn't bring along javafx.base module along with. To be precise this dependency is bringing in the org.openjfx:javafx-base:linux:11.0.1 as a dependency the reason being clear in their pom.xml dependencies.

like image 20
Naman Avatar answered Oct 23 '22 14:10

Naman