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
pull/4087/head
Andy Wilkinson 9 years ago
parent 6a31c1dda1
commit eae7b0364b

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

@ -16,6 +16,15 @@
package org.springframework.boot.autoconfigure.condition; 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.hamcrest.Matcher;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion; 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.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@ -85,6 +95,41 @@ public class ConditionalOnJavaTests {
+ "older than 1.6 found 1.7")); + "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, private void testBounds(Range range, JavaVersion runningVersion, JavaVersion version,
boolean expected) { boolean expected) {
ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion, ConditionOutcome outcome = this.condition.getMatchOutcome(range, runningVersion,
@ -103,6 +148,34 @@ public class ConditionalOnJavaTests {
assertThat(this.context.getBeansOfType(String.class).values(), is(matcher)); 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 @Configuration
@ConditionalOnJava(JavaVersion.NINE) @ConditionalOnJava(JavaVersion.NINE)
static class Java9Required { static class Java9Required {

Loading…
Cancel
Save