Skip to content

Commit c791f0c

Browse files
ppkarwaszvy
andcommitted
Fix reloading of the configuration from HTTP(S)
The `HttpWatcher` didn't propagate the observed last modification time back to the configuration. As a result, each new configuration was already deprecated when it started and the reconfiguration process looped. Closes #2937 Rewrite Jetty tests using WireMock Closes #2813 Co-authored-by: Volkan Yazıcı <[email protected]>
1 parent 981ae1e commit c791f0c

30 files changed

+1075
-828
lines changed

log4j-core-test/pom.xml

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,34 @@
6161
java.allocation.instrumenter;substitute="java-allocation-instrumenter",
6262
spring.test;substitute="spring-test"
6363
</bnd-extra-module-options>
64+
65+
<!-- Dependency versions -->
66+
<slf4j2.version>2.0.16</slf4j2.version>
67+
<wiremock.version>3.9.1</wiremock.version>
6468
</properties>
6569

70+
<dependencyManagement>
71+
<dependencies>
72+
73+
<!-- Transitive dependency of `wiremock` -->
74+
<dependency>
75+
<groupId>org.slf4j</groupId>
76+
<artifactId>slf4j-api</artifactId>
77+
<version>${slf4j2.version}</version>
78+
</dependency>
79+
80+
<!-- Pinned transitive dependencies with CVEs -->
81+
82+
<!-- Transitive dependency of `log4j2-custom-layout` -->
83+
<dependency>
84+
<groupId>com.google.code.gson</groupId>
85+
<artifactId>gson</artifactId>
86+
<version>2.11.0</version>
87+
</dependency>
88+
89+
</dependencies>
90+
</dependencyManagement>
91+
6692
<dependencies>
6793

6894
<dependency>
@@ -241,13 +267,6 @@
241267
<scope>test</scope>
242268
</dependency>
243269

244-
<!-- Log4j 1.2 tests -->
245-
<dependency>
246-
<groupId>log4j</groupId>
247-
<artifactId>log4j</artifactId>
248-
<scope>test</scope>
249-
</dependency>
250-
251270
<dependency>
252271
<groupId>com.github.ivandzf</groupId>
253272
<artifactId>log4j2-custom-layout</artifactId>
@@ -288,11 +307,11 @@
288307
<scope>test</scope>
289308
</dependency>
290309

291-
<!-- SLF4J tests -->
310+
<!-- Switch to `slf4j-simple` to enable HTTP logging -->
292311
<dependency>
293312
<groupId>org.slf4j</groupId>
294-
<artifactId>slf4j-api</artifactId>
295-
<scope>test</scope>
313+
<artifactId>slf4j-nop</artifactId>
314+
<version>${slf4j2.version}</version>
296315
</dependency>
297316

298317
<dependency>
@@ -303,8 +322,9 @@
303322

304323
<!-- Used for testing HTTP Watcher -->
305324
<dependency>
306-
<groupId>com.github.tomakehurst</groupId>
307-
<artifactId>wiremock-jre8</artifactId>
325+
<groupId>org.wiremock</groupId>
326+
<artifactId>wiremock</artifactId>
327+
<version>${wiremock.version}</version>
308328
<scope>test</scope>
309329
</dependency>
310330

@@ -345,6 +365,8 @@
345365
<runOrder>random</runOrder>
346366
<systemPropertyVariables>
347367
<Web.isWebApp>false</Web.isWebApp>
368+
<!-- Enables logging of HTTP requests, if `slf4j-nop` is replaced by `slf4j-simple` above-->
369+
<org.slf4j.simpleLogger.log.org.eclipse.jetty.server.HttpChannel>DEBUG</org.slf4j.simpleLogger.log.org.eclipse.jetty.server.HttpChannel>
348370
</systemPropertyVariables>
349371
<useModulePath>false</useModulePath>
350372
</configuration>

log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/ConfigurationSourceTest.java

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.logging.log4j.core.config;
1818

19+
import static java.util.Objects.requireNonNull;
1920
import static org.junit.jupiter.api.Assertions.assertEquals;
2021
import static org.junit.jupiter.api.Assertions.assertNotNull;
2122
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -32,50 +33,57 @@
3233
import java.net.URL;
3334
import java.nio.file.Files;
3435
import java.nio.file.Path;
35-
import java.nio.file.Paths;
3636
import java.util.jar.Attributes;
3737
import java.util.jar.JarEntry;
3838
import java.util.jar.JarOutputStream;
3939
import java.util.jar.Manifest;
40+
import org.apache.commons.io.IOUtils;
4041
import org.apache.logging.log4j.core.net.UrlConnectionFactory;
4142
import org.junit.jupiter.api.Test;
43+
import org.junit.jupiter.api.io.TempDir;
4244

