Skip to content

Commit e2a0ee3

Browse files
Add multi-release jar with module-info.java
Also apply minor changes to Gradle setup - most notably, hardcode values taken from configuration properties that are not required to be configurable.
1 parent 1901634 commit e2a0ee3

7 files changed

Lines changed: 117 additions & 31 deletions

File tree

build.gradle.kts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import com.diffplug.spotless.LineEnding
22

33
plugins {
44
id("internal.java-library-convention")
5+
id("internal.mrjar-module-info-convention")
56
id("internal.publishing-convention")
67
alias(libs.plugins.nmcp)
78
alias(libs.plugins.spotless)
@@ -78,24 +79,3 @@ spotless {
7879
lineEndings = LineEnding.UNIX
7980
}
8081
}
81-
82-
// This module targets Java 8 for its main sources to maintain compatibility with older runtime environments used by
83-
// dependent systems.
84-
//
85-
// Unit tests, however, are executed on Java 17 because JUnit 6 requires Java 17 or newer. The Gradle toolchain
86-
// configuration ensures that only the test compilation and execution use Java 17, while the main code remains compiled
87-
// for Java 8.
88-
//
89-
// In short:
90-
// - src/main -> Java 8 (for compatibility)
91-
// - src/test -> Java 17 (required by JUnit 6)
92-
93-
// JUnit 6 requires at Java 17+, main keeps Java 8.
94-
tasks.named<JavaCompile>("compileTestJava") {
95-
javaCompiler = javaToolchains.compilerFor { languageVersion = JavaLanguageVersion.of(17) }
96-
}
97-
98-
// JUnit 6 requires at Java 17+, main keeps Java 8.
99-
tasks.withType<Test>().configureEach {
100-
javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(17) }
101-
}

buildSrc/src/main/kotlin/internal.common-convention.gradle.kts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
group = property("internal.group") as String
2-
3-
//
4-
// Not assigning version as it is assigned in CI/CD using -Pversion=X.Y.Z parameter.
5-
//
6-
71
repositories {
82
mavenCentral()
93
}

buildSrc/src/main/kotlin/internal.java-library-convention.gradle.kts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
}
88

99
java {
10-
toolchain.languageVersion = providers.gradleProperty("internal.java.version").map { JavaLanguageVersion.of(it) }
10+
toolchain.languageVersion = JavaLanguageVersion.of(8)
1111
withSourcesJar()
1212
withJavadocJar()
1313
}
@@ -45,3 +45,24 @@ tasks.withType<Test>().configureEach {
4545
systemProperty("user.language", "en")
4646
systemProperty("user.country", "US")
4747
}
48+
49+
// This library targets Java 8 for its main sources to maintain compatibility with older runtime environments used by
50+
// dependent systems.
51+
//
52+
// Unit tests, however, are executed on Java 17 because JUnit 6 requires Java 17 or newer. The Gradle toolchain
53+
// configuration ensures that only the test compilation and execution use Java 17, while the main code remains compiled
54+
// for Java 8.
55+
//
56+
// In short:
57+
// - src/main -> Java 8 (for compatibility)
58+
// - src/test -> Java 17 (required by JUnit 6)
59+
60+
// JUnit 6 requires at Java 17+, main keeps Java 8.
61+
tasks.named<JavaCompile>("compileTestJava") {
62+
javaCompiler = javaToolchains.compilerFor { languageVersion = JavaLanguageVersion.of(17) }
63+
}
64+
65+
// JUnit 6 requires at Java 17+, main keeps Java 8.
66+
tasks.withType<Test>().configureEach {
67+
javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(17) }
68+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
plugins {
2+
id("internal.common-convention")
3+
id("java-library")
4+
}
5+
6+
// This convention plugin adds compilation of module-info.java with Java 9 transforms output into a multi-release JAR
7+
// for supporting modules if used by Java 9+.
8+
9+
val sourceSets = extensions.getByType<SourceSetContainer>()
10+
11+
val main9SourceSet = sourceSets.create("main9") {
12+
java.srcDirs("src/main9/java", "src/main/java")
13+
}
14+
15+
configurations.named(main9SourceSet.compileClasspathConfigurationName) {
16+
extendsFrom(configurations.named("compileClasspath").get())
17+
}
18+
configurations.named(main9SourceSet.runtimeClasspathConfigurationName) {
19+
extendsFrom(configurations.named("runtimeClasspath").get())
20+
}
21+
22+
tasks.named<JavaCompile>("compileMain9Java") {
23+
javaCompiler = javaToolchains.compilerFor { languageVersion = JavaLanguageVersion.of(9) }
24+
}
25+
26+
tasks.named<Jar>("jar") {
27+
into("META-INF/versions/9") {
28+
from(main9SourceSet.output) {
29+
include("module-info.class")
30+
}
31+
}
32+
manifest {
33+
attributes["Multi-Release"] = "true"
34+
}
35+
}

