-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Support arbitrary Java versions with JRE
conditions
#3931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support arbitrary Java versions with JRE
conditions
#3931
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
As can be inferred from the demo tests in the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extensibility of this looks good to me, @sbrannen. Thanks for looking at it.
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/EnabledForJreRange.java
Show resolved
Hide resolved
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/EnabledForJreRange.java
Outdated
Show resolved
Hide resolved
Glad you like it, and thanks for reviewing it, @wilkinsona! 👍 |
fee1aa0
to
1f8cf87
Compare
JRE
conditions
1f8cf87
to
c386d4c
Compare
a6b9b54
to
9b3c212
Compare
With the latest force pushed changes for this PR, the generated /*
* Copyright 2015-2025 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.jupiter.api.condition;
import static org.apiguardian.api.API.Status.DEPRECATED;
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
import static org.apiguardian.api.API.Status.STABLE;
import java.lang.reflect.Method;
import org.apiguardian.api.API;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junit.platform.commons.support.ReflectionSupport;
import org.junit.platform.commons.util.StringUtils;
/**
* Enumeration of Java Runtime Environment (JRE) versions.
*
* <p>If the current JRE version cannot be detected — for example, if the
* {@code java.version} JVM system property is undefined — then none of
* the constants defined in this enum will be considered to be the
* {@linkplain #isCurrentVersion current JRE version}.
*
* @since 5.1
* @see #JAVA_8
* @see #JAVA_9
* @see #JAVA_10
* @see #JAVA_11
* @see #JAVA_12
* @see #JAVA_13
* @see #JAVA_14
* @see #JAVA_15
* @see #JAVA_16
* @see #JAVA_17
* @see #JAVA_18
* @see #JAVA_19
* @see #JAVA_20
* @see #JAVA_21
* @see #JAVA_22
* @see #JAVA_23
* @see #JAVA_24
* @see #JAVA_25
* @see #OTHER
* @see EnabledOnJre
* @see DisabledOnJre
* @see EnabledForJreRange
* @see DisabledForJreRange
*/
@API(status = STABLE, since = "5.1")
public enum JRE {
/**
* An undefined JRE version.
*
* <p>This constant is used by JUnit as a default configuration value but is
* not intended to be used by users.
*
* <p>This constant returns {@code -1} for its {@link #version() version}.
*
* @since 5.12
*/
@API(status = EXPERIMENTAL, since = "5.12")
UNDEFINED(-1),
/**
* Java 8.
*/
JAVA_8(8),
/**
* Java 9.
*/
JAVA_9(9),
/**
* Java 10.
*/
JAVA_10(10),
/**
* Java 11.
*/
JAVA_11(11),
/**
* Java 12.
*
* @since 5.4
*/
@API(status = STABLE, since = "5.4")
JAVA_12(12),
/**
* Java 13.
*
* @since 5.4
*/
@API(status = STABLE, since = "5.4")
JAVA_13(13),
/**
* Java 14.
*
* @since 5.5
*/
@API(status = STABLE, since = "5.5")
JAVA_14(14),
/**
* Java 15.
*
* @since 5.6
*/
@API(status = STABLE, since = "5.6")
JAVA_15(15),
/**
* Java 16.
*
* @since 5.7
*/
@API(status = STABLE, since = "5.7")
JAVA_16(16),
/**
* Java 17.
*
* @since 5.7.1
*/
@API(status = STABLE, since = "5.7.1")
JAVA_17(17),
/**
* Java 18.
*
* @since 5.8.1
*/
@API(status = STABLE, since = "5.8.1")
JAVA_18(18),
/**
* Java 19.
*
* @since 5.9
*/
@API(status = STABLE, since = "5.9")
JAVA_19(19),
/**
* Java 20.
*
* @since 5.9
*/
@API(status = STABLE, since = "5.9")
JAVA_20(20),
/**
* Java 21.
*
* @since 5.9.2
*/
@API(status = STABLE, since = "5.9.2")
JAVA_21(21),
/**
* Java 22.
*
* @since 5.10
*/
@API(status = STABLE, since = "5.10")
JAVA_22(22),
/**
* Java 23.
*
* @since 5.11
*/
@API(status = STABLE, since = "5.11")
JAVA_23(23),
/**
* Java 24.
*
* @since 5.11
*/
@API(status = STABLE, since = "5.11")
JAVA_24(24),
/**
* Java 25.
*
* @since 5.11.4
*/
@API(status = STABLE, since = "5.11.4")
JAVA_25(25),
/**
* A JRE version other than {@link #JAVA_8}, {@link #JAVA_9},
* {@link #JAVA_10}, {@link #JAVA_11}, {@link #JAVA_12},
* {@link #JAVA_13}, {@link #JAVA_14}, {@link #JAVA_15},
* {@link #JAVA_16}, {@link #JAVA_17}, {@link #JAVA_18},
* {@link #JAVA_19}, {@link #JAVA_20}, {@link #JAVA_21},
* {@link #JAVA_22}, {@link #JAVA_23}, {@link #JAVA_24},
* or {@link #JAVA_25}.
*
* <p>This constant returns {@link Integer#MAX_VALUE} for its
* {@link #version() version}.
*/
OTHER(Integer.MAX_VALUE);
static final int UNDEFINED_VERSION = -1;
private static final Logger logger = LoggerFactory.getLogger(JRE.class);
private static final int CURRENT_VERSION = determineCurrentVersion();
private static final JRE CURRENT_JRE = determineCurrentJre(CURRENT_VERSION);
private static int determineCurrentVersion() {
String javaVersion = System.getProperty("java.version");
boolean javaVersionIsBlank = StringUtils.isBlank(javaVersion);
if (javaVersionIsBlank) {
logger.debug(
() -> "JVM system property 'java.version' is undefined. It is therefore not possible to detect Java 8.");
}
if (!javaVersionIsBlank && javaVersion.startsWith("1.8")) {
return 8;
}
try {
// java.lang.Runtime.version() is a static method available on Java 9+
// that returns an instance of java.lang.Runtime.Version which has the
// following method: public int major()
Method versionMethod = Runtime.class.getMethod("version");
Object version = ReflectionSupport.invokeMethod(versionMethod, null);
Method majorMethod = version.getClass().getMethod("major");
return (int) ReflectionSupport.invokeMethod(majorMethod, version);
}
catch (Exception ex) {
logger.debug(ex, () -> "Failed to determine the current JRE version via java.lang.Runtime.Version.");
}
return UNDEFINED_VERSION;
}
private static JRE determineCurrentJre(int currentVersion) {
switch (currentVersion) {
case UNDEFINED_VERSION:
// null signals that the current JRE version is undefined.
return null;
case 8:
return JAVA_8;
case 9:
return JAVA_9;
case 10:
return JAVA_10;
case 11:
return JAVA_11;
case 12:
return JAVA_12;
case 13:
return JAVA_13;
case 14:
return JAVA_14;
case 15:
return JAVA_15;
case 16:
return JAVA_16;
case 17:
return JAVA_17;
case 18:
return JAVA_18;
case 19:
return JAVA_19;
case 20:
return JAVA_20;
case 21:
return JAVA_21;
case 22:
return JAVA_22;
case 23:
return JAVA_23;
case 24:
return JAVA_24;
case 25:
return JAVA_25;
default:
return OTHER;
}
}
private final int version;
private JRE(int version) {
this.version = version;
}
/**
* Get the version of <em>this</em> {@code JRE}.
*
* <p>If this {@code JRE} is {@link #UNDEFINED}, this method returns
* {@code -1}. If this {@code JRE} is {@link #OTHER}, this method returns
* {@link Integer#MAX_VALUE}.
*
* @return the version of this {@code JRE}
* @since 5.12
* @see Runtime.Version#feature()
* @see #currentVersionNumber()
*/
@API(status = EXPERIMENTAL, since = "5.12")
public int version() {
return this.version;
}
/**
* @return {@code true} if <em>this</em> {@code JRE} is known to be the
* Java Runtime Environment version for the currently executing JVM or if
* the version is {@link #OTHER}
*
* @see #currentJre()
* @see #currentVersionNumber()
*/
public boolean isCurrentVersion() {
return this == CURRENT_JRE;
}
/**
* @return the {@link JRE} for the currently executing JVM, potentially
* {@link #OTHER}
*
* @since 5.7
* @see #currentVersionNumber()
* @deprecated in favor of {@link #currentJre()}
*/
@API(status = DEPRECATED, since = "5.12")
@Deprecated
public static JRE currentVersion() {
return currentJre();
}
/**
* @return the {@link JRE} for the currently executing JVM, potentially
* {@link #OTHER}
*
* @since 5.12
* @see #currentVersionNumber()
*/
@API(status = EXPERIMENTAL, since = "5.12")
public static JRE currentJre() {
return CURRENT_JRE;
}
/**
* @return the version number for the currently executing JVM, or {@code -1}
* to signal that the version is undefined
*
* @since 5.12
* @see Runtime.Version#feature()
* @see #currentJre()
*/
@API(status = EXPERIMENTAL, since = "5.12")
public static int currentVersionNumber() {
return CURRENT_VERSION;
}
/**
* @return {@code true} if the supplied version number is known to be the
* Java Runtime Environment version for the currently executing JVM or if
* the supplied version number is {@code -1} and the version of the current
* JVM is unknown
*
* @since 5.12
* @see Runtime.Version#feature()
*/
@API(status = EXPERIMENTAL, since = "5.12")
public static boolean isCurrentVersion(int version) {
return version == CURRENT_VERSION;
}
static boolean isCurrentVersionWithinRange(int min, int max) {
return CURRENT_VERSION >= min && CURRENT_VERSION <= max;
}
} Note the introduction of the In addition, |
This commit introduces support for arbitrary Java versions in the JRE enum, @EnabledOnJre, @DisabledOnJre, @EnabledForJreRange, and @DisabledForJreRange. Closes: junit-team#3930 Closes: junit-team#3931
9b3c212
to
4c4593f
Compare
This commit introduces support for arbitrary Java versions in the JRE enum, @EnabledOnJre, @DisabledOnJre, @EnabledForJreRange, and @DisabledForJreRange. Closes: junit-team#3930 Closes: junit-team#3931
4c4593f
to
d197f5a
Compare
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/DisabledOnJreCondition.java
Outdated
Show resolved
Hide resolved
This commit introduces support for arbitrary Java versions in the JRE enum, @EnabledOnJre, @DisabledOnJre, @EnabledForJreRange, and @DisabledForJreRange. Closes: junit-team#3930 Closes: junit-team#3931
d197f5a
to
cc6a514
Compare
This commit introduces support for arbitrary Java versions in the JRE enum, @EnabledOnJre, @DisabledOnJre, @EnabledForJreRange, and @DisabledForJreRange. Closes: junit-team#3930 Closes: junit-team#3931
cc6a514
to
699af22
Compare
junit-jupiter-api/src/templates/resources/main/org/junit/jupiter/api/condition/JRE.java.jte
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/templates/resources/main/org/junit/jupiter/api/condition/JRE.java.jte
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/templates/resources/main/org/junit/jupiter/api/condition/JRE.java.jte
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/templates/resources/main/org/junit/jupiter/api/condition/JRE.java.jte
Outdated
Show resolved
Hide resolved
...-jupiter-api/src/main/java/org/junit/jupiter/api/condition/DisabledForJreRangeCondition.java
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/DisabledOnJreCondition.java
Outdated
Show resolved
Hide resolved
...t-jupiter-api/src/main/java/org/junit/jupiter/api/condition/EnabledForJreRangeCondition.java
Outdated
Show resolved
Hide resolved
See: junit-team#3931 Co-authored-by: Marc Philipp <mail@marcphilipp.de>
67f73f9
to
d292998
Compare
5f40351
to
fddfeee
Compare
See: #3931 Co-authored-by: Marc Philipp <mail@marcphilipp.de>
Overview
This PR introduces support for arbitrary Java versions in the
JRE
enum,@EnabledOnJre
,@DisabledOnJre
,@EnabledForJreRange
, and@DisabledForJreRange
.Closes: #3930
Related Issues
JAVA_23
andJAVA_24
JRE
constants to5.10.x
#3918JRE
conditions #3930Definition of Done
@API
annotations