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 12ce1ce86cdc..47bf3deed53c 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.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 @@ */ 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 @@ else if (Proxy.isProxyClass(targetClass)) { 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 76e3ebf7cba0..d6c0aa2a391b 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 static Object newInstance(Class type, Class[] parameterTypes, Object[] ar 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 static Class defineClass(String className, byte[] b, ClassLoader loader, 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 a2ed94ff2ead..6d43d8c8bcc2 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 0d651c8f0464..9f8cfe268e57 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 cfeaffcaf734..5010538b6f67 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 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 @@ void registerAdapters(ReactiveAdapterRegistry registry) { 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 55a1c077474b..0a230ef076c7 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 @@ private Object convertToByteBuffer(@Nullable Object source, TypeDescriptor sourc 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 be2155f34332..ab6c80a25f45 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 @@ 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 @@ private void write(ByteBuffer source) { 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 ByteBuffer asByteBuffer(int index, int length) { 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 c9fa24824afb..5bee704483af 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 static Set> getAllInterfacesForClassAsSet(Class clazz, @Nulla * 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 aa4e79316288..e35836f1f5a8 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 static Constructor accessibleConstructor(Class clazz, Class. * @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 static boolean isCglibRenamedMethod(Method renamedMethod) { * @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 static boolean isPublicStaticFinal(Field field) { * @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 b18710a1bfde..c89286af88d0 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 @@ void hashCodeWithBooleanTrue() { @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 c918ee7c2df0..c308340714d0 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 @@ else if (found) { 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 d71f78752ccb..70b2c0b2e545 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 List> decode(ByteBuffer byteBuffer, 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 @@ private Message decodeMessage(ByteBuffer byteBuffer, @Nullable MultiValu headers.putAll(map); } } - buffer.reset(); + byteBuffer.reset(); } } else { @@ -357,8 +352,7 @@ else if (b == '\r') { 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 f492caf38cab..4803cfada497 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 @@ protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory) * @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 dac546303944..7ee5253fd8e1 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 int getMaxInMemorySize() { @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 Flux decode(Publisher input, ResolvableType element .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 63c70e30c643..94d4b0d75117 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 @@ private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage) } } - @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();