Skip to content

Commit

Permalink
Replace use of deprecated JdkVersion API by looking for presence of c…
Browse files Browse the repository at this point in the history
…lasses

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 spring-projectsgh-4005
  • Loading branch information
wilkinsona committed Oct 2, 2015
1 parent 6a31c1d commit eae7b03
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
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;

/**
Expand All @@ -32,6 +32,7 @@
*
* @author Oliver Gierke
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.1.0
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
Expand Down Expand Up @@ -78,32 +79,35 @@ enum Range {
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 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());
}

/**
Expand Down Expand Up @@ -134,9 +138,8 @@ public String toString() {
* @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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@

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;
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;
Expand Down Expand Up @@ -85,6 +95,41 @@ public void olderThanMessage() throws Exception {
+ "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,
Expand All @@ -103,6 +148,34 @@ private void assertPresent(boolean expected) {
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 {
Expand Down

0 comments on commit eae7b03

Please sign in to comment.