From 75fc8963215ea7289a89b0dc2e48873547d15add Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 19 Jan 2021 14:57:09 +0100 Subject: [PATCH] Avoid Illegal reflective access warnings with devtools This commit improves RestartClassLoader to use a method introduced in SmartClassLoader to avoid triggering a warning on Java 11 and later. See https://github.com/spring-projects/spring-framework/issues/26403 Closes gh-24857 --- .../restart/classloader/RestartClassLoader.java | 8 +++++++- .../restart/classloader/RestartClassLoaderTests.java | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java index 1edc0641f5..3ec58716ae 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; import java.util.Enumeration; import org.apache.commons.logging.Log; @@ -167,6 +168,11 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad }); } + @Override + public Class publicDefineClass(String name, byte[] b, ProtectionDomain protectionDomain) { + return defineClass(name, b, 0, b.length, protectionDomain); + } + private URL createFileUrl(String name, ClassLoaderFile file) { try { return new URL("reloaded", null, -1, "/" + name, new ClassLoaderFileURLStreamHandler(file)); diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoaderTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoaderTests.java index 0613600270..b9fbbc7b32 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoaderTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoaderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; @@ -34,6 +35,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.springframework.aop.framework.ProxyFactory; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind; import org.springframework.util.FileCopyUtils; import org.springframework.util.StreamUtils; @@ -200,6 +202,14 @@ class RestartClassLoaderTests { assertThat(loaded.getClassLoader()).isEqualTo(this.reloadClassLoader); } + @Test + void proxyOnClassFromSystemClassLoaderDoesNotYieldWarning() { + ProxyFactory pf = new ProxyFactory(new HashMap<>()); + pf.setProxyTargetClass(true); + pf.getProxy(this.reloadClassLoader); + // Warning would happen outside the boundary of the test + } + private String readString(InputStream in) throws IOException { return new String(FileCopyUtils.copyToByteArray(in)); }