I encountered the following error when I execute my JAR with
java -jar .\QuartzScheduler-0.0.1-SNAPSHOT.jar
Error: Could not find or load main class com.quartz.QuartzSchedulerApplication
Caused by: java.lang.ClassNotFoundException: com.quartz.QuartzSchedulerApplication
This is a snippet of my build.gradle, please help to shed some light on this.
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'com.quartz'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-quartz'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc:2.4.1'
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.20.0'
implementation files('C:\\Program Files\\Microsoft JDBC DRIVER 12.6 for SQL Server\\sqljdbc_12.6\\enu\\jars\\mssql-jdbc-12.6.3.jre11.jar')
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.withType(Jar) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes["Main-Class"] = "com.quartz.QuartzSchedulerApplication"
}
}
jar {
enabled = true
archiveClassifier = ''
manifest {
attributes 'Main-Class' : "com.quartz.QuartzSchedulerApplication"
}
from {
configurations.runtimeClasspath.collect {it.isDirectory() ? it : zipTree(it)}
}
}
tasks.named('test') {
useJUnitPlatform()
}
QuartzSchedulerApplication.class
package com.quartz;
import com.quartz.info.TriggerInfo;
import com.quartz.jobs.HelloWorldJob;
import com.quartz.services.SchedulerService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QuartzSchedulerApplication {
private static final Logger LOG = LogManager.getLogger(QuartzSchedulerApplication.class);
private final SchedulerService scheduler;
@Autowired
public QuartzSchedulerApplication(SchedulerService scheduler) {
this.scheduler = scheduler;
}
public static void main(String[] args) {
SpringApplication.run(QuartzSchedulerApplication.class, args).getBean(QuartzSchedulerApplication.class).scheduleJobs();
}
public void scheduleJobs() {
final TriggerInfo info = new TriggerInfo();
info.setCronExp("5 0/1 * * * ?"); // Run every min, at 5th second
info.setCallbackData("HelloWorldJob");
scheduler.schedule(HelloWorldJob.class, info);
LOG.debug("test");
}
}
I started off building my Quartz project with Log4j and it was successful. Also, I verified that the JAR file contains my main class and manifest file also exists. When I run the application using bootJar, it was also successful.
I also tried executing the JAR file using:
java -cp .\QuartzScheduler-0.0.1-SNAPSHOT.jar com.quartz.QuartzSchedulerApplication
I'm not sure if it is due to the implementation of JDBC.
Apologies, I did not add the requirement of Log4j2 in my question. Although I am able to execute my jar file by removing the jar task and jar task configuration, my Log4j2 logging does not work anymore. I know this because I isolated my application, same as above, just without JDBC and the logging works fine. Any advice?
The problem is your build file. You are working around the work that the Gradle Spring Boot plugin is doing. Next to that you are mixing modules from different Spring Boot versions never do that either.
The solution is thus quite simple, simplify/cleanup your build.gradle
.
spring-boot-starter-jdbc
jar
task and jar
task configuration.mssql-jdbc
dependency (remove the file one)plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'com.quartz'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-quartz'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.20.0'
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
Now just build your jar as you normally would with ./gradlew build
and Spring Boot will automatically create a jar for you that you can run with java -jar QuartzScheduler-0.0.1-SNAPSHOT.jar
.