diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java index 12ce1ce86cd..47bf3deed53 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java @@ -33,7 +33,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; /** * Utility methods for AOP proxy factories. @@ -48,11 +47,6 @@ import org.springframework.util.ReflectionUtils; */ public abstract class AopProxyUtils { - // JDK 17 Class.isSealed() method available? - @Nullable - private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed"); - - /** * Obtain the singleton target object behind the given proxy, if any. * @param candidate the (potential) proxy to check @@ -142,7 +136,7 @@ public abstract class AopProxyUtils { List> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3); for (Class ifc : specifiedInterfaces) { // Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17) - if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) { + if (!ifc.isSealed()) { proxiedInterfaces.add(ifc); } } diff --git a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java index 76e3ebf7cba..d6c0aa2a391 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java @@ -260,7 +260,7 @@ public class ReflectUtils { return newInstance(getConstructor(type, parameterTypes), args); } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Object newInstance(final Constructor cstruct, final Object[] args) { boolean flag = cstruct.isAccessible(); try { @@ -439,7 +439,7 @@ public class ReflectUtils { return defineClass(className, b, loader, protectionDomain, null); } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain, Class contextClass) throws Exception { diff --git a/spring-core/src/main/java/org/springframework/cglib/core/package-info.java b/spring-core/src/main/java/org/springframework/cglib/core/package-info.java index a2ed94ff2ea..6d43d8c8bcc 100644 --- a/spring-core/src/main/java/org/springframework/cglib/core/package-info.java +++ b/spring-core/src/main/java/org/springframework/cglib/core/package-info.java @@ -5,6 +5,6 @@ * *

As this repackaging happens at the class file level, sources * and javadocs are not available here... except for a few files - * that have been patched for Spring's purposes on JDK 9/10/11. + * that have been patched for Spring's purposes on JDK 9-17. */ package org.springframework.cglib.core; diff --git a/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java b/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java index 0d651c8f046..9f8cfe268e5 100644 --- a/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java +++ b/spring-core/src/main/java/org/springframework/cglib/proxy/package-info.java @@ -5,6 +5,6 @@ * *

As this repackaging happens at the class file level, sources * and javadocs are not available here... except for a few files - * that have been patched for Spring's purposes on JDK 9/10/11. + * that have been patched for Spring's purposes on JDK 9-17. */ package org.springframework.cglib.proxy; diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index cfeaffcaf73..5010538b6f6 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -16,17 +16,18 @@ package org.springframework.core; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.Flow; import java.util.function.Function; import kotlinx.coroutines.CompletableDeferredKt; import kotlinx.coroutines.Deferred; import org.reactivestreams.Publisher; +import reactor.adapter.JdkFlowAdapter; import reactor.blockhound.BlockHound; import reactor.blockhound.integration.BlockHoundIntegration; import reactor.core.publisher.Flux; @@ -36,7 +37,6 @@ import rx.RxReactiveStreams; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ReflectionUtils; /** * A registry of adapters to adapt Reactive Streams {@link Publisher} to/from @@ -350,28 +350,12 @@ public class ReactiveAdapterRegistry { private static class ReactorJdkFlowAdapterRegistrar { void registerAdapter(ReactiveAdapterRegistry registry) { - // TODO: remove reflection when build requires JDK 9+ - - try { - String publisherName = "java.util.concurrent.Flow.Publisher"; - Class publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader()); - - String adapterName = "reactor.adapter.JdkFlowAdapter"; - Class flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader()); - - Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass); - Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class); - Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty()); - - registry.registerReactiveType( - ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow), - source -> (Publisher) ReflectionUtils.invokeMethod(toFluxMethod, null, source), - publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher) - ); - } - catch (Throwable ex) { - // Ignore - } + Flow.Publisher emptyFlow = JdkFlowAdapter.publisherToFlowPublisher(Flux.empty()); + registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(Flow.Publisher.class, () -> emptyFlow), + source -> JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher) source), + JdkFlowAdapter::publisherToFlowPublisher + ); } } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java index 55a1c077474..0a230ef076c 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/ByteBufferConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-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. @@ -16,7 +16,6 @@ package org.springframework.core.convert.support; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashSet; @@ -122,10 +121,7 @@ final class ByteBufferConverter implements ConditionalGenericConverter { ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); - // Extra cast necessary for compiling on JDK 9 plus running on JDK 8, since - // otherwise the overridden ByteBuffer-returning rewind method would be chosen - // which isn't available on JDK 8. - return ((Buffer) byteBuffer).rewind(); + return byteBuffer.rewind(); } } diff --git a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index be2155f3433..ab6c80a25f4 100644 --- a/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-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. @@ -19,7 +19,6 @@ package org.springframework.core.io.buffer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Arrays; @@ -333,18 +332,14 @@ public class DefaultDataBuffer implements DataBuffer { public DefaultDataBuffer slice(int index, int length) { checkIndex(index, length); int oldPosition = this.byteBuffer.position(); - // Explicit access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = this.byteBuffer; try { - buffer.position(index); + this.byteBuffer.position(index); ByteBuffer slice = this.byteBuffer.slice(); - // Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer slice.limit(length); return new SlicedDefaultDataBuffer(slice, this.dataBufferFactory, length); } finally { - buffer.position(oldPosition); + this.byteBuffer.position(oldPosition); } } @@ -358,11 +353,8 @@ public class DefaultDataBuffer implements DataBuffer { checkIndex(index, length); ByteBuffer duplicate = this.byteBuffer.duplicate(); - // Explicit access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = duplicate; - buffer.position(index); - buffer.limit(index + length); + duplicate.position(index); + duplicate.limit(index + length); return duplicate.slice(); } diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index c9fa24824af..5bee704483a 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -778,7 +778,7 @@ public abstract class ClassUtils { * conflicting method signatures (or a similar constraint is violated) * @see java.lang.reflect.Proxy#getProxyClass */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static Class createCompositeInterface(Class[] interfaces, @Nullable ClassLoader classLoader) { Assert.notEmpty(interfaces, "Interface array must not be empty"); return Proxy.getProxyClass(classLoader, interfaces); diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java index aa4e7931628..e35836f1f5a 100644 --- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java @@ -194,7 +194,7 @@ public abstract class ReflectionUtils { * @param ctor the constructor to make accessible * @see java.lang.reflect.Constructor#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Constructor ctor) { if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) { @@ -563,7 +563,7 @@ public abstract class ReflectionUtils { * @param method the method to make accessible * @see java.lang.reflect.Method#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { @@ -775,7 +775,7 @@ public abstract class ReflectionUtils { * @param field the field to make accessible * @see java.lang.reflect.Field#setAccessible */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index b18710a1bfd..c89286af88d 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -251,7 +251,7 @@ class ObjectUtilsTests { @Deprecated void hashCodeWithDouble() { double dbl = 9830.43; - int expected = (new Double(dbl)).hashCode(); + int expected = Double.valueOf(dbl).hashCode(); assertThat(ObjectUtils.hashCode(dbl)).isEqualTo(expected); } diff --git a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java index c918ee7c2df..c308340714d 100644 --- a/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java +++ b/spring-jcl/src/main/java/org/apache/commons/logging/LogAdapter.java @@ -681,7 +681,7 @@ final class LogAdapter { setSourceMethodName(sourceMethodName); } - @SuppressWarnings("deprecation") // setMillis is deprecated in JDK 9 + @SuppressWarnings("deprecation") protected Object writeReplace() { LogRecord serialized = new LogRecord(getLevel(), getMessage()); serialized.setLoggerName(getLoggerName()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java index d71f78752cc..70b2c0b2e54 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-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. @@ -17,7 +17,6 @@ package org.springframework.messaging.simp.stomp; import java.io.ByteArrayOutputStream; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -134,11 +133,7 @@ public class StompDecoder { private Message decodeMessage(ByteBuffer byteBuffer, @Nullable MultiValueMap headers) { Message decodedMessage = null; skipEol(byteBuffer); - - // Explicit mark/reset access via Buffer base type for compatibility - // with covariant return type on JDK 9's ByteBuffer... - Buffer buffer = byteBuffer; - buffer.mark(); + byteBuffer.mark(); String command = readCommand(byteBuffer); if (command.length() > 0) { @@ -176,7 +171,7 @@ public class StompDecoder { headers.putAll(map); } } - buffer.reset(); + byteBuffer.reset(); } } else { @@ -357,8 +352,7 @@ public class StompDecoder { throw new StompConversionException("'\\r' must be followed by '\\n'"); } } - // Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer - ((Buffer) byteBuffer).position(byteBuffer.position() - 1); + byteBuffer.position(byteBuffer.position() - 1); } return false; } diff --git a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java index f492caf38ca..4803cfada49 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-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. @@ -189,7 +189,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller { * @return the XMLReader * @throws SAXException if thrown by JAXP methods */ - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") protected XMLReader createXmlReader() throws SAXException { XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd()); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java index dac54630394..7ee5253fd8e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/XmlEventDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-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. @@ -122,7 +122,6 @@ public class XmlEventDecoder extends AbstractDecoder { @Override - @SuppressWarnings({"rawtypes", "unchecked", "cast"}) // XMLEventReader is Iterator on JDK 9 public Flux decode(Publisher input, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { @@ -137,7 +136,7 @@ public class XmlEventDecoder extends AbstractDecoder { .flatMapIterable(buffer -> { try { InputStream is = buffer.asInputStream(); - Iterator eventReader = inputFactory.createXMLEventReader(is); + Iterator eventReader = inputFactory.createXMLEventReader(is); List result = new ArrayList<>(); eventReader.forEachRemaining(event -> result.add((XMLEvent) event)); return result; diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java index 63c70e30c64..94d4b0d7511 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-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. @@ -197,7 +197,7 @@ public class SourceHttpMessageConverter extends AbstractHttpMe } } - @SuppressWarnings("deprecation") // on JDK 9 + @SuppressWarnings("deprecation") private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException { try { XMLReader xmlReader = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();