Merge branch '5.3.x'
# Conflicts: # build.gradle # spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java # spring-core/src/main/java/org/springframework/core/ResolvableType.java # spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java # spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/R2dbcTransactionManager.java
This commit is contained in:
commit
dfae4eec2d
|
|
@ -437,7 +437,7 @@ public class ReflectUtils {
|
||||||
return defineClass(className, b, loader, protectionDomain, null);
|
return defineClass(className, b, loader, protectionDomain, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "serial"})
|
||||||
public static Class defineClass(String className, byte[] b, ClassLoader loader,
|
public static Class defineClass(String className, byte[] b, ClassLoader loader,
|
||||||
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
|
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
|
||||||
|
|
||||||
|
|
@ -514,6 +514,16 @@ public class ReflectUtils {
|
||||||
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup());
|
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup());
|
||||||
c = lookup.defineClass(b);
|
c = lookup.defineClass(b);
|
||||||
}
|
}
|
||||||
|
catch (IllegalAccessException ex) {
|
||||||
|
throw new CodeGenerationException(ex) {
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return "ClassLoader mismatch for [" + contextClass.getName() +
|
||||||
|
"]: JVM should be started with --add-opens=java.base/java.lang=ALL-UNNAMED " +
|
||||||
|
"for ClassLoader.defineClass to be accessible on " + loader.getClass().getName();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
throw new CodeGenerationException(ex);
|
throw new CodeGenerationException(ex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -180,26 +180,25 @@ public final class CollectionFactory {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <E> Collection<E> createCollection(Class<?> collectionType, @Nullable Class<?> elementType, int capacity) {
|
public static <E> Collection<E> createCollection(Class<?> collectionType, @Nullable Class<?> elementType, int capacity) {
|
||||||
Assert.notNull(collectionType, "Collection type must not be null");
|
Assert.notNull(collectionType, "Collection type must not be null");
|
||||||
if (collectionType.isInterface()) {
|
if (LinkedHashSet.class == collectionType || HashSet.class == collectionType ||
|
||||||
if (Set.class == collectionType || Collection.class == collectionType) {
|
Set.class == collectionType || Collection.class == collectionType) {
|
||||||
return new LinkedHashSet<>(capacity);
|
return new LinkedHashSet<>(capacity);
|
||||||
}
|
}
|
||||||
else if (List.class == collectionType) {
|
else if (ArrayList.class == collectionType || List.class == collectionType) {
|
||||||
return new ArrayList<>(capacity);
|
return new ArrayList<>(capacity);
|
||||||
}
|
}
|
||||||
else if (SortedSet.class == collectionType || NavigableSet.class == collectionType) {
|
else if (LinkedList.class == collectionType) {
|
||||||
return new TreeSet<>();
|
return new LinkedList<>();
|
||||||
}
|
}
|
||||||
else {
|
else if (SortedSet.class == collectionType || NavigableSet.class == collectionType) {
|
||||||
throw new IllegalArgumentException("Unsupported Collection interface: " + collectionType.getName());
|
return new TreeSet<>();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (EnumSet.class.isAssignableFrom(collectionType)) {
|
else if (EnumSet.class.isAssignableFrom(collectionType)) {
|
||||||
Assert.notNull(elementType, "Cannot create EnumSet for unknown element type");
|
Assert.notNull(elementType, "Cannot create EnumSet for unknown element type");
|
||||||
return EnumSet.noneOf(asEnumType(elementType));
|
return EnumSet.noneOf(asEnumType(elementType));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!Collection.class.isAssignableFrom(collectionType)) {
|
if (collectionType.isInterface() || !Collection.class.isAssignableFrom(collectionType)) {
|
||||||
throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
|
throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -221,9 +221,8 @@ public class ResolvableType implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Return the underlying source of the resolvable type. Will return a {@link Field},
|
* Return the underlying source of the resolvable type. Will return a {@link Field},
|
||||||
* {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType}
|
* {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType}
|
||||||
* was constructed. With the exception of the {@link #NONE} constant, this method will
|
* was constructed. This method is primarily to provide access to additional type
|
||||||
* never return {@code null}. This method is primarily to provide access to additional
|
* information or meta-data that alternative JVM languages may provide.
|
||||||
* type information or meta-data that alternative JVM languages may provide.
|
|
||||||
*/
|
*/
|
||||||
public Object getSource() {
|
public Object getSource() {
|
||||||
Object source = (this.typeProvider != null ? this.typeProvider.getSource() : null);
|
Object source = (this.typeProvider != null ? this.typeProvider.getSource() : null);
|
||||||
|
|
@ -1096,20 +1095,20 @@ public class ResolvableType implements Serializable {
|
||||||
* convey generic information but if it implements {@link ResolvableTypeProvider} a
|
* convey generic information but if it implements {@link ResolvableTypeProvider} a
|
||||||
* more precise {@link ResolvableType} can be used than the simple one based on
|
* more precise {@link ResolvableType} can be used than the simple one based on
|
||||||
* the {@link #forClass(Class) Class instance}.
|
* the {@link #forClass(Class) Class instance}.
|
||||||
* @param instance the instance
|
* @param instance the instance (possibly {@code null})
|
||||||
* @return a {@link ResolvableType} for the specified instance
|
* @return a {@link ResolvableType} for the specified instance,
|
||||||
|
* or {@code NONE} for {@code null}
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
* @see ResolvableTypeProvider
|
* @see ResolvableTypeProvider
|
||||||
*/
|
*/
|
||||||
public static ResolvableType forInstance(Object instance) {
|
public static ResolvableType forInstance(@Nullable Object instance) {
|
||||||
Assert.notNull(instance, "Instance must not be null");
|
|
||||||
if (instance instanceof ResolvableTypeProvider resolvableTypeProvider) {
|
if (instance instanceof ResolvableTypeProvider resolvableTypeProvider) {
|
||||||
ResolvableType type = resolvableTypeProvider.getResolvableType();
|
ResolvableType type = resolvableTypeProvider.getResolvableType();
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResolvableType.forClass(instance.getClass());
|
return (instance != null ? forClass(instance.getClass()) : NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -146,11 +146,9 @@ class ResolvableTypeTests {
|
||||||
assertThat(typeVariable.isAssignableFrom(raw)).isTrue();
|
assertThat(typeVariable.isAssignableFrom(raw)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test // gh-28776
|
||||||
void forInstanceMustNotBeNull() throws Exception {
|
void forInstanceNull() throws Exception {
|
||||||
assertThatIllegalArgumentException()
|
assertThat(ResolvableType.forInstance(null)).isEqualTo(ResolvableType.NONE);
|
||||||
.isThrownBy(() -> ResolvableType.forInstance(null))
|
|
||||||
.withMessage("Instance must not be null");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -26,6 +26,9 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -98,6 +101,9 @@ public abstract class StatementCreatorUtils {
|
||||||
javaTypeToSqlTypeMap.put(double.class, Types.DOUBLE);
|
javaTypeToSqlTypeMap.put(double.class, Types.DOUBLE);
|
||||||
javaTypeToSqlTypeMap.put(Double.class, Types.DOUBLE);
|
javaTypeToSqlTypeMap.put(Double.class, Types.DOUBLE);
|
||||||
javaTypeToSqlTypeMap.put(BigDecimal.class, Types.DECIMAL);
|
javaTypeToSqlTypeMap.put(BigDecimal.class, Types.DECIMAL);
|
||||||
|
javaTypeToSqlTypeMap.put(LocalDate.class, Types.DATE);
|
||||||
|
javaTypeToSqlTypeMap.put(LocalTime.class, Types.TIME);
|
||||||
|
javaTypeToSqlTypeMap.put(LocalDateTime.class, Types.TIMESTAMP);
|
||||||
javaTypeToSqlTypeMap.put(java.sql.Date.class, Types.DATE);
|
javaTypeToSqlTypeMap.put(java.sql.Date.class, Types.DATE);
|
||||||
javaTypeToSqlTypeMap.put(java.sql.Time.class, Types.TIME);
|
javaTypeToSqlTypeMap.put(java.sql.Time.class, Types.TIME);
|
||||||
javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP);
|
javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue