Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ extra["license"] = License(
val mavenizedProjects = listOf(
projects.junitStart,
projects.junitPlatformCommons,
projects.junitPlatformConfigurationApi,
projects.junitPlatformConfigurationProcessor,
projects.junitPlatformConsole,
projects.junitPlatformConsoleStandalone,
projects.junitPlatformEngine,
Expand Down
5 changes: 4 additions & 1 deletion junit-jupiter-api/junit-jupiter-api.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ plugins {
description = "JUnit Jupiter API"

dependencies {
annotationProcessor(projects.junitPlatformConfigurationProcessor)

api(platform(projects.junitBom))
api(libs.opentest4j)
api(projects.junitPlatformCommons)
Expand All @@ -17,6 +19,7 @@ dependencies {
compileOnlyApi(libs.jspecify)

compileOnly(kotlin("stdlib"))
compileOnly(projects.junitPlatformConfigurationApi)

testFixturesImplementation(libs.assertj)
testFixturesImplementation(testFixtures(projects.junitPlatformCommons))
Expand All @@ -35,7 +38,7 @@ eclipseConventions {

tasks {
compileJava {
options.compilerArgs.add("-Xlint:-module") // due to qualified exports
options.compilerArgs.add("-Xlint:-module,-processing") // -module: due to qualified exports, -processing: not all annotations need to be processed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What warnings does this emit without -processing?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complain about all present annotations that weren't claimed by a processor.

Similar too:

https://stackoverflow.com/questions/69439506/no-processor-claimed-any-of-these-annotations

}
jar {
bundle {
Expand Down
1 change: 1 addition & 0 deletions junit-jupiter-api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
requires transitive org.junit.platform.commons;
requires transitive org.opentest4j;

requires static org.junit.platform.configuration.api;
requires static kotlin.stdlib;

exports org.junit.jupiter.api;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.platform.configuration.api.ConfigurationProperty;

/**
* Collection of configuration constants for the Jupiter test engine.
Expand Down Expand Up @@ -64,6 +65,7 @@ public final class Constants {
*
* <p>Note: A class that matches both an inclusion and exclusion pattern will be excluded.
*/
@ConfigurationProperty
public static final String EXTENSIONS_AUTODETECTION_INCLUDE_PROPERTY_NAME = "junit.jupiter.extensions.autodetection.include";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
id("junitbuild.java-library-conventions")
}

description = "JUnit Platform Configuration API"

dependencies {
api(platform(projects.junitBom))
api(projects.junitPlatformCommons)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need that?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but the way OSGI is setup makes it a requirement for every module.


compileOnlyApi(libs.apiguardian)
compileOnlyApi(libs.jspecify)
}

backwardCompatibilityChecks {
enabled = false // not yet released
}
16 changes: 16 additions & 0 deletions junit-platform-configuration-api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright 2015-2026 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

module org.junit.platform.configuration.api {
requires static transitive org.jspecify;
requires static transitive org.apiguardian.api;

exports org.junit.platform.configuration.api;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2026 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.platform.configuration.api;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.apiguardian.api.API;

@API(status = API.Status.EXPERIMENTAL)
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface ConfigurationProperty {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright 2012 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

@NullMarked
package org.junit.platform.configuration.api;

import org.jspecify.annotations.NullMarked;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should build this as a fat/shadowed jar to make it easy to put it on the annotation processor classpath. No need to do that now, but let's discuss it.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
id("junitbuild.java-library-conventions")
}

description = "JUnit Platform Configuration Processor"

dependencies {
api(platform(projects.junitBom))
api(projects.junitPlatformConfigurationApi)
api(projects.junitPlatformCommons)

compileOnlyApi(libs.apiguardian)
compileOnlyApi(libs.jspecify)
}

backwardCompatibilityChecks {
enabled = false // not yet released
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2015-2026 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

module org.junit.platform.configuration.processor {
requires static transitive org.jspecify;
requires static transitive org.apiguardian.api;

requires java.compiler;
requires org.junit.platform.configuration.api;

provides javax.annotation.processing.Processor with org.junit.platform.configuration.processor.ConfigurationMetadataAnnotationProcessor;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2026 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.platform.configuration.processor;

import static java.util.Objects.requireNonNull;

import java.nio.charset.StandardCharsets;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.StandardLocation;

import org.apiguardian.api.API;
import org.jspecify.annotations.Nullable;

@API(status = API.Status.EXPERIMENTAL)
@SupportedSourceVersion(SourceVersion.RELEASE_17)
@SupportedAnnotationTypes("org.junit.platform.configuration.api.ConfigurationProperty")
public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor {
private static final String METADATA_PATH = "META-INF/junit-platform-configuration-metadata.json";
private @Nullable ProcessingEnvironment environment;

@Override
public synchronized void init(ProcessingEnvironment environment) {
super.init(environment);
this.environment = environment;
}

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
try {
var resource = requireNonNull(environment).getFiler().createResource(StandardLocation.CLASS_OUTPUT, "",
METADATA_PATH);
try (var out = resource.openOutputStream()) {
out.write("{}".getBytes(StandardCharsets.UTF_8));
}
}
catch (Exception ex) {
throw new IllegalStateException("Failed to write metadata", ex);
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright 2012 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

@NullMarked
package org.junit.platform.configuration.processor;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.junit.platform.configuration.processor.ConfigurationMetadataAnnotationProcessor,aggregating
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.junit.platform.configuration.processor.ConfigurationMetadataAnnotationProcessor
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ tasks {
// https://github.com/junit-team/junit-framework/issues/2557
// exclude compiled module declarations from any source (e.g. /*, /META-INF/versions/N/*)
exclude("**/module-info.class")
// TODO: merge meta data files?
exclude("META-INF/junit-platform-configuration-metadata.json")
// https://github.com/junit-team/junit-framework/issues/761
// prevent duplicates, add 3rd-party licenses explicitly
exclude("**/COPYRIGHT*")
Expand Down
7 changes: 7 additions & 0 deletions junit-platform-launcher/junit-platform-launcher.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ plugins {
description = "JUnit Platform Launcher"

dependencies {
annotationProcessor(projects.junitPlatformConfigurationProcessor)

api(platform(projects.junitBom))
api(projects.junitPlatformEngine)

compileOnlyApi(libs.apiguardian)
compileOnlyApi(libs.jspecify)

compileOnly(projects.junitPlatformConfigurationApi)

osgiVerification(projects.junitJupiterEngine)
}

Expand All @@ -20,6 +24,9 @@ javadocConventions {
}

tasks {
compileJava {
options.compilerArgs.add("-Xlint:-processing") // -processing: not all annotations need to be processed
}
jar {
bundle {
bnd("""
Expand Down
2 changes: 2 additions & 0 deletions junit-platform-launcher/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

requires static transitive org.apiguardian.api;
requires static transitive org.jspecify;

requires static org.junit.platform.configuration.api;
requires static jdk.jfr;

requires transitive java.logging;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.apiguardian.api.API;
import org.junit.platform.commons.util.ClassNamePatternFilterUtils;
import org.junit.platform.configuration.api.ConfigurationProperty;
import org.junit.platform.engine.EngineDiscoveryRequest;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.reporting.ReportEntry;
Expand Down Expand Up @@ -44,6 +45,7 @@ public class LauncherConstants {
* @see ReportEntry
* @see TestExecutionListener#reportingEntryPublished(TestIdentifier, ReportEntry)
*/
@ConfigurationProperty
public static final String CAPTURE_STDOUT_PROPERTY_NAME = "junit.platform.output.capture.stdout";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ClasspathAlignmentChecker {
"org.junit.jupiter.params", //
"org.junit.platform.commons", //
"org.junit.platform.console", //
"org.junit.platform.configuration.api", //
"org.junit.platform.configuration.processor", //
"org.junit.platform.engine", //
"org.junit.platform.launcher", //
"org.junit.platform.reporting", //
Expand Down
6 changes: 5 additions & 1 deletion junit-vintage-engine/junit-vintage-engine.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ plugins {
description = "JUnit Vintage Engine"

dependencies {
annotationProcessor(projects.junitPlatformConfigurationProcessor)

api(platform(projects.junitBom))
api(projects.junitPlatformEngine)
api(libs.junit4)

compileOnlyApi(libs.apiguardian)
compileOnlyApi(libs.jspecify)

compileOnly(projects.junitPlatformConfigurationApi)

testFixturesApi(platform(libs.groovy2.bom))
testFixturesApi(libs.spock1)
testFixturesImplementation(projects.junitPlatformSuiteApi)
Expand All @@ -33,7 +37,7 @@ dependencies {

tasks {
compileJava {
options.compilerArgs.add("-Xlint:-requires-automatic") // JUnit 4
options.compilerArgs.add("-Xlint:-requires-automatic,-processing") // -requires-automatic: JUnit 4, -module: due to qualified exports, -processing: not all annotations need to be processed
}
compileTestFixturesGroovy {
javaLauncher = project.javaToolchains.launcherFor {
Expand Down
1 change: 1 addition & 0 deletions junit-vintage-engine/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
module org.junit.vintage.engine {

requires static org.apiguardian.api;
requires static org.junit.platform.configuration.api;
requires static transitive org.jspecify;

requires junit; // 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static org.apiguardian.api.API.Status.MAINTAINED;

import org.apiguardian.api.API;
import org.junit.platform.configuration.api.ConfigurationProperty;

/**
* Collection of constants related to the {@link VintageTestEngine}.
Expand All @@ -34,6 +35,7 @@ public final class Constants {
* @since 5.12
*/
@API(status = MAINTAINED, since = "5.13.3")
@ConfigurationProperty
public static final String PARALLEL_EXECUTION_ENABLED = "junit.vintage.execution.parallel.enabled";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ requires kotlin.stdlib static
requires org.apiguardian.api static transitive
requires org.jspecify static transitive
requires org.junit.platform.commons transitive
requires org.junit.platform.configuration.api static
requires org.opentest4j transitive
qualified exports org.junit.jupiter.api.timeout to org.junit.jupiter.engine
qualified opens org.junit.jupiter.api.condition to org.junit.platform.commons
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
org.junit.platform.configuration.api@${version} jar:file:.+/junit-platform-configuration-api-\d.+\.jar..module-info\.class
exports org.junit.platform.configuration.api
requires java.base mandated
requires org.apiguardian.api static transitive
requires org.jspecify static transitive
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
org.junit.platform.configuration.processor@${version} jar:file:.+/junit-platform-configuration-processor-\d.+\.jar..module-info\.class
requires java.base mandated
requires java.compiler
requires org.apiguardian.api static transitive
requires org.jspecify static transitive
requires org.junit.platform.configuration.api
provides javax.annotation.processing.Processor with org.junit.platform.configuration.processor.ConfigurationMetadataAnnotationProcessor
contains org.junit.platform.configuration.processor
Loading
Loading