4345
public class ConfigurationSourceTest {
44-
private static final Path JAR_FILE = Paths.get("target", "test-classes", "jarfile.jar");
45-
private static final Path CONFIG_FILE = Paths.get("target", "test-classes", "log4j2-console.xml");
46-
private static final byte[] buffer = new byte[1024];
46+
/**
47+
* The path inside the jar created by {@link #prepareJarConfigURL} containing the configuration.
48+
*/
49+
public static final String PATH_IN_JAR = "/config/console.xml";
50+
51+
private static final String CONFIG_FILE = "/config/ConfigurationSourceTest.xml";
52+
53+
@TempDir
54+
private Path tempDir;
4755

4856
@Test
49-
public void testJira_LOG4J2_2770_byteArray() throws Exception {
57+
void testJira_LOG4J2_2770_byteArray() throws Exception {
5058
final ConfigurationSource configurationSource =
5159
new ConfigurationSource(new ByteArrayInputStream(new byte[] {'a', 'b'}));
5260
assertNotNull(configurationSource.resetInputStream());
5361
}
5462

5563
/**
5664
* Checks if the usage of 'jar:' URLs does not increase the file descriptor
57-
* count and the jar file can be deleted.
58-
*
59-
* @throws Exception
65+
* count, and the jar file can be deleted.
6066
*/
6167
@Test
62-
public void testNoJarFileLeak() throws Exception {
63-
final URL jarConfigURL = prepareJarConfigURL();
68+
void testNoJarFileLeak() throws Exception {
69+
final Path jarFile = prepareJarConfigURL(tempDir);
70+
final URL jarConfigURL = new URL("jar:" + jarFile.toUri().toURL() + "!" + PATH_IN_JAR);
6471
final long expected = getOpenFileDescriptorCount();
6572
UrlConnectionFactory.createConnection(jarConfigURL).getInputStream().close();
6673
// This can only fail on UNIX
6774
assertEquals(expected, getOpenFileDescriptorCount());
6875
// This can only fail on Windows
6976
try {
70-
Files.delete(JAR_FILE);
77+
Files.delete(jarFile);
7178
} catch (IOException e) {
7279
fail(e);
7380
}
7481
}
7582

7683
@Test
7784
public void testLoadConfigurationSourceFromJarFile() throws Exception {
78-
final URL jarConfigURL = prepareJarConfigURL();
85+
final Path jarFile = prepareJarConfigURL(tempDir);
86+
final URL jarConfigURL = new URL("jar:" + jarFile.toUri().toURL() + "!" + PATH_IN_JAR);
7987
final long expectedFdCount = getOpenFileDescriptorCount();
8088
ConfigurationSource configSource = ConfigurationSource.fromUri(jarConfigURL.toURI());
8189
assertNotNull(configSource);
@@ -90,7 +98,7 @@ public void testLoadConfigurationSourceFromJarFile() throws Exception {
9098
assertEquals(expectedFdCount, getOpenFileDescriptorCount());
9199
// This can only fail on Windows
92100
try {
93-
Files.delete(JAR_FILE);
101+
Files.delete(jarFile);
94102
} catch (IOException e) {
95103
fail(e);
96104
}
@@ -104,22 +112,18 @@ private long getOpenFileDescriptorCount() {
104112
return 0L;
105113
}
106114

107-
public static URL prepareJarConfigURL() throws IOException {
108-
if (!Files.exists(JAR_FILE)) {
109-
final Manifest manifest = new Manifest();
110-
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
111-
try (final OutputStream os = Files.newOutputStream(JAR_FILE);
112-
final JarOutputStream jar = new JarOutputStream(os, manifest);
113-
final InputStream config = Files.newInputStream(CONFIG_FILE)) {
114-
final JarEntry jarEntry = new JarEntry("config/console.xml");
115-
jar.putNextEntry(jarEntry);
116-
int len;
117-
while ((len = config.read(buffer)) != -1) {
118-
jar.write(buffer, 0, len);
119-
}
120-
jar.closeEntry();
121-
}
115+
public static Path prepareJarConfigURL(Path dir) throws IOException {
116+
Path jarFile = dir.resolve("jarFile.jar");
117+
final Manifest manifest = new Manifest();
118+
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
119+
try (final OutputStream os = Files.newOutputStream(jarFile);
120+
final JarOutputStream jar = new JarOutputStream(os, manifest);
121+
final InputStream config =
122+
requireNonNull(ConfigurationSourceTest.class.getResourceAsStream(CONFIG_FILE))) {
123+
final JarEntry jarEntry = new JarEntry("config/console.xml");
124+
jar.putNextEntry(jarEntry);
125+
IOUtils.copy(config, os);
122126
}
123-
return new URL("jar:" + JAR_FILE.toUri().toURL() + "!/config/console.xml");
127+
return jarFile;
124128
}
125129
}

log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/HttpThreadContextMapFilterTest.java

Lines changed: 0 additions & 113 deletions
This file was deleted.

0 commit comments

Comments
 (0)