From 9957bb69183d267f7e1cc784521fdd90193331f8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 9 Nov 2023 10:52:51 +0100 Subject: [PATCH 1/3] Check for procedure vs function constants in CallMetaDataContext Closes gh-31550 --- .../core/metadata/CallMetaDataContext.java | 19 +++-- .../core/metadata/CallParameterMetaData.java | 24 +++++- .../metadata/GenericCallMetaDataProvider.java | 75 ++++++------------- 3 files changed, 56 insertions(+), 62 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java index c9ef473dd5..07650a8904 100755 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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.jdbc.core.metadata; -import java.sql.DatabaseMetaData; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; @@ -115,28 +114,28 @@ public class CallMetaDataContext { } /** - * Specify a limited set of in parameters to be used. + * Specify a limited set of the {@code in} parameters to be used. */ public void setLimitedInParameterNames(Set limitedInParameterNames) { this.limitedInParameterNames = limitedInParameterNames; } /** - * Get a limited set of in parameters to be used. + * Get the limited set of the {@code in} parameters to be used. */ public Set getLimitedInParameterNames() { return this.limitedInParameterNames; } /** - * Specify the names of the out parameters. + * Specify the names of the {@code out} parameters. */ public void setOutParameterNames(List outParameterNames) { this.outParameterNames = outParameterNames; } /** - * Get a list of the out parameter names. + * Get the list of the {@code out} parameter names. */ public List getOutParameterNames() { return this.outParameterNames; @@ -434,14 +433,14 @@ public class CallMetaDataContext { if (paramNameToUse == null) { paramNameToUse = ""; } - if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) { + if (meta.isOutParameter()) { workParams.add(provider.createDefaultOutParameter(paramNameToUse, meta)); outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { logger.debug("Added meta-data out parameter for '" + paramNameToUse + "'"); } } - else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) { + else if (meta.isInOutParameter()) { workParams.add(provider.createDefaultInOutParameter(paramNameToUse, meta)); outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { @@ -554,7 +553,7 @@ public class CallMetaDataContext { Map callParameterNames = CollectionUtils.newHashMap(this.callParameters.size()); for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { - String parameterName = parameter.getName(); + String parameterName = parameter.getName(); String parameterNameToMatch = provider.parameterNameToUse(parameterName); if (parameterNameToMatch != null) { callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName); @@ -606,7 +605,7 @@ public class CallMetaDataContext { int i = 0; for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { - String parameterName = parameter.getName(); + String parameterName = parameter.getName(); matchedParameters.put(parameterName, parameterValues[i++]); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java index edce0df036..2b7a61c069 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 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. @@ -97,6 +97,28 @@ public class CallParameterMetaData { this.parameterType == DatabaseMetaData.procedureColumnResult)); } + /** + * Determine whether the declared parameter qualifies as an 'out' parameter + * for our purposes: type {@link DatabaseMetaData#procedureColumnOut}, + * or in case of a function, {@link DatabaseMetaData#functionColumnOut}. + * @since 5.3.31 + */ + public boolean isOutParameter() { + return (this.function ? this.parameterType == DatabaseMetaData.functionColumnOut : + this.parameterType == DatabaseMetaData.procedureColumnOut); + } + + /** + * Determine whether the declared parameter qualifies as an 'in-out' parameter + * for our purposes: type {@link DatabaseMetaData#procedureColumnInOut}, + * or in case of a function, {@link DatabaseMetaData#functionColumnInOut}. + * @since 5.3.31 + */ + public boolean isInOutParameter() { + return (this.function ? this.parameterType == DatabaseMetaData.functionColumnInOut : + this.parameterType == DatabaseMetaData.procedureColumnInOut); + } + /** * Return the parameter SQL type. */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java index 8a9b2d0a3f..3822fae85b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 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. @@ -35,7 +35,8 @@ import org.springframework.util.StringUtils; /** * A generic implementation of the {@link CallMetaDataProvider} interface. - * This class can be extended to provide database specific behavior. + * + *

This class can be extended to provide database specific behavior. * * @author Thomas Risberg * @author Juergen Hoeller @@ -113,7 +114,7 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { @Nullable String schemaName, @Nullable String procedureName) throws SQLException { this.procedureColumnMetaDataUsed = true; - processProcedureColumns(databaseMetaData, catalogName, schemaName, procedureName); + processProcedureColumns(databaseMetaData, catalogName, schemaName, procedureName); } @Override @@ -124,52 +125,19 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { @Override @Nullable public String procedureNameToUse(@Nullable String procedureName) { - if (procedureName == null) { - return null; - } - else if (isStoresUpperCaseIdentifiers()) { - return procedureName.toUpperCase(); - } - else if (isStoresLowerCaseIdentifiers()) { - return procedureName.toLowerCase(); - } - else { - return procedureName; - } + return identifierNameToUse(procedureName); } @Override @Nullable public String catalogNameToUse(@Nullable String catalogName) { - if (catalogName == null) { - return null; - } - else if (isStoresUpperCaseIdentifiers()) { - return catalogName.toUpperCase(); - } - else if (isStoresLowerCaseIdentifiers()) { - return catalogName.toLowerCase(); - } - else { - return catalogName; - } + return identifierNameToUse(catalogName); } @Override @Nullable public String schemaNameToUse(@Nullable String schemaName) { - if (schemaName == null) { - return null; - } - else if (isStoresUpperCaseIdentifiers()) { - return schemaName.toUpperCase(); - } - else if (isStoresLowerCaseIdentifiers()) { - return schemaName.toLowerCase(); - } - else { - return schemaName; - } + return identifierNameToUse(schemaName); } @Override @@ -197,18 +165,7 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { @Override @Nullable public String parameterNameToUse(@Nullable String parameterName) { - if (parameterName == null) { - return null; - } - else if (isStoresUpperCaseIdentifiers()) { - return parameterName.toUpperCase(); - } - else if (isStoresLowerCaseIdentifiers()) { - return parameterName.toLowerCase(); - } - else { - return parameterName; - } + return identifierNameToUse(parameterName); } @Override @@ -316,6 +273,22 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { } + @Nullable + private String identifierNameToUse(@Nullable String identifierName) { + if (identifierName == null) { + return null; + } + else if (isStoresUpperCaseIdentifiers()) { + return identifierName.toUpperCase(); + } + else if (isStoresLowerCaseIdentifiers()) { + return identifierName.toLowerCase(); + } + else { + return identifierName; + } + } + /** * Process the procedure column meta-data. */ From 11fdb5ba178478e889efa7708e5ee609f8ae4c5f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 9 Nov 2023 10:53:47 +0100 Subject: [PATCH 2/3] Upgrade to Log4J 2.21.1, Tomcat 10.1.15, Jetty 11.0.18, Undertow 2.3.10, EclipseLink 3.0.4, Mockito 5.7 --- framework-platform/framework-platform.gradle | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index 6561c5718a..db94db5b65 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -14,12 +14,12 @@ dependencies { api(platform("io.projectreactor:reactor-bom:2022.0.12")) api(platform("io.rsocket:rsocket-bom:1.1.3")) api(platform("org.apache.groovy:groovy-bom:4.0.15")) - api(platform("org.apache.logging.log4j:log4j-bom:2.20.0")) - api(platform("org.eclipse.jetty:jetty-bom:11.0.17")) + api(platform("org.apache.logging.log4j:log4j-bom:2.21.1")) + api(platform("org.eclipse.jetty:jetty-bom:11.0.18")) api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4")) api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.4.0")) api(platform("org.junit:junit-bom:5.9.3")) - api(platform("org.mockito:mockito-bom:5.6.0")) + api(platform("org.mockito:mockito-bom:5.7.0")) constraints { api("com.fasterxml:aalto-xml:1.3.2") @@ -54,9 +54,9 @@ dependencies { api("io.r2dbc:r2dbc-spi:1.0.0.RELEASE") api("io.reactivex.rxjava3:rxjava:3.1.6") api("io.smallrye.reactive:mutiny:1.9.0") - api("io.undertow:undertow-core:2.3.8.Final") - api("io.undertow:undertow-servlet:2.3.8.Final") - api("io.undertow:undertow-websockets-jsr:2.3.8.Final") + api("io.undertow:undertow-core:2.3.10.Final") + api("io.undertow:undertow-servlet:2.3.10.Final") + api("io.undertow:undertow-websockets-jsr:2.3.10.Final") api("io.vavr:vavr:0.10.4") api("jakarta.activation:jakarta.activation-api:2.0.1") api("jakarta.annotation:jakarta.annotation-api:2.0.0") @@ -99,10 +99,10 @@ dependencies { api("org.apache.httpcomponents.client5:httpclient5:5.2.1") api("org.apache.httpcomponents.core5:httpcore5-reactive:5.2.2") api("org.apache.poi:poi-ooxml:5.2.3") - api("org.apache.tomcat.embed:tomcat-embed-core:10.1.14") - api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.14") - api("org.apache.tomcat:tomcat-util:10.1.14") - api("org.apache.tomcat:tomcat-websocket:10.1.14") + api("org.apache.tomcat.embed:tomcat-embed-core:10.1.15") + api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.15") + api("org.apache.tomcat:tomcat-util:10.1.15") + api("org.apache.tomcat:tomcat-websocket:10.1.15") api("org.aspectj:aspectjrt:1.9.20.1") api("org.aspectj:aspectjtools:1.9.20.1") api("org.aspectj:aspectjweaver:1.9.20.1") @@ -111,8 +111,8 @@ dependencies { api("org.bouncycastle:bcpkix-jdk18on:1.72") api("org.codehaus.jettison:jettison:1.5.4") api("org.dom4j:dom4j:2.1.4") - api("org.eclipse.jetty:jetty-reactive-httpclient:3.0.8") - api("org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.3") + api("org.eclipse.jetty:jetty-reactive-httpclient:3.0.10") + api("org.eclipse.persistence:org.eclipse.persistence.jpa:3.0.4") api("org.eclipse:yasson:2.0.4") api("org.ehcache:ehcache:3.10.8") api("org.ehcache:jcache:1.0.1") From 1e78cc35e596a6927a6ae25418c5f043ee8c40aa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 9 Nov 2023 11:46:22 +0100 Subject: [PATCH 3/3] Log4jLog re-resolves ExtendedLogger on deserialization This is necessary for compatibility with Log4J 2.21, analogous to the existing re-resolution in Spring's SLF4J adapter. Closes gh-31582 --- .../main/java/org/apache/commons/logging/LogAdapter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 49b47054db..021295d2dc 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 @@ -145,9 +145,12 @@ final class LogAdapter { private static final LoggerContext loggerContext = LogManager.getContext(Log4jLog.class.getClassLoader(), false); - private final ExtendedLogger logger; + private final String name; + + private final transient ExtendedLogger logger; public Log4jLog(String name) { + this.name = name; LoggerContext context = loggerContext; if (context == null) { // Circular call in early-init scenario -> static field not initialized yet @@ -261,6 +264,10 @@ final class LogAdapter { this.logger.logIfEnabled(FQCN, level, null, message, exception); } } + + protected Object readResolve() { + return new Log4jLog(this.name); + } }