diff --git a/.github/workflows/lapis2.yml b/.github/workflows/lapis2.yml index 954bdb57..0b9263af 100644 --- a/.github/workflows/lapis2.yml +++ b/.github/workflows/lapis2.yml @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@v4 - - name: Set up JDK 19 + name: Set up JDK uses: actions/setup-java@v4 with: - java-version: '19' + java-version: '21' distribution: 'adopt' - name: Execute Tests @@ -39,10 +39,10 @@ jobs: - uses: actions/checkout@v4 - - name: Set up JDK 19 + name: Set up JDK uses: actions/setup-java@v4 with: - java-version: '19' + java-version: '21' distribution: 'adopt' - name: Login to GitHub Container Registry @@ -90,10 +90,10 @@ jobs: - uses: actions/checkout@v4 - - name: Set up JDK 19 + name: Set up JDK uses: actions/setup-java@v4 with: - java-version: '19' + java-version: '21' distribution: 'adopt' - name: Setup Node.js diff --git a/lapis2/build.gradle b/lapis2/build.gradle index 530d0f9a..f89d29bf 100644 --- a/lapis2/build.gradle +++ b/lapis2/build.gradle @@ -1,12 +1,11 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent -import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - id 'org.springframework.boot' version '3.1.5' + id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' - id 'org.jetbrains.kotlin.jvm' version '1.9.20' - id 'org.jetbrains.kotlin.plugin.spring' version '1.9.20' + id 'org.jetbrains.kotlin.jvm' version '1.9.21' + id 'org.jetbrains.kotlin.plugin.spring' version '1.9.21' id 'org.jlleitschuh.gradle.ktlint' version "11.6.1" id 'org.springdoc.openapi-gradle-plugin' version "1.8.0" id 'antlr' @@ -14,7 +13,15 @@ plugins { group = 'org.genspectrum' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '19' + +java { + sourceCompatibility = '21' + targetCompatibility = '21' +} + +kotlin { + jvmToolchain(21) +} repositories { mavenCentral() @@ -43,10 +50,6 @@ dependencies { compileKotlin { dependsOn generateGrammarSource - compilerOptions { - freeCompilerArgs.add("-Xexport-kdoc") - jvmTarget.set(JvmTarget.JVM_19) - } } tasks.named('runKtlintCheckOverMainSourceSet') { @@ -69,7 +72,7 @@ tasks.named('test') { } tasks.named('bootBuildImage') { - environment["BP_JVM_VERSION"] = "20" + environment["BP_JVM_VERSION"] = "21" environment["BPE_SPRING_PROFILES_ACTIVE"] = "docker" environment["BPE_LAPIS_REFERENCE_GENOME_FILENAME"] = "./reference_genomes.json" imageName = "ghcr.io/genspectrum/${project.name}" diff --git a/lapis2/gradle/wrapper/gradle-wrapper.jar b/lapis2/gradle/wrapper/gradle-wrapper.jar index 943f0cbf..249e5832 100644 Binary files a/lapis2/gradle/wrapper/gradle-wrapper.jar and b/lapis2/gradle/wrapper/gradle-wrapper.jar differ diff --git a/lapis2/gradle/wrapper/gradle-wrapper.properties b/lapis2/gradle/wrapper/gradle-wrapper.properties index 744c64d1..a5952066 100644 --- a/lapis2/gradle/wrapper/gradle-wrapper.properties +++ b/lapis2/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip -networkTimeout=10000 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/lapis2/gradlew b/lapis2/gradlew index 65dcd68d..a69d9cb6 100755 --- a/lapis2/gradlew +++ b/lapis2/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,11 +80,11 @@ do esac done -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,16 +143,12 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/lapis2/gradlew.bat b/lapis2/gradlew.bat index 6689b85b..53a6b238 100644 --- a/lapis2/gradlew.bat +++ b/lapis2/gradlew.bat @@ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/lapis2/src/main/kotlin/org/genspectrum/lapis/controller/ExceptionHandler.kt b/lapis2/src/main/kotlin/org/genspectrum/lapis/controller/ExceptionHandler.kt index f3a412ca..f79f9f19 100644 --- a/lapis2/src/main/kotlin/org/genspectrum/lapis/controller/ExceptionHandler.kt +++ b/lapis2/src/main/kotlin/org/genspectrum/lapis/controller/ExceptionHandler.kt @@ -3,6 +3,7 @@ package org.genspectrum.lapis.controller import mu.KotlinLogging import org.genspectrum.lapis.model.SiloNotImplementedError import org.genspectrum.lapis.silo.SiloException +import org.springframework.core.annotation.Order import org.springframework.http.HttpStatus import org.springframework.http.HttpStatusCode import org.springframework.http.MediaType @@ -12,11 +13,32 @@ import org.springframework.web.bind.annotation.ControllerAdvice import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler +import org.springframework.web.servlet.resource.NoResourceFoundException private val log = KotlinLogging.logger {} private typealias ErrorResponse = ResponseEntity +/** + * Taken from https://github.com/spring-projects/spring-framework/issues/31569#issuecomment-1825444419 + * Due to https://github.com/spring-projects/spring-framework/commit/c00508d6cf2408d06a0447ed193ad96466d0d7b4 + * + * This forwards "404" errors to the ErrorController to allow it to return a view. + * Thus, browsers get their own error page. + * + * Spring reworked handling of "404 not found" errors. This was introduced with the upgrade to Spring boot 3.2.0. + * This can be removed/reworked once Spring decides on how to return a view from an ExceptionHandler + * or allows them to respect the Accept header. + */ +@ControllerAdvice +@Order(-1) +internal class ExceptionToErrorControllerBypass { + @ExceptionHandler(NoResourceFoundException::class) + fun handleResourceNotFound(e: Exception): Nothing { + throw e + } +} + @ControllerAdvice class ExceptionHandler : ResponseEntityExceptionHandler() { @ExceptionHandler(Throwable::class) diff --git a/lapis2/src/main/kotlin/org/genspectrum/lapis/logging/StatisticsLogObjectMapper.kt b/lapis2/src/main/kotlin/org/genspectrum/lapis/logging/StatisticsLogObjectMapper.kt index 7853eedd..62c233fc 100644 --- a/lapis2/src/main/kotlin/org/genspectrum/lapis/logging/StatisticsLogObjectMapper.kt +++ b/lapis2/src/main/kotlin/org/genspectrum/lapis/logging/StatisticsLogObjectMapper.kt @@ -10,15 +10,12 @@ import org.springframework.stereotype.Component @Component class StatisticsLogObjectMapper(objectMapperBuilder: Jackson2ObjectMapperBuilder) { - private val mapper: ObjectMapper - - init { - mapper = objectMapperBuilder.build() - mapper.registerModule(JavaTimeModule()) - mapper.registerModule(kotlinModule()) - mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) - mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL) + private val mapper = objectMapperBuilder.build().apply { + registerModule(JavaTimeModule()) + registerModule(kotlinModule()) + configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + setSerializationInclusion(JsonInclude.Include.NON_NULL) } fun writeValueAsString(requestContext: RequestContext): String {