I am getting module not found
when compiling with maven. This is a simple project for testing some concepts, it can be found here on Github. Here are the errors:
/home/TestQuerydsl/src/main/java/module-info.java:2: error: module not found: javafx.controls
requires javafx.controls;
^
/home/TestQuerydsl/src/main/java/module-info.java:3: error: module not found: javafx.fxml
requires javafx.fxml;
^
/home/TestQuerydsl/src/main/java/module-info.java:4: error: module not found: java.persistence
requires java.persistence;
Full module-info.java
module com.intelidia.testquerydsl {
requires javafx.controls;
requires javafx.fxml;
requires java.persistence;
opens com.intelidia.testquerydsl to javafx.fxml;
exports com.intelidia.testquerydsl;
}
Full pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.intelidia.testquerydsl</groupId>
<artifactId>TestQuerydsl</artifactId>
<version>1.0-SNAPSHOT</version>
<name>TestQuerydsl</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.0</junit.version>
<querydsl.version>5.1.0</querydsl.version>
</properties>
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.6</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.6</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</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.intelidia.testquerydsl.testquerydsl/com.intelidia.testquerydsl.testquerydsl.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>
</project>
Note the answer below assumes you want or need your project to be modular. If that's not the case, then the easiest solution is to just delete your module-info.java
file. Plus, some of your dependencies are non-modular. Having a dependency on automatic modules negates many of the benefits of modular code (e.g., jlink
cannot work with automatic modules). Also see jewelsea's comment about possibly using JDKs that include JavaFX.
Whether you keep your code modular or not, I still suggest removing apt-maven-plugin
and moving the annotation processor configuration to maven-compiler-plugin
instead.
Those "module not found" errors are emitted by the com.mysema.maven:apt-maven-plugin
plugin. That plugin's repository was archived in 2021 and the latest release on Maven Central says it was published 9 years ago in 2015 (note Java 9 was released in 2017). I'm not sure why the querydsl-jpa documentation still says to apply it. Maybe someone more familiar with Querydsl can provide some clarification, because removing that plugin and configuring the annotation processor in the maven-compiler-plugin
plugin instead seems to work just as well:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
<annotationProcessors>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</annotationProcessors>
</configuration>
</plugin>
Or at least, that solves the "module not found" errors. But now it fails with:
l error compiling: java.lang.NoClassDefFoundError: javax/persistence/Entity: javax.persistence.Entity
From what I can tell, this error is caused by the following:
When compiling a module, annotation processors picked up from the class-path or processor-path cannot find classes on the module-path (don't know if this is documented anywhere). Your project has a module-info.java
file, so you are compiling a module.
Maven is placing the javax.persistence-api
dependency on module-path only.
The querydsl-apt
dependency does not have a transitive dependency on javax.persistence-api
.
It looks like one way to fix this is to explicitly set the processor-path:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
<annotationProcessorPaths>
<path>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</path>
<path>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</path>
</annotationProcessorPaths>
<annotationProcessors>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</annotationProcessors>
</configuration>
</plugin>
We're getting closer, but now this fails with:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project TestQuerydsl: Compilation failure: Compilation failure:
[ERROR] /C:/Users/koles/Desktop/TestQueryDSL/target/generated-sources/annotations/com/intelidia/testquerydsl/testquerydsl/models/QUser.java:[3,32] package com.querydsl.core.types is not visible
[ERROR] (package com.querydsl.core.types is declared in the unnamed module, but module com.intelidia.testquerydsl does not read it)
[ERROR] /C:/Users/koles/Desktop/TestQueryDSL/target/generated-sources/annotations/com/intelidia/testquerydsl/testquerydsl/models/QUser.java:[5,31] package com.querydsl.core.types.dsl is not visible
[ERROR] (package com.querydsl.core.types.dsl is declared in the unnamed module, but module com.intelidia.testquerydsl does not read it)
[ERROR] /C:/Users/koles/Desktop/TestQueryDSL/target/generated-sources/annotations/com/intelidia/testquerydsl/testquerydsl/models/QUser.java:[7,25] package com.querydsl.core.types is not visible
[ERROR] (package com.querydsl.core.types is declared in the unnamed module, but module com.intelidia.testquerydsl does not read it)
[ERROR] /C:/Users/koles/Desktop/TestQueryDSL/target/generated-sources/annotations/com/intelidia/testquerydsl/testquerydsl/models/QUser.java:[8,24] package javax.annotation.processing is not visible
[ERROR] (package javax.annotation.processing is declared in module java.compiler, but module com.intelidia.testquerydsl does not read it)
[ERROR] /C:/Users/koles/Desktop/TestQueryDSL/target/generated-sources/annotations/com/intelidia/testquerydsl/testquerydsl/models/QUser.java:[9,25] package com.querydsl.core.types is not visible
[ERROR] (package com.querydsl.core.types is declared in the unnamed module, but module com.intelidia.testquerydsl does not read it)
The fix for that is to modify your module-info.java
file to add the following:
requires static java.compiler;
requires com.querydsl.core;
Those are necessary because the generated code is being compiled into your module.
The generated code includes a javax.annotation.processing.Generated
annotation. That annotation comes from the java.compiler
module. But the annotation is only required at compile-time, hence the use of requires static
instead of requires
.
The generated code uses many types from com.querydsl.core
.
After making all those changes, running ./mvnw compile
succeeds and the expected sources are generated. But there are still problems with executing javafx:run
. You have the wrong module name in your POM; it should be:
<mainClass>
com.intelidia.testquerydsl/com.intelidia.testquerydsl.testquerydsl.HelloApplication
</mainClass>
And you need to add two more directives to your module-info.java
file:
exports com.intelidia.testquerydsl.testquerydsl to javafx.graphics;
opens com.intelidia.testquerydsl.testquerydsl to javafx.fxml;
And finally, executing ./mvnw compile javafx:run
should work.
Here is the new module-info.java
:
module com.intelidia.testquerydsl {
requires static java.compiler;
requires com.querydsl.core;
requires java.persistence;
requires javafx.controls;
requires javafx.fxml;
exports com.intelidia.testquerydsl.testquerydsl to
javafx.graphics;
opens com.intelidia.testquerydsl.testquerydsl to
javafx.fxml;
}
And the new pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.intelidia.testquerydsl</groupId>
<artifactId>TestQuerydsl</artifactId>
<version>1.0-SNAPSHOT</version>
<name>TestQuerydsl</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>11</maven.compiler.release>
<javafx.version>17.0.6</javafx.version>
<javax.persistence.version>2.2</javax.persistence.version>
<querydsl.version>5.1.0</querydsl.version>
<junit.version>5.10.0</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>${javax.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</path>
<path>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>${javax.persistence.version}</version>
</path>
</annotationProcessorPaths>
<annotationProcessors>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</annotationProcessors>
</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.intelidia.testquerydsl/com.intelidia.testquerydsl.testquerydsl.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>
</project>