Replace use of deprecated JdkVersion API by looking for presence of classes

This commit updates ConditionalOnJava to remove a dependency on the
deprecated JdkVersion API from Spring Framework. In its place it now
looks for the presence of certain classes to determine the version of
Java on which its running.

Closes gh-4005
This commit is contained in:
Andy Wilkinson
2015-10-02 18:10:21 +01:00
parent 6a31c1dda1
commit eae7b0364b
2 changed files with 90 additions and 14 deletions

View File

@@ -22,8 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.flywaydb.core.internal.util.ClassUtils;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.JdkVersion;
import org.springframework.util.Assert;
/**
@@ -32,6 +32,7 @@ import org.springframework.util.Assert;
*
* @author Oliver Gierke
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.1.0
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@@ -78,32 +79,35 @@ public @interface ConditionalOnJava {
enum JavaVersion {
/**
* Java 1.6.
* Java 1.9.
*/
SIX(JdkVersion.JAVA_16, "1.6"),
/**
* Java 1.7.
*/
SEVEN(JdkVersion.JAVA_17, "1.7"),
NINE(9, "1.9", "java.security.cert.URICertStoreParameters"),
/**
* Java 1.8.
*/
EIGHT(JdkVersion.JAVA_18, "1.8"),
EIGHT(8, "1.8", "java.util.function.Function"),
/**
* Java 1.9.
* Java 1.7.
*/
NINE(JdkVersion.JAVA_19, "1.9");
SEVEN(7, "1.7", "java.nio.file.Files"),
/**
* Java 1.6.
*/
SIX(6, "1.6", "java.util.ServiceLoader");
private final int value;
private final String name;
JavaVersion(int value, String name) {
private final boolean available;
JavaVersion(int value, String name, String className) {
this.value = value;
this.name = name;
this.available = ClassUtils.isPresent(className, getClass().getClassLoader());
}
/**
@@ -134,9 +138,8 @@ public @interface ConditionalOnJava {
* @return the {@link JavaVersion}
*/
public static JavaVersion getJavaVersion() {
int version = JdkVersion.getMajorJavaVersion();
for (JavaVersion candidate : JavaVersion.values()) {
if (candidate.value == version) {
if (candidate.available) {
return candidate;
}
}

View File

@@ -16,6 +16,15 @@
package org.springframework.boot.autoconfigure.condition;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Function;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
@@ -23,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.Range;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -85,6 +95,41 @@ public class ConditionalOnJavaTests {
+ "older than 1.6 found 1.7"));
}
@Test
public void java8IsDetected() throws Exception {
assertThat(getJavaVersion(), is("1.8"));
}
@Test
public void java7IsDetected() throws Exception {
assertThat(getJavaVersion(Function.class), is("1.7"));
}
@Test
public void java6IsDetected() throws Exception {
assertThat(getJavaVersion(Function.class, Files.class), is("1.6"));
}
@Test
public void java6IsTheFallback() throws Exception {
assertThat(getJavaVersion(Function.class, Files.class, ServiceLoader.class),
is("1.6"));
}
private String getJavaVersion(Class<?>... hiddenClasses) throws Exception {
URL[] urls = ((URLClassLoader) getClass().getClassLoader()).getURLs();
URLClassLoader classLoader = new ClassHidingClassLoader(urls, hiddenClasses);
Class<?> javaVersionClass = classLoader
.loadClass(ConditionalOnJava.JavaVersion.class.getName());
Method getJavaVersionMethod = ReflectionUtils.findMethod(javaVersionClass,
"getJavaVersion");
Object javaVersion = ReflectionUtils.invokeMethod(getJavaVersionMethod, null);
classLoader.close();
return javaVersion.toString();
}
private void testBounds(Range range, JavaVersion runningVersion, JavaVersion version,
boolean expected) {
ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion,
@@ -103,6 +148,34 @@ public class ConditionalOnJavaTests {
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher));
}
private final class ClassHidingClassLoader extends URLClassLoader {
private final List<Class<?>> hiddenClasses;
private ClassHidingClassLoader(URL[] urls, Class<?>... hiddenClasses) {
super(urls, null);
this.hiddenClasses = Arrays.asList(hiddenClasses);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (isHidden(name)) {
throw new ClassNotFoundException();
}
return super.loadClass(name);
}
private boolean isHidden(String name) {
for (Class<?> hiddenClass : this.hiddenClasses) {
if (hiddenClass.getName().equals(name)) {
return true;
}
}
return false;
}
}
@Configuration
@ConditionalOnJava(JavaVersion.NINE)
static class Java9Required {