I have a JavaFX project and I use Maven for dependency management. Everything is working fine, until I add maven dependency for "mariadb-java-client" in order to get MariaDB JDBC Driver. Then I get "java.lang.NoClassDefFoundError: org.slf4j.Logger"
error.
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.3.3</version>
</dependency>
I'm getting the following error:
Exception in Application init method
Exception in thread "main" java.lang.RuntimeException: Exception in Application init method
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:888)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:857)
Caused by: java.lang.NoClassDefFoundError: org.slf4j.Logger
at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:36)
at org.apache.commons.logging.LogAdapter$Log4jLog.<init>(LogAdapter.java:159)
at org.apache.commons.logging.LogAdapter$Log4jAdapter.createLog(LogAdapter.java:113)
at org.apache.commons.logging.LogAdapter.createLog(LogAdapter.java:95)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:67)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:59)
at [email protected]/org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:202)
at com.mypackage/com.mypackage.CustomerApp.init(CustomerApp.java:72)
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:817)
... 2 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:827)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:1095)
... 11 more
The error is thrown at the startup of the application. The only code line to my code from Stack trace point to line 72 in CustomerApp.java which the following piece of code at the initilization stage of the app where I set the Spring Context:
@Override
public void init() throws Exception {
springContext = SpringApplication.run(CustomerApp.class);
}
I tried everything I have found in previous questions. I have tried to adding "slf4j-api"
, "slf4j-log4j12"
, "slf4j-simple"
etc.
Nothing helped.
My dependencies in pom.xml:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>${javafx.classifier}</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
<classifier>${javafx.classifier}</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<classifier>${javafx.classifier}</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>${javafx.version}</version>
<classifier>${javafx.classifier}</classifier>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>${javafx.version}</version>
<classifier>${javafx.classifier}</classifier>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.2</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.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx</artifactId>
<version>8.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>io.github.palexdev</groupId>
<artifactId>scenicview</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.4</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.3.3</version>
</dependency>
</dependencies>
Output of mvn dependency:tree
:
com.mypackage:artifact_CustomerApp:jar:1.1-SNAPSHOT
+- org.openjfx:javafx-controls:jar:win:20.0.2:compile
| \- org.openjfx:javafx-graphics:jar:20.0.2:compile
+- org.openjfx:javafx-fxml:jar:win:20.0.2:compile
| \- org.openjfx:javafx-controls:jar:20.0.2:compile
+- org.openjfx:javafx-graphics:jar:win:20.0.2:compile
| \- org.openjfx:javafx-base:jar:20.0.2:compile
| \- org.openjfx:javafx-base:jar:win:20.0.2:compile
+- org.openjfx:javafx-web:jar:win:20.0.2:compile
| \- org.openjfx:javafx-media:jar:20.0.2:compile
| \- org.openjfx:javafx-media:jar:win:20.0.2:compile
+- org.openjfx:javafx-swing:jar:win:20.0.2:compile
+- org.controlsfx:controlsfx:jar:11.1.2:compile
+- org.junit.jupiter:junit-jupiter-api:jar:5.9.2:test
| +- org.opentest4j:opentest4j:jar:1.2.0:test
| +- org.junit.platform:junit-platform-commons:jar:1.10.1:test
| \- org.apiguardian:apiguardian-api:jar:1.1.2:test
+- org.junit.jupiter:junit-jupiter-engine:jar:5.9.2:test
| \- org.junit.platform:junit-platform-engine:jar:1.10.1:test
+- org.projectlombok:lombok:jar:1.18.28:compile
+- org.hsqldb:hsqldb:jar:2.7.2:compile
+- jakarta.persistence:jakarta.persistence-api:jar:3.1.0:compile
+- com.fasterxml.jackson.core:jackson-databind:jar:2.15.2:compile
| +- com.fasterxml.jackson.core:jackson-annotations:jar:2.15.3:compile
| \- com.fasterxml.jackson.core:jackson-core:jar:2.15.3:compile
+- de.jensd:fontawesomefx:jar:8.9:compile
+- org.springframework.boot:spring-boot-starter-test:jar:3.2.2:test
| +- org.springframework.boot:spring-boot-starter:jar:3.2.2:compile
| | +- org.springframework.boot:spring-boot:jar:3.2.2:compile
| | +- org.springframework.boot:spring-boot-autoconfigure:jar:3.2.2:compile
| | +- org.springframework.boot:spring-boot-starter-logging:jar:3.2.2:compile
| | | +- ch.qos.logback:logback-classic:jar:1.4.14:compile
| | | | \- ch.qos.logback:logback-core:jar:1.4.14:compile
| | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.21.1:compile
| | | | \- org.apache.logging.log4j:log4j-api:jar:2.21.1:compile
| | | \- org.slf4j:jul-to-slf4j:jar:2.0.11:compile
| | \- org.yaml:snakeyaml:jar:2.2:compile
| +- org.springframework.boot:spring-boot-test:jar:3.2.2:test
| +- org.springframework.boot:spring-boot-test-autoconfigure:jar:3.2.2:test
| +- com.jayway.jsonpath:json-path:jar:2.8.0:test
| +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.1:compile
| | \- jakarta.activation:jakarta.activation-api:jar:2.1.2:compile
| +- net.minidev:json-smart:jar:2.5.0:test
| | \- net.minidev:accessors-smart:jar:2.5.0:test
| | \- org.ow2.asm:asm:jar:9.3:test
| +- org.assertj:assertj-core:jar:3.24.2:test
| | \- net.bytebuddy:byte-buddy:jar:1.14.11:runtime
| +- org.awaitility:awaitility:jar:4.2.0:test
| +- org.hamcrest:hamcrest:jar:2.2:test
| +- org.junit.jupiter:junit-jupiter:jar:5.10.1:test
| | \- org.junit.jupiter:junit-jupiter-params:jar:5.10.1:test
| +- org.mockito:mockito-core:jar:5.7.0:test
| | +- net.bytebuddy:byte-buddy-agent:jar:1.14.11:test
| | \- org.objenesis:objenesis:jar:3.3:test
| +- org.mockito:mockito-junit-jupiter:jar:5.7.0:test
| +- org.skyscreamer:jsonassert:jar:1.5.1:test
| | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
| +- org.springframework:spring-core:jar:6.1.3:compile
| | \- org.springframework:spring-jcl:jar:6.1.3:compile
| +- org.springframework:spring-test:jar:6.1.3:test
| \- org.xmlunit:xmlunit-core:jar:2.9.1:test
+- org.springframework.restdocs:spring-restdocs-mockmvc:jar:3.0.0:test
| +- org.springframework.restdocs:spring-restdocs-core:jar:3.0.1:test
| +- org.springframework:spring-webmvc:jar:6.1.3:compile
| | \- org.springframework:spring-expression:jar:6.1.3:compile
| \- jakarta.servlet:jakarta.servlet-api:jar:6.0.0:test
+- org.springframework.boot:spring-boot-starter-web:jar:3.2.2:compile
| +- org.springframework.boot:spring-boot-starter-json:jar:3.2.2:compile
| | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.15.3:compile
| | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.15.3:compile
| | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.15.3:compile
| +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.2.2:compile
| | +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.18:compile
| | +- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.18:compile
| | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.18:compile
| \- org.springframework:spring-web:jar:6.1.3:compile
| \- io.micrometer:micrometer-observation:jar:1.12.2:compile
| \- io.micrometer:micrometer-commons:jar:1.12.2:compile
+- org.springframework.boot:spring-boot-starter-data-jpa:jar:3.1.4:compile
| +- org.springframework.boot:spring-boot-starter-aop:jar:3.2.2:compile
| | \- org.aspectj:aspectjweaver:jar:1.9.21:compile
| +- org.springframework.boot:spring-boot-starter-jdbc:jar:3.2.2:compile
| | \- com.zaxxer:HikariCP:jar:5.0.1:compile
| +- org.hibernate.orm:hibernate-core:jar:6.4.1.Final:compile
| | +- jakarta.transaction:jakarta.transaction-api:jar:2.0.1:compile
| | +- org.jboss.logging:jboss-logging:jar:3.5.3.Final:runtime
| | +- org.hibernate.common:hibernate-commons-annotations:jar:6.0.6.Final:runtime
| | +- io.smallrye:jandex:jar:3.1.2:runtime
| | +- com.fasterxml:classmate:jar:1.6.0:runtime
| | +- org.glassfish.jaxb:jaxb-runtime:jar:4.0.4:runtime
| | | \- org.glassfish.jaxb:jaxb-core:jar:4.0.4:runtime
| | | +- org.eclipse.angus:angus-activation:jar:2.0.1:runtime
| | | +- org.glassfish.jaxb:txw2:jar:4.0.4:runtime
| | | \- com.sun.istack:istack-commons-runtime:jar:4.1.2:runtime
| | \- jakarta.inject:jakarta.inject-api:jar:2.0.1:runtime
| \- org.springframework:spring-aspects:jar:6.1.3:compile
+- io.github.palexdev:scenicview:jar:17.0.2:compile
| +- org.openjfx:javafx-base:jar:linux:18:runtime
| +- org.openjfx:javafx-graphics:jar:linux:18:runtime
| +- org.openjfx:javafx-fxml:jar:linux:18:runtime
| \- org.openjfx:javafx-controls:jar:linux:18:runtime
+- org.springframework.data:spring-data-jpa:jar:3.1.4:compile
| +- org.springframework.data:spring-data-commons:jar:3.2.2:compile
| +- org.springframework:spring-orm:jar:6.1.3:compile
| +- org.springframework:spring-context:jar:6.1.3:compile
| +- org.springframework:spring-aop:jar:6.1.3:compile
| +- org.springframework:spring-tx:jar:6.1.3:compile
| +- org.springframework:spring-beans:jar:6.1.3:compile
| +- org.antlr:antlr4-runtime:jar:4.10.1:compile
| +- jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
| \- org.slf4j:slf4j-api:jar:2.0.11:compile
+- org.springdoc:springdoc-openapi-starter-webmvc-ui:jar:2.2.0:compile
| +- org.springdoc:springdoc-openapi-starter-webmvc-api:jar:2.2.0:compile
| | \- org.springdoc:springdoc-openapi-starter-common:jar:2.2.0:compile
| | \- io.swagger.core.v3:swagger-core-jakarta:jar:2.2.15:compile
| | +- org.apache.commons:commons-lang3:jar:3.13.0:compile
| | +- io.swagger.core.v3:swagger-annotations-jakarta:jar:2.2.15:compile
| | +- io.swagger.core.v3:swagger-models-jakarta:jar:2.2.15:compile
| | +- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
| | \- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.15.3:compile
| \- org.webjars:swagger-ui:jar:5.2.0:compile
+- javax.annotation:javax.annotation-api:jar:1.3.2:compile
+- javax.xml.bind:jaxb-api:jar:2.3.1:compile
| \- javax.activation:javax.activation-api:jar:1.2.0:compile
+- org.springframework:spring-jdbc:jar:6.1.4:compile
\- org.mariadb.jdbc:mariadb-java-client:jar:3.3.3:compile
\- com.github.waffle:waffle-jna:jar:3.3.0:compile
+- net.java.dev.jna:jna:jar:5.13.0:compile
+- net.java.dev.jna:jna-platform:jar:5.13.0:compile
+- org.slf4j:jcl-over-slf4j:jar:2.0.11:compile
+- com.github.ben-manes.caffeine:caffeine:jar:3.1.8:compile
| \- com.google.errorprone:error_prone_annotations:jar:2.21.1:compile
\- org.checkerframework:checker-qual:jar:3.32.0:compile
You have defined a java platform module which relies on a modular version of the slf4j library, but does not require slf4j in the module.
Note: slf4j was only modularized in version 2 of that library.
Fix Alternative: for a modular app
Add the following to your module-info.java
:
requires slf4j;
As noted in comments by the asker:
Adding "requires org.slf4j;" resolved the issue.
Fix Alternative: for a non-modular app
Delete the module-info.java
from your application, making the application non-modular. Load the JavaFX libraries as modules from the JavaFX SDK by adding them to the module path.
Instructions for non-modular JavaFX applications are in the getting started instructions at openjfx.io and are also provided in the "Testing" section of this answer.
Your module is not well-defined
When you have a module which tries to use classes on the module path but does not require them or appropriately load them via the service mechanism, the module system will limit the accessibility to classes in the module you are trying to use, and they will not be usable.
Reporting a class name by fully qualifying it in the form <module-name>/<package-name>.<class-name>
is indicative that the class has been loaded from a module.
As this appears in your stack trace:
com.mypackage/com.mypackage.CustomerApp
it means that have created a modular application by defining a module-info.java
(not provided in your question) with your module named com.mypackage
and loaded that module from the module path.
I cannot reproduce your issue once the application is made non-modular.
To attempt to reproduce, I:
@SpringBootApplication
annotation to the generated application class.module-info.java
.It just worked, no issue with logging.
Don't make Spring 6 applications modular
For SpringBoot 3 or Spring 6 applications I strongly recommend not making your application modular.
The Spring software in those versions are defined as automatic modules. Automatic modules modules cannot fully exploit benefits of the module system, especially when some software they rely on is loaded from the classpath. Automatic modules can still confusingly mix loading of software from the classpath and module path, they do not allow module dependencies to be easily analyzed via module dependency analysis tools, they don't enforce all constraints needed to ensure well-defined modules for all software in your application and they can't be linked via jlink.
Defining a Spring 6 application as a modular application provides little benefit to you as a developer and complicates application development for you. You suffer the pain of trying to create a well-defined modular application while receiving little of the benefit of the module system. In the worst cases, some software used by Spring (likely not Spring itself) will be incompatible with the Java module system because, for instance, the software splits packages across jar files.
Follow instructions for non-modular apps at openjfx.io getting started, delete your module-info.java
.
Use separate application classes for JavaFX and SpringBoot
I don't recommend making the JavaFX application also a SpringBoot application. (This is not the cause of the error in your question.)
Create two different classes for SpringBoot and JavaFX.
The JavaFX launcher and the SpringBoot runner create new instances of a class. You end up with two instances of the same application class when you use the same class for everything. That could be confusing, even though it works.
Seperation of the SpringBoot and JavaFX application is also good from a Seperation of Concerns software design viewpoint.