Skip to content

Commit

Permalink
Upgrade to Spring Boot 3.2.0
Browse files Browse the repository at this point in the history
Turn on virtual threads for Spring Boot.

Add an update mechanism for H2.
  • Loading branch information
zapek committed Nov 24, 2023
1 parent 3f249ac commit 405fc7e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 30 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jpackage {
appDescription = parent.project.name
input = "${project.buildDir}/${project.libsDirName}"
destination = "${project.buildDir}/dist"
mainClass = "org.springframework.boot.loader.JarLauncher"
mainClass = "org.springframework.boot.loader.launch.JarLauncher"
mainJar = "app-${project.version}.jar"
licenseFile = "${parent.rootDir}/LICENSE"
aboutUrl = "https://xeres.io"
Expand Down Expand Up @@ -161,7 +161,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-json'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'com.h2database:h2'
implementation 'com.h2database:h2'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import io.xeres.app.properties.DatabaseProperties;
import io.xeres.ui.support.splash.SplashService;
import org.h2.tools.Upgrade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand All @@ -32,7 +33,11 @@
import org.springframework.core.env.Profiles;

import javax.sql.DataSource;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Properties;

/**
* Configuration for the location and options of the database.
Expand All @@ -43,6 +48,11 @@ public class DataSourceConfiguration
{
private static final Logger log = LoggerFactory.getLogger(DataSourceConfiguration.class);

private static final int H2_UPGRADE_FROM_VERSION = 214;
private static final int H2_UPGRADE_CURRENT_FORMAT = 3;
private static final String H2_URL_PREFIX = "jdbc:h2:file:";
private static final String H2_USERNAME = "sa";

private final Environment environment;
private final DatabaseProperties databaseProperties;
private final DataDirConfiguration dataDirConfiguration;
Expand Down Expand Up @@ -80,11 +90,51 @@ public DataSource getDataSource()
dbOpts += ";CACHE_SIZE=" + databaseProperties.getCacheSize();
}

var url = H2_URL_PREFIX + dataDir + dbOpts + useJMX;

upgradeIfNeeded(url);

return DataSourceBuilder
.create()
.url("jdbc:h2:file:" + dataDir + dbOpts + useJMX)
.username("sa")
.url(url)
.username(H2_USERNAME)
.driverClassName("org.h2.Driver")
.build();
}

private void upgradeIfNeeded(String url)
{
if (!url.startsWith(H2_URL_PREFIX))
{
log.debug("Not an H2 file, no upgrade needed");
return;
}
var fileName = url.substring(13, url.indexOf(";")) + ".mv.db";

try (var reader = new BufferedReader(new FileReader(fileName)))
{
var header = reader.readLine();
if (header.contains("format:" + H2_UPGRADE_CURRENT_FORMAT))
{
log.debug("No upgrade needed for H2");
return;
}
}
catch (IOException e)
{
throw new RuntimeException("Couldn't read database: " + e.getMessage());
}

var properties = new Properties();
properties.put("USER", H2_USERNAME);
properties.put("PASSWORD", "");
try
{
Upgrade.upgrade(url, properties, H2_UPGRADE_FROM_VERSION);
}
catch (Exception e)
{
log.error("Couldn't perform upgrade: {}", e.getMessage(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,16 @@

package io.xeres.app.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
* Configuration of the scheduler. Just enables it. We also provide
* a thread pool because by default it just uses one task for all
* Scheduled beans.
* Note: Spring Boot currently doesn't support virtual threads in there. Revisit if it does one day.
* Configuration of the scheduler. Just enables it. We use JDK 21 and virtual threads
* are enabled so there's no need to set up a thread pool anymore.
*/
@Configuration
@EnableScheduling
public class SchedulerConfiguration implements SchedulingConfigurer
public class SchedulerConfiguration
{
public static final int CORE_POOL_SIZE = 3;

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
{
taskRegistrar.setScheduler(taskExecutor());
}

@SuppressWarnings("ContextJavaBeanUnresolvedMethodsInspection")
@Bean(destroyMethod = "shutdown") // make sure task executor is properly shut down when spring exits
public Executor taskExecutor()
{
return Executors.newScheduledThreadPool(CORE_POOL_SIZE);
}
}
4 changes: 3 additions & 1 deletion app/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,6 @@ logging.level.org.apache.catalina.loader=ERROR

# Graceful shutdown. This is useful as it will put a warning if there are still active connections
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=10s
spring.lifecycle.timeout-per-shutdown-phase=10s

spring.threads.virtual.enabled=true
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ buildscript {
}

plugins {
id 'org.springframework.boot' version '3.1.5' apply false
id 'org.springframework.boot' version '3.2.0' apply false
id 'org.flywaydb.flyway' version '9.5.1' apply false // Keep the version in sync with spring-boot from time to time
id 'org.panteleyev.jpackageplugin' version '1.5.2' apply false
id 'org.sonarqube' version '4.4.1.3373'
Expand Down

0 comments on commit 405fc7e

Please sign in to comment.