Home > database >  Intellij 2021.3.2, JavaFX Maven project not resolving dependencies correctly
Intellij 2021.3.2, JavaFX Maven project not resolving dependencies correctly

Time:03-19

I added a library to my JavaFX projects following these steps:

  1. File --> Project Structure --> Project Settings --> Libraries --> --> Maven
  2. Insert the Maven coordinates and checked the "Download to projectPath/libs"
  3. In pom.xml added the correct dependecy declaration
  4. In module-info.java added the 'requires module'

Importing the library to my class seems to work, but after calling a method from the library, it results in a

Caused by: java.lang.ClassNotFoundException: org.web3j.utils.Numeric
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)

Now, i initially thought was a library problem, but reproducing the same steps in a normal Maven project (and trying to run the same exact code snippet) works perfectly.

Any ideas why this could happen? Am i doing something wrong in importing the library?

HELLOAPPLICATION.JAVA

public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
    Scene scene = new Scene(fxmlLoader.load() , 320 , 240);
    stage.setTitle("Hello!");
    stage.setScene(scene);
    stage.show();
    Web3j web3j = Web3j.build(new HttpService("http://127.0.0.1:8545"));
    web3j.ethGetBlockByNumber(DefaultBlockParameter.valueOf(new BigInteger("14000000")), true);
}

public static void main(String[] args) {
    launch();
}

}

Edit:

POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <junit.version>5.8.1</junit.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>17.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>17.0.1</version>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.web3j</groupId>
        <artifactId>web3j-evm</artifactId>
        <version>4.9.0</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>17</source>
                <target>17</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.8</version>
            <executions>
                <execution>
                    <!-- Default configuration for running with: mvn clean javafx:run -->
                    <id>default-cli</id>
                    <configuration>
                        <mainClass>com.example.demo/com.example.demo.HelloApplication</mainClass>
                        <launcher>app</launcher>
                        <jlinkZipName>app</jlinkZipName>
                        <jlinkImageName>app</jlinkImageName>
                        <noManPages>true</noManPages>
                        <stripDebug>true</stripDebug>
                        <noHeaderFiles>true</noHeaderFiles>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

MODULE-INFO.JAVA

module com.example.demo {
requires javafx.controls;
requires javafx.fxml;
requires core;
opens com.example.demo to javafx.fxml;
exports com.example.demo;}

CodePudding user response:

From the comments, you seem to be using some less common libraries. Sometimes, those kinds of libraries are not updated to be compatible with the Java Platform Module System. I think it is probably safe to assume that unless you know otherwise.

The easiest way to deal with such dependencies is to make your project non-modular: delete the module-info.java.

But JavaFX itself is only supported as modules. So, even though your project and its dependencies are non-modular, you should still place the JavaFX libraries on the module path.

To accomplish such a setup (non-modular application using JavaFX modules), the easiest way is to rely on JDK or JRE that includes JavaFX modules, for example, the Zulu JDK FX distribution or the Liberica Full JDK distribution. It is important to use the correct distribution as the base JDK distributions for Zulu and Liberica do not include JavaFX.

With a bit more work, you can use OpenJDK. You can do this by sourcing the JavaFX modules from either the maven repository with a build tool, or a manual download of the modules and SDK from Gluon. In all your build and execution steps, you need to ensure that all of those modules are on the module path and declared to the module system via either VM arguments or a module-info.java. For a Maven build, you need to add each module to the module path individually, as they are all in separate directories in the local .m2 repository (modern Maven systems and some IDEs, such as Idea, will do that automatically, other IDEs such as VSCode may not).

Alternately, don't add dependencies on the JavaFX modules via Maven. Instead, download the JavaFX SDK and add the JavaFX modules there via VM arguments --module-path and --add-modules. This process for adding JavaFX modules to OpenJDK is documented in the getting started documentation at openjfx.io.

Note that the openjfx.io getting started documentation around this mentions maven archetypes. My advice is not to use those as they are really difficult to work with if you try to use them from IDEs. Instead, use the Idea new JavaFX project wizard, either keeping the module-info.java it generates for a modular project or removing it and manually specifying JavaFX module VM arguments for a non-modular project.

In terms of your actual project, I encountered the same error that duffymo pointed out in the comments:

I can't resolve all the dependencies for web3jm-evm from Maven Central. It's pulling in a bunch of JARs from org.hyperledger.besu that aren't in Maven Central.

So I was unable to build or test it.

  • Related