This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch 2.x-site-pro
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x-site-pro by this push:
new da4420763e fix: synchronize with `2.x`
da4420763e is described below
commit da4420763ee276c8da2f1d31d3a451063702c5d8
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Mon Jun 16 21:54:41 2025 +0200
fix: synchronize with `2.x`
---
.../map/UnmodifiableArrayBackedMapTest.java | 19 --
.../apache/logging/log4j/message/package-info.java | 2 +-
.../apache/logging/log4j/spi/AbstractLogger.java | 4 +
.../apache/logging/log4j/spi/LoggerContext.java | 7 +-
.../org/apache/logging/log4j/spi/package-info.java | 2 +-
.../log4j/core/appender/AbstractAppender.java | 6 +-
.../core/appender/HttpURLConnectionManager.java | 3 +-
.../log4j/core/config/AbstractConfiguration.java | 15 +-
.../log4j/core/config/ConfigurationSource.java | 9 +-
.../apache/logging/log4j/core/net/SmtpManager.java | 3 +-
.../logging/log4j/core/net/SslSocketManager.java | 62 +++++-
.../log4j/core/net/UrlConnectionFactory.java | 3 +-
.../net/ssl/AbstractKeyStoreConfiguration.java | 9 +-
.../log4j/core/net/ssl/KeyStoreConfiguration.java | 6 +-
.../log4j/core/net/ssl/PasswordProvider.java | 1 +
.../log4j/core/net/ssl/SslConfiguration.java | 240 ++++++++-------------
.../core/net/ssl/SslConfigurationFactory.java | 3 +-
.../log4j/core/net/ssl/StoreConfiguration.java | 2 +-
.../core/net/ssl/TrustStoreConfiguration.java | 6 +-
.../logging/log4j/core/net/ssl/package-info.java | 2 +-
.../apache/logging/log4j/core/package-info.java | 2 +-
.../org/apache/logging/log4j/core/util/Loader.java | 5 +-
.../org/apache/logging/log4j/core/util/Source.java | 45 ++--
.../log4j/core/util/datetime/FastDatePrinter.java | 2 +-
.../org/apache/logging/log4j/smtp/SmtpManager.java | 3 +-
.../log4j/taglib/Log4jTaglibLoggerContext.java | 7 +-
.../apache/logging/log4j/taglib/package-info.java | 2 +-
.../logging/log4j/tojul/JULLoggerContext.java | 7 +-
.../apache/logging/log4j/tojul/package-info.java | 2 +-
.../apache/logging/slf4j/SLF4JLoggerContext.java | 7 +-
.../org/apache/logging/slf4j/package-info.java | 2 +-
31 files changed, 255 insertions(+), 233 deletions(-)
diff --git
a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/map/UnmodifiableArrayBackedMapTest.java
b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/map/UnmodifiableArrayBackedMapTest.java
index 48befed7f9..612840bbf5 100644
---
a/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/map/UnmodifiableArrayBackedMapTest.java
+++
b/log4j-api-test/src/test/java/org/apache/logging/log4j/internal/map/UnmodifiableArrayBackedMapTest.java
@@ -394,23 +394,4 @@ class UnmodifiableArrayBackedMapTest {
actualMap = actualMap.copyAndRemoveAll(Collections.singleton("inner"));
Assertions.assertThat(actualMap).isEqualTo(expectedMap);
}
-
- @Test
- void copyAndRemoveAll_should_work() {
-
- // Create the actual map
- UnmodifiableArrayBackedMap actualMap =
UnmodifiableArrayBackedMap.EMPTY_MAP;
- actualMap = actualMap.copyAndPut("outer", "two");
- actualMap = actualMap.copyAndPut("inner", "one");
- actualMap = actualMap.copyAndPut("not-in-closeable", "true");
-
- // Create the expected map
- UnmodifiableArrayBackedMap expectedMap =
UnmodifiableArrayBackedMap.EMPTY_MAP;
- expectedMap = expectedMap.copyAndPut("outer", "two");
- expectedMap = expectedMap.copyAndPut("not-in-closeable", "true");
-
- // Remove the key and verify
- actualMap = actualMap.copyAndRemoveAll(Collections.singleton("inner"));
- Assertions.assertThat(actualMap).isEqualTo(expectedMap);
- }
}
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
b/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
index dae91264f4..fbec2d82f4 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
@@ -19,7 +19,7 @@
* Public Message Types used for Log4j 2. Users may implement their own
Messages.
*/
@Export
-@Version("2.24.1")
+@Version("2.24.2")
package org.apache.logging.log4j.message;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
index 1ec0a84937..ebe5e5c668 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
@@ -168,7 +168,11 @@ public abstract class AbstractLogger implements
ExtendedLogger, LocationAwareLog
*
* @param logger The logger to check
* @param messageFactory The message factory to check.
+ * @deprecated As of version {@code 2.25.0}, planned to be removed!
+ * Instead, in {@link LoggerContext#getLogger(String, MessageFactory)}
implementations, namespace loggers with message factories.
+ * If your implementation uses {@link LoggerRegistry}, you are already
covered.
*/
+ @Deprecated
public static void checkMessageFactory(final ExtendedLogger logger, final
MessageFactory messageFactory) {
final String name = logger.getName();
final MessageFactory loggerMessageFactory = logger.getMessageFactory();
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
index 2b6f932d35..d5a9119a1e 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.spi;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.MessageFactory;
+import org.jspecify.annotations.Nullable;
/**
* Anchor point for logging implementations.
@@ -55,7 +56,7 @@ public interface LoggerContext {
* @return The logger.
* @since 2.14.0
*/
- default ExtendedLogger getLogger(Class<?> cls, MessageFactory
messageFactory) {
+ default ExtendedLogger getLogger(Class<?> cls, @Nullable MessageFactory
messageFactory) {
final String canonicalName = cls.getCanonicalName();
return getLogger(canonicalName != null ? canonicalName :
cls.getName(), messageFactory);
}
@@ -74,7 +75,7 @@ public interface LoggerContext {
* the logger but will log a warning if mismatched.
* @return The logger with the specified name.
*/
- ExtendedLogger getLogger(String name, MessageFactory messageFactory);
+ ExtendedLogger getLogger(String name, @Nullable MessageFactory
messageFactory);
/**
* Gets the LoggerRegistry.
@@ -119,7 +120,7 @@ public interface LoggerContext {
* @return true if the Logger exists, false otherwise.
* @since 2.5
*/
- boolean hasLogger(String name, MessageFactory messageFactory);
+ boolean hasLogger(String name, @Nullable MessageFactory messageFactory);
/**
* Associates an object into the LoggerContext by name for later use.
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
index 1637d7a3d1..3b6b5c2585 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
@@ -19,7 +19,7 @@
* API classes.
*/
@Export
-@Version("2.24.2")
+@Version("2.25.0")
package org.apache.logging.log4j.spi;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index 83ed7d48f8..beaf5134a0 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -172,7 +172,7 @@ public abstract class AbstractAppender extends
AbstractFilterable implements App
private final boolean ignoreExceptions;
private final Layout<? extends Serializable> layout;
- private ErrorHandler handler = new DefaultErrorHandler(this);
+ private volatile ErrorHandler handler = new DefaultErrorHandler(this);
@Override
public boolean requiresLocation() {
@@ -316,10 +316,6 @@ public abstract class AbstractAppender extends
AbstractFilterable implements App
LOGGER.error("The handler cannot be set to null");
return;
}
- if (isStarted()) {
- LOGGER.error("The handler cannot be changed once the appender is
started");
- return;
- }
this.handler = handler;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
index 38c9c52b2e..a4e9858431 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
@@ -100,7 +100,8 @@ public class HttpURLConnectionManager extends HttpManager {
header.getName(),
header.evaluate(getConfiguration().getStrSubstitutor()));
}
if (sslConfiguration != null) {
- ((HttpsURLConnection)
urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ ((HttpsURLConnection) urlConnection)
+
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
}
if (isHttps && !verifyHostname) {
((HttpsURLConnection)
urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 0f2eebcb70..4c3dde9179 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -17,9 +17,11 @@
package org.apache.logging.log4j.core.config;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -279,9 +281,10 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
if (configSource != null && (configSource.getFile() != null ||
configSource.getURL() != null)) {
if (monitorIntervalSeconds > 0) {
watchManager.setIntervalSeconds(monitorIntervalSeconds);
- if (configSource.getFile() != null) {
- final Source cfgSource = new Source(configSource);
- final long lastModified =
configSource.getFile().lastModified();
+ File file = configSource.getFile();
+ if (file != null) {
+ final Source cfgSource = new Source(file);
+ final long lastModified = file.lastModified();
final ConfigurationFileWatcher watcher =
new ConfigurationFileWatcher(this, reconfigurable,
listeners, lastModified);
watchManager.watch(cfgSource, watcher);
@@ -297,8 +300,10 @@ public abstract class AbstractConfiguration extends
AbstractFilterable implement
}
private void monitorSource(final Reconfigurable reconfigurable, final
ConfigurationSource configSource) {
- if (configSource.getLastModified() > 0) {
- final Source cfgSource = new Source(configSource);
+ URI uri = configSource.getURI();
+ if (uri != null && configSource.getLastModified() > 0) {
+ File file = configSource.getFile();
+ final Source cfgSource = file != null ? new Source(file) : new
Source(uri);
final Watcher watcher = WatcherFactory.getInstance(pluginPackages)
.newWatcher(cfgSource, this, reconfigurable, listeners,
configSource.getLastModified());
if (watcher != null) {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
index ff443b08f3..d6143cdc15 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
@@ -142,7 +142,7 @@ public class ConfigurationSource {
* @param stream the input stream, the caller is responsible for closing
this resource.
* @throws IOException if an exception occurred reading from the specified
stream
*/
- public ConfigurationSource(final InputStream stream) throws IOException {
+ public ConfigurationSource(InputStream stream) throws IOException {
this(toByteArray(stream), null, 0);
}
@@ -298,12 +298,13 @@ public class ConfigurationSource {
@Override
public String toString() {
- if (isLocation()) {
- return getLocation();
+ if (source != null) {
+ return source.getLocation();
}
if (this == NULL_SOURCE) {
return "NULL_SOURCE";
}
+ byte[] data = this.data;
final int length = data == null ? -1 : data.length;
return "stream (" + length + " bytes, unknown location)";
}
@@ -311,7 +312,7 @@ public class ConfigurationSource {
/**
* Loads the configuration from a URI.
* @param configLocation A URI representing the location of the
configuration.
- * @return The ConfigurationSource for the configuration.
+ * @return The ConfigurationSource for the configuration or {@code null}.
*/
public static /*@Nullable*/ ConfigurationSource fromUri(final URI
configLocation) {
final File configFile = FileUtils.fileFromUri(configLocation);
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
index 9c362ed045..f129b80fe4 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
@@ -308,7 +308,8 @@ public class SmtpManager extends MailManager {
if (smtpProtocol.equals("smtps")) {
final SslConfiguration sslConfiguration =
data.getSslConfiguration();
if (sslConfiguration != null) {
- final SSLSocketFactory sslSocketFactory =
sslConfiguration.getSslSocketFactory();
+ final SSLSocketFactory sslSocketFactory =
+
sslConfiguration.getSslContext().getSocketFactory();
properties.put(prefix + ".ssl.socketFactory",
sslSocketFactory);
properties.setProperty(
prefix + ".ssl.checkserveridentity",
Boolean.toString(sslConfiguration.isVerifyHostName()));
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
index 8326f3ceeb..4f28e57502 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
@@ -22,7 +22,13 @@ import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.security.KeyStoreException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.apache.logging.log4j.core.Layout;
@@ -197,6 +203,8 @@ public class SslSocketManager extends TcpSocketManager {
final Layout<? extends Serializable> layout,
final int bufferSize,
final SocketOptions socketOptions) {
+
+ // Check arguments
if (Strings.isEmpty(host)) {
throw new IllegalArgumentException("A host name is required");
}
@@ -206,7 +214,14 @@ public class SslSocketManager extends TcpSocketManager {
if (reconnectDelayMillis == 0) {
reconnectDelayMillis = DEFAULT_RECONNECTION_DELAY_MILLIS;
}
- final String name = "TLS:" + host + ':' + port;
+
+ // Create an ID associated with the SSL configuration. This is
necessary to make sure a new `name` is generated
+ // (and consequently a new connection pool is created) upon
reconfiguration with a different configuration;
+ // e.g., change in the SSL certificate content, even though the
certificate file locations are still the same.
+ // See #2767 and LOG4J2-2988 for details.
+ final String sslConfigId = createSslConfigurationId(sslConfig);
+ final String name = String.format("%s:%s:%d:%s",
sslConfig.getProtocol(), host, port, sslConfigId);
+
return (SslSocketManager) getManager(
name,
new SslFactoryData(
@@ -222,6 +237,49 @@ public class SslSocketManager extends TcpSocketManager {
FACTORY);
}
+ /**
+ * Creates a unique identifier using the certificate issuers and serial
numbers of the given SSL configuration.
+ *
+ * @param sslConfig an SSL configuration
+ * @return a unique identifier extracted from the given SSL configuration
+ */
+ private static String createSslConfigurationId(final SslConfiguration
sslConfig) {
+ return String.valueOf(Stream.of(sslConfig.getKeyStoreConfig(),
sslConfig.getTrustStoreConfig())
+ .flatMap(keyStoreConfig -> {
+ final Enumeration<String> aliases;
+ try {
+ aliases = keyStoreConfig.getKeyStore().aliases();
+ } catch (final KeyStoreException error) {
+ LOGGER.error(
+ "Failed reading the aliases for the key store
located at `{}`",
+ keyStoreConfig.getLocation(),
+ error);
+ return Stream.empty();
+ }
+ return
Collections.list(aliases).stream().sorted().flatMap(alias -> {
+ final X509Certificate certificate;
+ try {
+ certificate = (X509Certificate)
+
keyStoreConfig.getKeyStore().getCertificate(alias);
+ } catch (final KeyStoreException error) {
+ LOGGER.error(
+ "Failed reading the certificate of alias
`{}` for the key store located at `{}`",
+ alias,
+ keyStoreConfig.getLocation(),
+ error);
+ return Stream.empty();
+ }
+ final String issuer =
+ certificate.getIssuerX500Principal().getName();
+ final String serialNumber =
+ certificate.getSerialNumber().toString();
+ return Stream.of(issuer, serialNumber);
+ });
+ })
+ .collect(Collectors.toList())
+ .hashCode());
+ }
+
@Override
protected Socket createSocket(final InetSocketAddress socketAddress)
throws IOException {
final SSLSocketFactory socketFactory =
createSslSocketFactory(sslConfig);
@@ -234,7 +292,7 @@ public class SslSocketManager extends TcpSocketManager {
SSLSocketFactory socketFactory;
if (sslConf != null) {
- socketFactory = sslConf.getSslSocketFactory();
+ socketFactory = sslConf.getSslContext().getSocketFactory();
} else {
socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
index 7c5416210e..e6ba2a1366 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
@@ -102,7 +102,8 @@ public class UrlConnectionFactory {
httpURLConnection.setIfModifiedSince(lastModifiedMillis);
}
if (url.getProtocol().equals(HTTPS) && sslConfiguration != null) {
- ((HttpsURLConnection)
httpURLConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ ((HttpsURLConnection) httpURLConnection)
+
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
if (!sslConfiguration.isVerifyHostName()) {
((HttpsURLConnection)
httpURLConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
index ad928482d9..a70b71edd3 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
@@ -33,9 +33,10 @@ import org.apache.logging.log4j.core.util.NetUtils;
*/
public class AbstractKeyStoreConfiguration extends
StoreConfiguration<KeyStore> {
- private final KeyStore keyStore;
private final String keyStoreType;
+ private final transient KeyStore keyStore;
+
public AbstractKeyStoreConfiguration(
final String location, final PasswordProvider passwordProvider,
final String keyStoreType)
throws StoreConfigurationException {
@@ -114,7 +115,7 @@ public class AbstractKeyStoreConfiguration extends
StoreConfiguration<KeyStore>
}
}
- private InputStream openInputStream(final String filePathOrUri) {
+ private static InputStream openInputStream(final String filePathOrUri) {
return
ConfigurationSource.fromUri(NetUtils.toURI(filePathOrUri)).getInputStream();
}
@@ -126,7 +127,6 @@ public class AbstractKeyStoreConfiguration extends
StoreConfiguration<KeyStore>
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
- result = prime * result + ((keyStore == null) ? 0 :
keyStore.hashCode());
result = prime * result + ((keyStoreType == null) ? 0 :
keyStoreType.hashCode());
return result;
}
@@ -143,9 +143,6 @@ public class AbstractKeyStoreConfiguration extends
StoreConfiguration<KeyStore>
return false;
}
final AbstractKeyStoreConfiguration other =
(AbstractKeyStoreConfiguration) obj;
- if (!Objects.equals(keyStore, other.keyStore)) {
- return false;
- }
if (!Objects.equals(keyStoreType, other.keyStoreType)) {
return false;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
index 6e23d5bb40..205f7b0d9d 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
@@ -161,7 +161,7 @@ public class KeyStoreConfiguration extends
AbstractKeyStoreConfiguration {
* Extension Reference Guide for information about these names.
* @return a new KeyStoreConfiguration
* @throws StoreConfigurationException Thrown if this call cannot load the
KeyStore.
- * @deprecated Use createKeyStoreConfiguration(String, char[], String,
String)
+ * @deprecated Use {@link #createKeyStoreConfiguration(String, char[],
String, String, String, String)}
*/
@Deprecated
public static KeyStoreConfiguration createKeyStoreConfiguration(
@@ -176,6 +176,10 @@ public class KeyStoreConfiguration extends
AbstractKeyStoreConfiguration {
location, (password == null ? null : password.toCharArray()),
keyStoreType, keyManagerFactoryAlgorithm);
}
+ /**
+ * @deprecated Planned to be removed in the next major release
+ */
+ @Deprecated
public KeyManagerFactory initKeyManagerFactory()
throws NoSuchAlgorithmException, UnrecoverableKeyException,
KeyStoreException {
final KeyManagerFactory kmFactory =
KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm);
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
index ca61176a30..ec37de3b9e 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
@@ -26,6 +26,7 @@ package org.apache.logging.log4j.core.net.ssl;
* is no longer needed.
* </p>
*/
+@FunctionalInterface
public interface PasswordProvider {
/**
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
index 68ee689b9e..cb24113bd9 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
@@ -16,10 +16,7 @@
*/
package org.apache.logging.log4j.core.net.ssl;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
import java.util.Objects;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
@@ -34,29 +31,42 @@ import
org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.status.StatusLogger;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.NullUnmarked;
+import org.jspecify.annotations.Nullable;
/**
* SSL Configuration
*/
+@NullMarked
@Plugin(name = "Ssl", category = Core.CATEGORY_NAME, printObject = true)
public class SslConfiguration {
+
private static final StatusLogger LOGGER = StatusLogger.getLogger();
- private final KeyStoreConfiguration keyStoreConfig;
- private final TrustStoreConfiguration trustStoreConfig;
- private final SSLContext sslContext;
+
private final String protocol;
+
private final boolean verifyHostName;
+ @Nullable
+ private final KeyStoreConfiguration keyStoreConfig;
+
+ @Nullable
+ private final TrustStoreConfiguration trustStoreConfig;
+
+ private final transient SSLContext sslContext;
+
private SslConfiguration(
- final String protocol,
- final KeyStoreConfiguration keyStoreConfig,
- final TrustStoreConfiguration trustStoreConfig,
- final boolean verifyHostName) {
+ @Nullable final String protocol,
+ final boolean verifyHostName,
+ @Nullable final KeyStoreConfiguration keyStoreConfig,
+ @Nullable final TrustStoreConfiguration trustStoreConfig) {
this.keyStoreConfig = keyStoreConfig;
this.trustStoreConfig = trustStoreConfig;
- this.protocol = protocol == null ? SslConfigurationDefaults.PROTOCOL :
protocol;
- this.sslContext = this.createSslContext();
+ final String effectiveProtocol = protocol == null ?
SslConfigurationDefaults.PROTOCOL : protocol;
+ this.protocol = effectiveProtocol;
this.verifyHostName = verifyHostName;
+ this.sslContext = createSslContext(effectiveProtocol, keyStoreConfig,
trustStoreConfig);
}
/**
@@ -71,157 +81,96 @@ public class SslConfiguration {
}
}
+ /**
+ * Gets the SSL socket factory of the configured SSL context.
+ *
+ * @return the SSL socket factory of the configured SSL context
+ * @deprecated Use {@link SSLContext#getSocketFactory()} on {@link
#getSslContext()}
+ */
+ @Deprecated
public SSLSocketFactory getSslSocketFactory() {
return sslContext.getSocketFactory();
}
+ /**
+ * Gets the SSL server socket factory of the configured SSL context.
+ *
+ * @return the SSL server socket factory of the configured SSL context
+ * @deprecated Use {@link SSLContext#getServerSocketFactory()} on {@link
#getSslContext()}
+ */
+ @Deprecated
public SSLServerSocketFactory getSslServerSocketFactory() {
return sslContext.getServerSocketFactory();
}
- private SSLContext createSslContext() {
- SSLContext context = null;
-
- try {
- context = createSslContextBasedOnConfiguration();
- LOGGER.debug("Creating SSLContext with the given parameters");
- } catch (final TrustStoreConfigurationException e) {
- context = createSslContextWithTrustStoreFailure();
- } catch (final KeyStoreConfigurationException e) {
- context = createSslContextWithKeyStoreFailure();
- }
- return context;
- }
-
- private SSLContext createSslContextWithTrustStoreFailure() {
- SSLContext context;
-
- try {
- context = createSslContextWithDefaultTrustManagerFactory();
- LOGGER.debug("Creating SSLContext with default truststore");
- } catch (final KeyStoreConfigurationException e) {
- context = createDefaultSslContext();
- LOGGER.debug("Creating SSLContext with default configuration");
- }
- return context;
- }
-
- private SSLContext createSslContextWithKeyStoreFailure() {
- SSLContext context;
-
- try {
- context = createSslContextWithDefaultKeyManagerFactory();
- LOGGER.debug("Creating SSLContext with default keystore");
- } catch (final TrustStoreConfigurationException e) {
- context = createDefaultSslContext();
- LOGGER.debug("Creating SSLContext with default configuration");
- }
- return context;
- }
-
- private SSLContext createSslContextBasedOnConfiguration()
- throws KeyStoreConfigurationException,
TrustStoreConfigurationException {
- return createSslContext(false, false);
- }
-
- private SSLContext createSslContextWithDefaultKeyManagerFactory() throws
TrustStoreConfigurationException {
- try {
- return createSslContext(true, false);
- } catch (final KeyStoreConfigurationException dummy) {
- LOGGER.debug("Exception occurred while using default keystore.
This should be a BUG");
- return null;
- }
- }
-
- private SSLContext createSslContextWithDefaultTrustManagerFactory() throws
KeyStoreConfigurationException {
- try {
- return createSslContext(false, true);
- } catch (final TrustStoreConfigurationException dummy) {
- LOGGER.debug("Exception occurred while using default truststore.
This should be a BUG");
- return null;
- }
- }
-
- private SSLContext createDefaultSslContext() {
+ private static SSLContext createDefaultSslContext(final String protocol) {
try {
return SSLContext.getDefault();
- } catch (final NoSuchAlgorithmException e) {
- LOGGER.error("Failed to create an SSLContext with default
configuration", e);
- return null;
+ } catch (final NoSuchAlgorithmException defaultContextError) {
+ LOGGER.error(
+ "Failed to create an `SSLContext` using the default
configuration, falling back to creating an empty one",
+ defaultContextError);
+ try {
+ final SSLContext emptyContext =
SSLContext.getInstance(protocol);
+ emptyContext.init(new KeyManager[0], new TrustManager[0],
null);
+ return emptyContext;
+ } catch (final Exception emptyContextError) {
+ LOGGER.error("Failed to create an empty `SSLContext`",
emptyContextError);
+ return null;
+ }
}
}
- private SSLContext createSslContext(
- final boolean loadDefaultKeyManagerFactory, final boolean
loadDefaultTrustManagerFactory)
- throws KeyStoreConfigurationException,
TrustStoreConfigurationException {
+ private static SSLContext createSslContext(
+ final String protocol,
+ @Nullable final KeyStoreConfiguration keyStoreConfig,
+ @Nullable final TrustStoreConfiguration trustStoreConfig) {
try {
- KeyManager[] kManagers = null;
- TrustManager[] tManagers = null;
-
- final SSLContext newSslContext =
SSLContext.getInstance(this.protocol);
- if (!loadDefaultKeyManagerFactory) {
- final KeyManagerFactory kmFactory = loadKeyManagerFactory();
- kManagers = kmFactory.getKeyManagers();
- }
- if (!loadDefaultTrustManagerFactory) {
- final TrustManagerFactory tmFactory =
loadTrustManagerFactory();
- tManagers = tmFactory.getTrustManagers();
- }
-
- newSslContext.init(kManagers, tManagers, null);
- return newSslContext;
- } catch (final NoSuchAlgorithmException e) {
- LOGGER.error("No Provider supports a TrustManagerFactorySpi
implementation for the specified protocol", e);
- throw new TrustStoreConfigurationException(e);
- } catch (final KeyManagementException e) {
- LOGGER.error("Failed to initialize the SSLContext", e);
- throw new KeyStoreConfigurationException(e);
+ final SSLContext sslContext = SSLContext.getInstance(protocol);
+ final KeyManager[] keyManagers = loadKeyManagers(keyStoreConfig);
+ final TrustManager[] trustManagers =
loadTrustManagers(trustStoreConfig);
+ sslContext.init(keyManagers, trustManagers, null);
+ return sslContext;
+ } catch (final Exception error) {
+ LOGGER.error(
+ "Failed to create an `SSLContext` using the provided
configuration, falling back to a default instance",
+ error);
+ return createDefaultSslContext(protocol);
}
}
- private TrustManagerFactory loadTrustManagerFactory() throws
TrustStoreConfigurationException {
- if (trustStoreConfig == null) {
- throw new TrustStoreConfigurationException(new Exception("The
trustStoreConfiguration is null"));
+ private static KeyManager[] loadKeyManagers(@Nullable final
KeyStoreConfiguration config) throws Exception {
+ if (config == null) {
+ return new KeyManager[0];
}
-
+ final KeyManagerFactory factory =
KeyManagerFactory.getInstance(config.getKeyManagerFactoryAlgorithm());
+ final char[] password = config.getPasswordAsCharArray();
try {
- return trustStoreConfig.initTrustManagerFactory();
- } catch (final NoSuchAlgorithmException e) {
- LOGGER.error("The specified algorithm is not available from the
specified provider", e);
- throw new TrustStoreConfigurationException(e);
- } catch (final KeyStoreException e) {
- LOGGER.error("Failed to initialize the TrustManagerFactory", e);
- throw new TrustStoreConfigurationException(e);
+ factory.init(config.getKeyStore(), password);
+ } finally {
+ config.clearSecrets();
}
+ return factory.getKeyManagers();
}
- private KeyManagerFactory loadKeyManagerFactory() throws
KeyStoreConfigurationException {
- if (keyStoreConfig == null) {
- throw new KeyStoreConfigurationException(new Exception("The
keyStoreConfiguration is null"));
- }
-
- try {
- return keyStoreConfig.initKeyManagerFactory();
- } catch (final NoSuchAlgorithmException e) {
- LOGGER.error("The specified algorithm is not available from the
specified provider", e);
- throw new KeyStoreConfigurationException(e);
- } catch (final KeyStoreException e) {
- LOGGER.error("Failed to initialize the TrustManagerFactory", e);
- throw new KeyStoreConfigurationException(e);
- } catch (final UnrecoverableKeyException e) {
- LOGGER.error("The key cannot be recovered (e.g. the given password
is wrong)", e);
- throw new KeyStoreConfigurationException(e);
+ private static TrustManager[] loadTrustManagers(@Nullable final
TrustStoreConfiguration config) throws Exception {
+ if (config == null) {
+ return new TrustManager[0];
}
+ final TrustManagerFactory factory =
TrustManagerFactory.getInstance(config.getTrustManagerFactoryAlgorithm());
+ factory.init(config.getKeyStore());
+ return factory.getTrustManagers();
}
/**
* Creates an SslConfiguration from a KeyStoreConfiguration and a
TrustStoreConfiguration.
*
- * @param protocol The protocol, see <a
href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">SSLContext
Algorithms</a>
- * @param keyStoreConfig The KeyStoreConfiguration.
+ * @param protocol The protocol, see <a
href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext">SSLContext
Algorithms</a>
+ * @param keyStoreConfig The KeyStoreConfiguration.
* @param trustStoreConfig The TrustStoreConfiguration.
* @return a new SslConfiguration
*/
+ @NullUnmarked
@PluginFactory
public static SslConfiguration createSSLConfiguration(
// @formatter:off
@@ -229,7 +178,7 @@ public class SslConfiguration {
@PluginElement("KeyStore") final KeyStoreConfiguration
keyStoreConfig,
@PluginElement("TrustStore") final TrustStoreConfiguration
trustStoreConfig) {
// @formatter:on
- return new SslConfiguration(protocol, keyStoreConfig,
trustStoreConfig, false);
+ return new SslConfiguration(protocol, false, keyStoreConfig,
trustStoreConfig);
}
/**
@@ -242,6 +191,7 @@ public class SslConfiguration {
* @return a new SslConfiguration
* @since 2.12
*/
+ @NullUnmarked
public static SslConfiguration createSSLConfiguration(
// @formatter:off
@PluginAttribute("protocol") final String protocol,
@@ -249,7 +199,7 @@ public class SslConfiguration {
@PluginElement("TrustStore") final TrustStoreConfiguration
trustStoreConfig,
@PluginAttribute("verifyHostName") final boolean verifyHostName) {
// @formatter:on
- return new SslConfiguration(protocol, keyStoreConfig,
trustStoreConfig, verifyHostName);
+ return new SslConfiguration(protocol, verifyHostName, keyStoreConfig,
trustStoreConfig);
}
@Override
@@ -269,13 +219,13 @@ public class SslConfiguration {
return false;
}
final SslConfiguration other = (SslConfiguration) obj;
- if (!Objects.equals(keyStoreConfig, other.keyStoreConfig)) {
+ if (!Objects.equals(protocol, other.protocol)) {
return false;
}
- if (!Objects.equals(protocol, other.protocol)) {
+ if (!Objects.equals(verifyHostName, other.verifyHostName)) {
return false;
}
- if (!Objects.equals(sslContext, other.sslContext)) {
+ if (!Objects.equals(keyStoreConfig, other.keyStoreConfig)) {
return false;
}
if (!Objects.equals(trustStoreConfig, other.trustStoreConfig)) {
@@ -284,6 +234,14 @@ public class SslConfiguration {
return true;
}
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public boolean isVerifyHostName() {
+ return verifyHostName;
+ }
+
public KeyStoreConfiguration getKeyStoreConfig() {
return keyStoreConfig;
}
@@ -295,12 +253,4 @@ public class SslConfiguration {
public SSLContext getSslContext() {
return sslContext;
}
-
- public String getProtocol() {
- return protocol;
- }
-
- public boolean isVerifyHostName() {
- return verifyHostName;
- }
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
index 6c09ad2c09..2da16b886d 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
@@ -27,7 +27,6 @@ import org.apache.logging.log4j.util.Strings;
public class SslConfigurationFactory {
private static final Logger LOGGER = StatusLogger.getLogger();
- private static final SslConfiguration sslConfiguration =
createSslConfiguration(PropertiesUtil.getProperties());
private static final String trustStorelocation =
"log4j2.trustStoreLocation";
private static final String trustStorePassword =
"log4j2.trustStorePassword";
@@ -111,6 +110,6 @@ public class SslConfigurationFactory {
}
public static SslConfiguration getSslConfiguration() {
- return sslConfiguration;
+ return createSslConfiguration(PropertiesUtil.getProperties());
}
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
index e50a4a377e..0c4393bc19 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
@@ -58,7 +58,7 @@ public class StoreConfiguration<T> {
*/
public void clearSecrets() {
this.location = null;
- this.passwordProvider = null;
+ this.passwordProvider = new MemoryPasswordProvider(new char[0]);
}
public String getLocation() {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
index 6dc212303d..5b27b883b0 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
@@ -152,7 +152,7 @@ public class TrustStoreConfiguration extends
AbstractKeyStoreConfiguration {
* Secure Socket Extension Reference Guide for information these names.
* @return a new TrustStoreConfiguration
* @throws StoreConfigurationException Thrown if this instance cannot load
the KeyStore.
- * @deprecated Use createKeyStoreConfiguration(String, char[], String,
String)
+ * @deprecated Use {@link #createKeyStoreConfiguration(String, char[],
String, String, String, String)}
*/
@Deprecated
public static TrustStoreConfiguration createKeyStoreConfiguration(
@@ -172,6 +172,10 @@ public class TrustStoreConfiguration extends
AbstractKeyStoreConfiguration {
trustManagerFactoryAlgorithm);
}
+ /**
+ * @deprecated Planned to be removed in the next major release
+ */
+ @Deprecated
public TrustManagerFactory initTrustManagerFactory() throws
NoSuchAlgorithmException, KeyStoreException {
final TrustManagerFactory tmFactory =
TrustManagerFactory.getInstance(this.trustManagerFactoryAlgorithm);
tmFactory.init(this.getKeyStore());
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
index db4860c1ff..7f7b26c282 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
@@ -18,7 +18,7 @@
* Log4j 2 SSL support
*/
@Export
-@Version("2.20.2")
+@Version("2.20.3")
package org.apache.logging.log4j.core.net.ssl;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
index 7c02b12fe6..00552976b7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
@@ -18,7 +18,7 @@
* Implementation of Log4j 2.
*/
@Export
-@Version("2.24.1")
+@Version("2.24.2")
package org.apache.logging.log4j.core;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
index a0464fde4f..4ae5d46335 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
@@ -23,6 +23,7 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.PropertiesUtil;
+import org.jspecify.annotations.Nullable;
/**
* Load resources (or images) from various sources.
@@ -84,9 +85,9 @@ public final class Loader {
* </ol>
* @param resource The resource to load.
* @param defaultLoader The default ClassLoader.
- * @return A URL to the resource.
+ * @return A URL to the resource or {@code null}.
*/
- public static URL getResource(final String resource, final ClassLoader
defaultLoader) {
+ public static @Nullable URL getResource(final String resource, final
ClassLoader defaultLoader) {
try {
ClassLoader classLoader = getThreadContextClassLoader();
if (classLoader != null) {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
index 580d3b73d4..5a79ab8b9a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
@@ -16,6 +16,8 @@
*/
package org.apache.logging.log4j.core.util;
+import static java.util.Objects.requireNonNull;
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.io.IOException;
@@ -30,10 +32,13 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
/**
* Represents the source for the logging configuration as an immutable object.
*/
+@NullMarked
public class Source {
private static final Logger LOGGER = StatusLogger.getLogger();
@@ -45,9 +50,9 @@ public class Source {
}
}
- private static File toFile(final Path path) {
+ private static @Nullable File toFile(Path path) {
try {
- return Objects.requireNonNull(path, "path").toFile();
+ return requireNonNull(path, "path").toFile();
} catch (final UnsupportedOperationException e) {
return null;
}
@@ -57,9 +62,9 @@ public class Source {
@SuppressFBWarnings(
value = "PATH_TRAVERSAL_IN",
justification = "The URI should be specified in a configuration
file.")
- private static File toFile(final URI uri) {
+ private static @Nullable File toFile(URI uri) {
try {
- final String scheme = Objects.requireNonNull(uri,
"uri").getScheme();
+ final String scheme = requireNonNull(uri, "uri").getScheme();
if (Strings.isBlank(scheme) || scheme.equals("file")) {
return new File(uri.getPath());
} else {
@@ -67,20 +72,20 @@ public class Source {
return null;
}
} catch (final Exception e) {
- LOGGER.debug("uri is malformed: " + uri.toString());
+ LOGGER.debug("uri is malformed: " + uri);
return null;
}
}
private static URI toURI(final URL url) {
try {
- return Objects.requireNonNull(url, "url").toURI();
+ return requireNonNull(url, "url").toURI();
} catch (final URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
- private final File file;
+ private final @Nullable File file;
private final URI uri;
private final String location;
@@ -88,21 +93,23 @@ public class Source {
* Constructs a Source from a ConfigurationSource.
*
* @param source The ConfigurationSource.
+ * @throws NullPointerException if {@code source} is {@code null}.
*/
public Source(final ConfigurationSource source) {
this.file = source.getFile();
- this.uri = source.getURI();
- this.location = source.getLocation();
+ this.uri = requireNonNull(source.getURI());
+ this.location = requireNonNull(source.getLocation());
}
/**
* Constructs a new {@code Source} with the specified file.
* file.
*
- * @param file the file where the input stream originated
+ * @param file the file where the input stream originated.
+ * @throws NullPointerException if {@code file} is {@code null}.
*/
public Source(final File file) {
- this.file = Objects.requireNonNull(file, "file");
+ this.file = requireNonNull(file, "file");
this.location = normalize(file);
this.uri = file.toURI();
}
@@ -111,9 +118,10 @@ public class Source {
* Constructs a new {@code Source} from the specified Path.
*
* @param path the Path where the input stream originated
+ * @throws NullPointerException if {@code path} is {@code null}.
*/
public Source(final Path path) {
- final Path normPath = Objects.requireNonNull(path, "path").normalize();
+ final Path normPath = requireNonNull(path, "path").normalize();
this.file = toFile(normPath);
this.uri = normPath.toUri();
this.location = normPath.toString();
@@ -123,9 +131,10 @@ public class Source {
* Constructs a new {@code Source} from the specified URI.
*
* @param uri the URI where the input stream originated
+ * @throws NullPointerException if {@code uri} is {@code null}.
*/
public Source(final URI uri) {
- final URI normUri = Objects.requireNonNull(uri, "uri").normalize();
+ final URI normUri = requireNonNull(uri, "uri").normalize();
this.uri = normUri;
this.location = normUri.toString();
this.file = toFile(normUri);
@@ -135,11 +144,12 @@ public class Source {
* Constructs a new {@code Source} from the specified URI.
*
* @param uri the URI where the input stream originated
- * @param lastModified Not used.
+ * @param ignored Not used.
* @deprecated Use {@link Source#Source(URI)}.
+ * @throws NullPointerException if {@code uri} is {@code null}.
*/
@Deprecated
- public Source(final URI uri, final long lastModified) {
+ public Source(URI uri, long ignored) {
this(uri);
}
@@ -147,6 +157,7 @@ public class Source {
* Constructs a new {@code Source} from the specified URL.
*
* @param url the URL where the input stream originated
+ * @throws NullPointerException if this URL is {@code null}.
* @throws IllegalArgumentException if this URL is not formatted strictly
according to RFC2396 and cannot be
* converted to a URI.
*/
@@ -174,7 +185,7 @@ public class Source {
*
* @return the configuration source file, or {@code null}
*/
- public File getFile() {
+ public @Nullable File getFile() {
return file;
}
@@ -197,7 +208,7 @@ public class Source {
value = "PATH_TRAVERSAL_IN",
justification = "The `file`, `uri` and `location` fields come from
Log4j properties.")
public Path getPath() {
- return file != null ? file.toPath() : uri != null ? Paths.get(uri) :
Paths.get(location);
+ return file != null ? file.toPath() : Paths.get(uri);
}
/**
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
index f2e50816d3..f4df3ebfa0 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
@@ -459,7 +459,7 @@ public class FastDatePrinter implements DatePrinter,
Serializable {
}
/**
- * Creation method for new calender instances.
+ * Creation method for new calendar instances.
* @return a new Calendar instance.
*/
private Calendar newCalendar() {
diff --git
a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
index afa401341c..ab1963ea23 100644
---
a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
+++
b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
@@ -262,7 +262,8 @@ public class SmtpManager extends MailManager {
if (smtpProtocol.equals("smtps")) {
final SslConfiguration sslConfiguration =
data.getSslConfiguration();
if (sslConfiguration != null) {
- final SSLSocketFactory sslSocketFactory =
sslConfiguration.getSslSocketFactory();
+ final SSLSocketFactory sslSocketFactory =
+
sslConfiguration.getSslContext().getSocketFactory();
properties.put(prefix + ".ssl.socketFactory",
sslSocketFactory);
properties.setProperty(
prefix + ".ssl.checkserveridentity",
Boolean.toString(sslConfiguration.isVerifyHostName()));
diff --git
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
index 46fb56f3de..97a7ab28bb 100644
---
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
+++
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
@@ -28,6 +28,8 @@ import
org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.spi.LoggerRegistry;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
/**
* This bridge between the tag library and the Log4j API ensures that
instances of {@link Log4jTaglibLogger} are
@@ -35,6 +37,7 @@ import org.apache.logging.log4j.spi.LoggerRegistry;
*
* @since 2.0
*/
+@NullMarked
final class Log4jTaglibLoggerContext implements LoggerContext {
private static final ReadWriteLock LOCK = new ReentrantReadWriteLock();
@@ -67,7 +70,7 @@ final class Log4jTaglibLoggerContext implements LoggerContext
{
}
@Override
- public Log4jTaglibLogger getLogger(final String name, final MessageFactory
messageFactory) {
+ public Log4jTaglibLogger getLogger(final String name, @Nullable final
MessageFactory messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
final Log4jTaglibLogger oldLogger = loggerRegistry.getLogger(name,
effectiveMessageFactory);
@@ -91,7 +94,7 @@ final class Log4jTaglibLoggerContext implements LoggerContext
{
}
@Override
- public boolean hasLogger(final String name, final MessageFactory
messageFactory) {
+ public boolean hasLogger(final String name, @Nullable final MessageFactory
messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
index ac85ecafea..9f8d273e7d 100644
---
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
+++
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
@@ -20,7 +20,7 @@
* @since 2.0
*/
@Export
-@Version("2.24.1")
+@Version("2.25.0")
package org.apache.logging.log4j.taglib;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
index ae6697fd98..6c18a83d48 100644
---
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
+++
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
@@ -22,6 +22,7 @@ import
org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.spi.LoggerRegistry;
+import org.jspecify.annotations.Nullable;
/**
* Implementation of Log4j {@link LoggerContext} SPI.
@@ -48,7 +49,7 @@ class JULLoggerContext implements LoggerContext {
}
@Override
- public ExtendedLogger getLogger(final String name, final MessageFactory
messageFactory) {
+ public ExtendedLogger getLogger(final String name, @Nullable final
MessageFactory messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
final ExtendedLogger oldLogger = loggerRegistry.getLogger(name,
effectiveMessageFactory);
@@ -60,7 +61,7 @@ class JULLoggerContext implements LoggerContext {
return loggerRegistry.getLogger(name, effectiveMessageFactory);
}
- private static ExtendedLogger createLogger(final String name, final
MessageFactory messageFactory) {
+ private static ExtendedLogger createLogger(final String name, @Nullable
final MessageFactory messageFactory) {
final Logger logger = Logger.getLogger(name);
return new JULLogger(name, messageFactory, logger);
}
@@ -71,7 +72,7 @@ class JULLoggerContext implements LoggerContext {
}
@Override
- public boolean hasLogger(final String name, final MessageFactory
messageFactory) {
+ public boolean hasLogger(final String name, @Nullable final MessageFactory
messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
index 8308d5c2fa..68812bb248 100644
---
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
+++
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
@@ -21,7 +21,7 @@
* @author <a href="http://www.vorburger.ch">Michael Vorburger.ch</a> for
Google
*/
@Export
-@Version("2.24.1")
+@Version("2.25.0")
package org.apache.logging.log4j.tojul;
import org.osgi.annotation.bundle.Export;
diff --git
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
index 407a9636f0..50160e9063 100644
---
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
+++
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
@@ -21,6 +21,7 @@ import
org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.spi.LoggerRegistry;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,7 +42,7 @@ public class SLF4JLoggerContext implements LoggerContext {
}
@Override
- public ExtendedLogger getLogger(final String name, final MessageFactory
messageFactory) {
+ public ExtendedLogger getLogger(final String name, @Nullable final
MessageFactory messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
final ExtendedLogger oldLogger = loggerRegistry.getLogger(name,
effectiveMessageFactory);
@@ -53,7 +54,7 @@ public class SLF4JLoggerContext implements LoggerContext {
return loggerRegistry.getLogger(name, effectiveMessageFactory);
}
- private static ExtendedLogger createLogger(final String name, final
MessageFactory messageFactory) {
+ private static ExtendedLogger createLogger(final String name, @Nullable
final MessageFactory messageFactory) {
final Logger logger = LoggerFactory.getLogger(name);
return new SLF4JLogger(name, messageFactory, logger);
}
@@ -64,7 +65,7 @@ public class SLF4JLoggerContext implements LoggerContext {
}
@Override
- public boolean hasLogger(final String name, final MessageFactory
messageFactory) {
+ public boolean hasLogger(final String name, @Nullable final MessageFactory
messageFactory) {
final MessageFactory effectiveMessageFactory =
messageFactory != null ? messageFactory :
DEFAULT_MESSAGE_FACTORY;
return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
index 12e4bedba2..8e6a1c3ac8 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
@@ -18,7 +18,7 @@
* SLF4J support.
*/
@Export
-@Version("2.24.1")
+@Version("2.25.0")
package org.apache.logging.slf4j;
import org.osgi.annotation.bundle.Export;