gradle.properties

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ org.gradle.configuration-cache=true
33
org.gradle.parallel=true
44
org.gradle.workers.max=4
55
#
6+
# Project settings
7+
group=io.github.problem4j
8+
#
69
# Project internal settings
7-
internal.java.version=8
8-
internal.group=io.github.problem4j
910
internal.pom.url=https://github.com/problem4j/problem4j-core
1011
internal.pom.inception-year=2025
1112
internal.pom.licenses.0.name=MIT License

src/main/java/io/github/problem4j/core/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121

2222
/**
23-
* Core classes and interfaces for the Problem4J library, implementing <a
23+
* Core classes and interfaces for the Problem4J set of libraries, implementing <a
2424
* href="https://tools.ietf.org/html/rfc7807">RFC 7807: Problem Details for HTTP APIs</a>.
2525
*
2626
* <p>RFC 7807 was later extended in <a href="https://tools.ietf.org/html/rfc9457">RFC 9457</a>,

src/main9/java/module-info.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2025-2026 Problem4J Team & Contributors
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in all
11+
* copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
* SOFTWARE.
20+
*/
21+
22+
import org.jspecify.annotations.NullMarked;
23+
24+
/**
25+
* Core classes and interfaces for the Problem4J set of libraries, implementing <a
26+
* href="https://tools.ietf.org/html/rfc7807">RFC 7807: Problem Details for HTTP APIs</a>.
27+
*
28+
* <p>RFC 7807 was later extended in <a href="https://tools.ietf.org/html/rfc9457">RFC 9457</a>,
29+
* however core concepts remain the same.
30+
*
31+
* <p>This package provides the foundational types for modeling "Problem Details" objects, which are
32+
* used to convey machine-readable error details in HTTP responses.
33+
*
34+
* <p>Key components include:
35+
*
36+
* <ul>
37+
* <li>{@code Problem}: The central immutable model representing a problem detail.
38+
* <li>{@code ProblemBuilder}: A fluent builder for creating {@code Problem} instances.
39+
* <li>{@code ProblemException}: A runtime exception that wraps a {@code Problem}, allowing it to
40+
* be thrown and handled by structured error handlers.
41+
* <li>{@code ProblemMapping}: An annotation for configuring how exceptions should be mapped to
42+
* {@code Problem} instances, supporting message interpolation and automatic mapping.
43+
* <li>{@code ProblemMapper}: A utility for mapping exceptions to {@code Problem} instances,
44+
* supporting annotation-based configuration for automatic mapping.
45+
* </ul>
46+
*
47+
* <p>This library is framework-agnostic and intended to be used as a basis for higher-level
48+
* integrations (e.g., with Spring Boot, Micronaut, or other web frameworks).
49+
*/
50+
@NullMarked
51+
module io.github.problem4j.core {
52+
requires static org.jspecify;
53+
54+
exports io.github.problem4j.core;
55+
}

0 commit comments

Comments
 (0)