This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 78c6699 [LOG4J2-3014] Log4j1ConfigurationConverter on Windows
produces "
" at end of every line.
new adfd2b7 Merge branch 'master' of
https://gitbox.apache.org/repos/asf/logging-log4j2.git
78c6699 is described below
commit 78c66999a4d27e4cd7c31acac5de1361b1d050e3
Author: Gary Gregory <[email protected]>
AuthorDate: Wed Feb 3 11:15:20 2021 -0500
[LOG4J2-3014] Log4j1ConfigurationConverter on Windows produces "
"
at end of every line.
---
.../log4j/config/Log4j1ConfigurationConverter.java | 26 +++++++--
.../AbstractLog4j1ConfigurationConverterTest.java | 21 ++++++-
.../builder/impl/DefaultConfigurationBuilder.java | 66 ++++++++++++----------
.../config/builder/ConfigurationBuilderTest.java | 4 +-
src/changes/changes.xml | 3 +
5 files changed, 83 insertions(+), 37 deletions(-)
diff --git
a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationConverter.java
b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationConverter.java
index 4475f6a..caede4e 100644
---
a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationConverter.java
+++
b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationConverter.java
@@ -16,6 +16,8 @@
*/
package org.apache.log4j.config;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -26,9 +28,14 @@ import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
import org.apache.logging.log4j.core.config.ConfigurationException;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
+import
org.apache.logging.log4j.core.config.builder.impl.DefaultConfigurationBuilder;
import org.apache.logging.log4j.core.tools.BasicCommandLineArguments;
import org.apache.logging.log4j.core.tools.picocli.CommandLine;
import org.apache.logging.log4j.core.tools.picocli.CommandLine.Command;
@@ -175,11 +182,16 @@ public final class Log4j1ConfigurationConverter {
final int lastIndex = newFile.lastIndexOf(".");
newFile = lastIndex < 0 ? newFile + FILE_EXT_XML
: newFile.substring(0, lastIndex) +
FILE_EXT_XML;
- final Path resolved = file.resolveSibling(newFile);
+ final Path resolvedPath =
file.resolveSibling(newFile);
try (final InputStream input = new
InputStreamWrapper(Files.newInputStream(file), file.toString());
- final OutputStream output =
Files.newOutputStream(resolved)) {
+ final OutputStream output =
Files.newOutputStream(resolvedPath)) {
try {
- convert(input, output);
+ final ByteArrayOutputStream tmpOutput =
new ByteArrayOutputStream();
+ convert(input, tmpOutput);
+ tmpOutput.close();
+ DefaultConfigurationBuilder.formatXml(
+ new StreamSource(new
ByteArrayInputStream(tmpOutput.toByteArray())),
+ new StreamResult(output));
countOKs.incrementAndGet();
} catch (ConfigurationException | IOException
e) {
countFails.incrementAndGet();
@@ -187,8 +199,14 @@ public final class Log4j1ConfigurationConverter {
throw e;
}
e.printStackTrace();
+ } catch (TransformerException e) {
+ countFails.incrementAndGet();
+ if (cla.isFailFast()) {
+ throw new IOException(e);
+ }
+ e.printStackTrace();
}
- verbose("Wrote %s", resolved);
+ verbose("Wrote %s", resolvedPath);
}
}
return FileVisitResult.CONTINUE;
diff --git
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationConverterTest.java
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationConverterTest.java
index 9c973ee..43e3c5d 100644
---
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationConverterTest.java
+++
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationConverterTest.java
@@ -1,5 +1,7 @@
package org.apache.log4j.config;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -10,9 +12,13 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import org.xml.sax.SAXException;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -54,15 +60,28 @@ public abstract class
AbstractLog4j1ConfigurationConverterTest {
}
@Test
- public void test() throws IOException {
+ public void test() throws Exception {
final Path tempFile = Files.createTempFile("log4j2", ".xml");
try {
final Log4j1ConfigurationConverter.CommandLineArguments cla = new
Log4j1ConfigurationConverter.CommandLineArguments();
cla.setPathIn(pathIn);
cla.setPathOut(tempFile);
Log4j1ConfigurationConverter.run(cla);
+ checkWellFormedXml(tempFile);
+ checkUnnecessaryEscaping(tempFile);
} finally {
Files.deleteIfExists(tempFile);
}
}
+
+ private void checkUnnecessaryEscaping(Path tempFile) throws IOException {
+ for (String line : Files.readAllLines(tempFile)) {
+ assertFalse(line.endsWith("
"));
+ }
+
+ }
+
+ private void checkWellFormedXml(Path xmlFilePath) throws SAXException,
IOException, ParserConfigurationException {
+
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFilePath.toUri().toString());
+ }
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
index 4d703fa..822f742 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.config.builder.impl;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.util.List;
@@ -27,6 +28,16 @@ import java.util.concurrent.TimeUnit;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter;
@@ -58,7 +69,6 @@ import org.apache.logging.log4j.core.util.Throwables;
public class DefaultConfigurationBuilder<T extends BuiltConfiguration>
implements ConfigurationBuilder<T> {
private static final String INDENT = " ";
- private static final String EOL = System.lineSeparator();
private final Component root = new Component();
private final Component loggers;
@@ -80,6 +90,14 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
private LoggerContext loggerContext;
private String name;
+ public static void formatXml(final Source source, final Result result)
+ throws TransformerConfigurationException,
TransformerFactoryConfigurationError, TransformerException {
+ final Transformer transformer =
TransformerFactory.newInstance().newTransformer();
+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
Integer.toString(INDENT.length()));
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.transform(source, result);
+ }
+
@SuppressWarnings("unchecked")
public DefaultConfigurationBuilder() {
this((Class<T>) BuiltConfiguration.class);
@@ -215,7 +233,7 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
xmlWriter.close();
} catch (final XMLStreamException e) {
if (e.getNestedException() instanceof IOException) {
- throw (IOException)e.getNestedException();
+ throw (IOException) e.getNestedException();
}
Throwables.rethrow(e);
}
@@ -223,20 +241,27 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
@Override
public String toXmlConfiguration() {
- final StringWriter sw = new StringWriter();
+ final StringWriter writer = new StringWriter();
try {
- final XMLStreamWriter xmlWriter =
XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
+ final XMLStreamWriter xmlWriter =
XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
writeXmlConfiguration(xmlWriter);
xmlWriter.close();
- } catch (final XMLStreamException e) {
+ return formatXml(writer.toString());
+ } catch (final XMLStreamException | TransformerException e) {
Throwables.rethrow(e);
}
- return sw.toString();
+ return writer.toString();
+ }
+
+ private String formatXml(String xml)
+ throws TransformerConfigurationException, TransformerException,
TransformerFactoryConfigurationError {
+ final StringWriter writer = new StringWriter();
+ formatXml(new StreamSource(new StringReader(xml)), new
StreamResult(writer));
+ return writer.toString();
}
private void writeXmlConfiguration(final XMLStreamWriter xmlWriter) throws
XMLStreamException {
xmlWriter.writeStartDocument();
- xmlWriter.writeCharacters(EOL);
xmlWriter.writeStartElement("Configuration");
if (name != null) {
@@ -267,13 +292,11 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
xmlWriter.writeAttribute("monitorInterval",
String.valueOf(monitorInterval));
}
- xmlWriter.writeCharacters(EOL);
-
writeXmlSection(xmlWriter, properties);
writeXmlSection(xmlWriter, scripts);
writeXmlSection(xmlWriter, customLevels);
if (filters.getComponents().size() == 1) {
- writeXmlComponent(xmlWriter, filters.getComponents().get(0), 1);
+ writeXmlComponent(xmlWriter, filters.getComponents().get(0));
} else if (filters.getComponents().size() > 1) {
writeXmlSection(xmlWriter, filters);
}
@@ -281,47 +304,30 @@ public class DefaultConfigurationBuilder<T extends
BuiltConfiguration> implement
writeXmlSection(xmlWriter, loggers);
xmlWriter.writeEndElement(); // "Configuration"
- xmlWriter.writeCharacters(EOL);
-
xmlWriter.writeEndDocument();
}
private void writeXmlSection(final XMLStreamWriter xmlWriter, final
Component component) throws XMLStreamException {
if (!component.getAttributes().isEmpty() ||
!component.getComponents().isEmpty() || component.getValue() != null) {
- writeXmlComponent(xmlWriter, component, 1);
+ writeXmlComponent(xmlWriter, component);
}
}
- private void writeXmlComponent(final XMLStreamWriter xmlWriter, final
Component component, final int nesting) throws XMLStreamException {
+ private void writeXmlComponent(final XMLStreamWriter xmlWriter, final
Component component) throws XMLStreamException {
if (!component.getComponents().isEmpty() || component.getValue() !=
null) {
- writeXmlIndent(xmlWriter, nesting);
xmlWriter.writeStartElement(component.getPluginType());
writeXmlAttributes(xmlWriter, component);
- if (!component.getComponents().isEmpty()) {
- xmlWriter.writeCharacters(EOL);
- }
for (final Component subComponent : component.getComponents()) {
- writeXmlComponent(xmlWriter, subComponent, nesting + 1);
+ writeXmlComponent(xmlWriter, subComponent);
}
if (component.getValue() != null) {
xmlWriter.writeCharacters(component.getValue());
}
- if (!component.getComponents().isEmpty()) {
- writeXmlIndent(xmlWriter, nesting);
- }
xmlWriter.writeEndElement();
} else {
- writeXmlIndent(xmlWriter, nesting);
xmlWriter.writeEmptyElement(component.getPluginType());
writeXmlAttributes(xmlWriter, component);
}
- xmlWriter.writeCharacters(EOL);
- }
-
- private void writeXmlIndent(final XMLStreamWriter xmlWriter, final int
nesting) throws XMLStreamException {
- for (int i = 0; i < nesting; i++) {
- xmlWriter.writeCharacters(INDENT);
- }
}
private void writeXmlAttributes(final XMLStreamWriter xmlWriter, final
Component component) throws XMLStreamException {
diff --git
a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
index 40c0717..03b76a5 100644
---
a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
+++
b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/builder/ConfigurationBuilderTest.java
@@ -64,7 +64,7 @@ public class ConfigurationBuilderTest {
}
private final static String expectedXml =
- "<?xml version='1.0' encoding='UTF-8'?>" + EOL +
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" /*+ EOL*/ +
"<Configuration name=\"config name\" status=\"ERROR\"
packages=\"foo,bar\" shutdownTimeout=\"5000\">" + EOL +
INDENT + "<Properties>" + EOL +
INDENT + INDENT + "<Property
name=\"MyKey\">MyValue</Property>" + EOL +
@@ -96,7 +96,7 @@ public class ConfigurationBuilderTest {
"</Configuration>" + EOL;
@Test
- @DisabledOnOs(OS.WINDOWS) // TODO make test run properly on Windows
+ //@DisabledOnOs(OS.WINDOWS) // TODO make test run properly on Windows
public void testXmlConstructing() throws Exception {
final ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
addTestFixtures("config name", builder);
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8a69cf4..3e4549e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -209,6 +209,9 @@
<action issue="LOG4J2-2850" dev="sandeepbarnwal" type="fix">
Fixes incorrect constructor call in LocalizedMessageFactory.
</action>
+ <action issue="LOG4J2-2976" dev="ggregory" type="fix" due-to="Lee
Breisacher, Gary Gregory">
+ Log4j1ConfigurationConverter on Windows produces "
" at end of
every line.
+ </action>
</release>
<release version="2.14.1" date="2020-MM-DD" description="GA Release
2.14.1">
<action dev="rgoers" type="update">