You may not be missing anything. If you don’t think it is a problem then just add the config items revapi spits out to the configuration. There are some there already so you can look at the justifications for those as examples.
Ralph > On Aug 16, 2019, at 11:23 AM, Gary Gregory <[email protected]> wrote: > > It looks like a bug in revapi to me: it does not know about type erasures. > I created a new Maven project that depends on Log4j Core 2.12.1 with: > > public class App > { > public static void main( String[] args ) > { > System.out.println( "Hello World!" ); > Builder builder = OutputStreamAppender.newBuilder(); > } > } > > Then I ran that class against 2.13.-SNAPSHOT Core without recompiling and > it ran fine. > > What am I missing? > > Gary > > On Thu, Aug 15, 2019 at 5:03 PM Ralph Goers <[email protected]> > wrote: > >> I believe you have not read this thread. I am not talking about the bug >> you fixed. I am talking the compatibility breakage you created. >> >> 1. The backward compatibility breakage only occurred on the release-2.x >> branch because revapi is essentially disabled on master. Too much has >> changed to bother keeping track. >> 2. I haven’t seen any commit messages indicating you committed anything to >> fix this. >> 3. The build is still failing for me. Try running mvn clean install >> -DskipTests in log4j-core. It will break for you too. >> >> Please look at the Jenkins build and fix the problems by either reverting >> the breakage or by adding the recommended changes to revapi.json to >> document why compatibility was broken. >> >> Ralph >> >> >>> On Aug 15, 2019, at 4:54 PM, Gary Gregory <[email protected]> >> wrote: >>> >>> I fixed it already in both branches. >>> >>> Gary >>> >>> On Thu, Aug 15, 2019, 10:42 Ralph Goers <[email protected]> >> wrote: >>> >>>> Gary, >>>> >>>> Are you going to look into this? >>>> >>>> Ralph >>>> >>>>> On Aug 14, 2019, at 9:17 AM, Ralph Goers <[email protected]> >>>> wrote: >>>>> >>>>> Any update on this? I’d like my builds to work again. >>>>> >>>>> Ralph >>>>> >>>>>> On Aug 13, 2019, at 4:29 PM, Ralph Goers <[email protected]> >>>> wrote: >>>>>> >>>>>> Gary, >>>>>> >>>>>> It seems this change broker compatibility. Please see the Jenkins >>>> failure. You either need to resolve the code so compatibility is >> maintained >>>> or update revapi.json with the recommended changes. >>>>>> >>>>>> Ralph >>>>>> >>>>>>> On Aug 13, 2019, at 2:06 PM, [email protected] wrote: >>>>>>> >>>>>>> This is an automated email from the ASF dual-hosted git repository. >>>>>>> >>>>>>> ggregory pushed a commit to branch release-2.x >>>>>>> in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git >>>>>>> >>>>>>> >>>>>>> The following commit(s) were added to refs/heads/release-2.x by this >>>> push: >>>>>>> new 4679a08 [LOG4J2-2673] OutputStreamAppender.Builder ignores >>>> setFilter(). >>>>>>> 4679a08 is described below >>>>>>> >>>>>>> commit 4679a08d4899350f7ee19d050d2a96783b748066 >>>>>>> Author: Gary Gregory <[email protected]> >>>>>>> AuthorDate: Tue Aug 13 17:06:48 2019 -0400 >>>>>>> >>>>>>> [LOG4J2-2673] OutputStreamAppender.Builder ignores setFilter(). >>>>>>> >>>>>>> Also allow a null output stream for convenience instead of an NPE. >>>>>>> --- >>>>>>> .../log4j/core/appender/OutputStreamAppender.java | 351 >>>> +++++++++++---------- >>>>>>> .../core/appender/OutputStreamAppenderTest.java | 230 >> +++++++------- >>>>>>> src/changes/changes.xml | 3 + >>>>>>> 3 files changed, 302 insertions(+), 282 deletions(-) >>>>>>> >>>>>>> diff --git >>>> >> a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java >>>> >> b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java >>>>>>> index 7dfd187..dc6f352 100644 >>>>>>> --- >>>> >> a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java >>>>>>> +++ >>>> >> b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java >>>>>>> @@ -1,174 +1,177 @@ >>>>>>> -/* >>>>>>> - * Licensed to the Apache Software Foundation (ASF) under one or >> more >>>>>>> - * contributor license agreements. See the NOTICE file distributed >>>> with >>>>>>> - * this work for additional information regarding copyright >> ownership. >>>>>>> - * The ASF licenses this file to You under the Apache license, >>>> Version 2.0 >>>>>>> - * (the "License"); you may not use this file except in compliance >>>> with >>>>>>> - * the License. You may obtain a copy of the License at >>>>>>> - * >>>>>>> - * http://www.apache.org/licenses/LICENSE-2.0 >>>>>>> - * >>>>>>> - * Unless required by applicable law or agreed to in writing, >> software >>>>>>> - * distributed under the License is distributed on an "AS IS" BASIS, >>>>>>> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>> implied. >>>>>>> - * See the license for the specific language governing permissions >> and >>>>>>> - * limitations under the license. >>>>>>> - */ >>>>>>> -package org.apache.logging.log4j.core.appender; >>>>>>> - >>>>>>> -import java.io.OutputStream; >>>>>>> -import java.io.Serializable; >>>>>>> - >>>>>>> -import org.apache.logging.log4j.core.Appender; >>>>>>> -import org.apache.logging.log4j.core.Core; >>>>>>> -import org.apache.logging.log4j.core.Filter; >>>>>>> -import org.apache.logging.log4j.core.Layout; >>>>>>> -import org.apache.logging.log4j.core.config.Property; >>>>>>> -import org.apache.logging.log4j.core.config.plugins.Plugin; >>>>>>> -import >>>> org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; >>>>>>> -import org.apache.logging.log4j.core.config.plugins.PluginFactory; >>>>>>> -import org.apache.logging.log4j.core.layout.PatternLayout; >>>>>>> -import org.apache.logging.log4j.core.util.CloseShieldOutputStream; >>>>>>> - >>>>>>> -/** >>>>>>> - * Appends log events to a given output stream using a layout. >>>>>>> - * <p> >>>>>>> - * Character encoding is handled within the Layout. >>>>>>> - * </p> >>>>>>> - */ >>>>>>> -@Plugin(name = "OutputStream", category = Core.CATEGORY_NAME, >>>> elementType = Appender.ELEMENT_TYPE, printObject = true) >>>>>>> -public final class OutputStreamAppender extends >>>> AbstractOutputStreamAppender<OutputStreamManager> { >>>>>>> - >>>>>>> - /** >>>>>>> - * Builds OutputStreamAppender instances. >>>>>>> - */ >>>>>>> - public static class Builder<B extends Builder<B>> extends >>>> AbstractOutputStreamAppender.Builder<B> >>>>>>> - implements >>>> org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> { >>>>>>> - >>>>>>> - private Filter filter; >>>>>>> - >>>>>>> - private boolean follow = false; >>>>>>> - >>>>>>> - private final boolean ignoreExceptions = true; >>>>>>> - >>>>>>> - private OutputStream target; >>>>>>> - >>>>>>> - @Override >>>>>>> - public OutputStreamAppender build() { >>>>>>> - final Layout<? extends Serializable> layout = >> getLayout(); >>>>>>> - final Layout<? extends Serializable> actualLayout = >>>> layout == null ? PatternLayout.createDefaultLayout() >>>>>>> - : layout; >>>>>>> - return new OutputStreamAppender(getName(), actualLayout, >>>> filter, getManager(target, follow, actualLayout), >>>>>>> - ignoreExceptions, getPropertyArray()); >>>>>>> - } >>>>>>> - >>>>>>> - public B setFollow(final boolean shouldFollow) { >>>>>>> - this.follow = shouldFollow; >>>>>>> - return asBuilder(); >>>>>>> - } >>>>>>> - >>>>>>> - public B setTarget(final OutputStream aTarget) { >>>>>>> - this.target = aTarget; >>>>>>> - return asBuilder(); >>>>>>> - } >>>>>>> - } >>>>>>> - >>>>>>> - /** >>>>>>> - * Holds data to pass to factory method. >>>>>>> - */ >>>>>>> - private static class FactoryData { >>>>>>> - private final Layout<? extends Serializable> layout; >>>>>>> - private final String name; >>>>>>> - private final OutputStream os; >>>>>>> - >>>>>>> - /** >>>>>>> - * Builds instances. >>>>>>> - * >>>>>>> - * @param os >>>>>>> - * The OutputStream. >>>>>>> - * @param type >>>>>>> - * The name of the target. >>>>>>> - * @param layout >>>>>>> - * A Serializable layout >>>>>>> - */ >>>>>>> - public FactoryData(final OutputStream os, final String type, >>>> final Layout<? extends Serializable> layout) { >>>>>>> - this.os = os; >>>>>>> - this.name = type; >>>>>>> - this.layout = layout; >>>>>>> - } >>>>>>> - } >>>>>>> - >>>>>>> - /** >>>>>>> - * Creates the manager. >>>>>>> - */ >>>>>>> - private static class OutputStreamManagerFactory implements >>>> ManagerFactory<OutputStreamManager, FactoryData> { >>>>>>> - >>>>>>> - /** >>>>>>> - * Creates an OutputStreamManager. >>>>>>> - * >>>>>>> - * @param name >>>>>>> - * The name of the entity to manage. >>>>>>> - * @param data >>>>>>> - * The data required to create the entity. >>>>>>> - * @return The OutputStreamManager >>>>>>> - */ >>>>>>> - @Override >>>>>>> - public OutputStreamManager createManager(final String name, >>>> final FactoryData data) { >>>>>>> - return new OutputStreamManager(data.os, data.name, >>>> data.layout, true); >>>>>>> - } >>>>>>> - } >>>>>>> - >>>>>>> - private static OutputStreamManagerFactory factory = new >>>> OutputStreamManagerFactory(); >>>>>>> - >>>>>>> - /** >>>>>>> - * Creates an OutputStream Appender. >>>>>>> - * >>>>>>> - * @param layout >>>>>>> - * The layout to use or null to get the default >> layout. >>>>>>> - * @param filter >>>>>>> - * The Filter or null. >>>>>>> - * @param target >>>>>>> - * an output stream. >>>>>>> - * @param follow >>>>>>> - * If true will follow changes to the underlying >>>> output stream. >>>>>>> - * Use false as the default. >>>>>>> - * @param name >>>>>>> - * The name of the Appender (required). >>>>>>> - * @param ignore >>>>>>> - * If {@code "true"} (default) exceptions encountered >>>> when >>>>>>> - * appending events are logged; otherwise they are >>>> propagated to >>>>>>> - * the caller. Use true as the default. >>>>>>> - * @return The ConsoleAppender. >>>>>>> - */ >>>>>>> - @PluginFactory >>>>>>> - public static OutputStreamAppender createAppender(Layout<? >>>> extends Serializable> layout, final Filter filter, >>>>>>> - final OutputStream target, final String name, final >>>> boolean follow, final boolean ignore) { >>>>>>> - if (name == null) { >>>>>>> - LOGGER.error("No name provided for >> OutputStreamAppender"); >>>>>>> - return null; >>>>>>> - } >>>>>>> - if (layout == null) { >>>>>>> - layout = PatternLayout.createDefaultLayout(); >>>>>>> - } >>>>>>> - return new OutputStreamAppender(name, layout, filter, >>>> getManager(target, follow, layout), ignore, null); >>>>>>> - } >>>>>>> - >>>>>>> - private static OutputStreamManager getManager(final OutputStream >>>> target, final boolean follow, >>>>>>> - final Layout<? extends Serializable> layout) { >>>>>>> - final OutputStream os = new CloseShieldOutputStream(target); >>>>>>> - final String managerName = target.getClass().getName() + "@" >>>> + Integer.toHexString(target.hashCode()) + '.' >>>>>>> - + follow; >>>>>>> - return OutputStreamManager.getManager(managerName, new >>>> FactoryData(os, managerName, layout), factory); >>>>>>> - } >>>>>>> - >>>>>>> - @PluginBuilderFactory >>>>>>> - public static Builder newBuilder() { >>>>>>> - return new Builder(); >>>>>>> - } >>>>>>> - >>>>>>> - private OutputStreamAppender(final String name, final Layout<? >>>> extends Serializable> layout, final Filter filter, >>>>>>> - final OutputStreamManager manager, final boolean >>>> ignoreExceptions, final Property[] properties) { >>>>>>> - super(name, layout, filter, ignoreExceptions, true, >>>> properties, manager); >>>>>>> - } >>>>>>> - >>>>>>> -} >>>>>>> +/* >>>>>>> + * Licensed to the Apache Software Foundation (ASF) under one or >> more >>>>>>> + * contributor license agreements. See the NOTICE file distributed >>>> with >>>>>>> + * this work for additional information regarding copyright >> ownership. >>>>>>> + * The ASF licenses this file to You under the Apache license, >>>> Version 2.0 >>>>>>> + * (the "License"); you may not use this file except in compliance >>>> with >>>>>>> + * the License. You may obtain a copy of the License at >>>>>>> + * >>>>>>> + * http://www.apache.org/licenses/LICENSE-2.0 >>>>>>> + * >>>>>>> + * Unless required by applicable law or agreed to in writing, >> software >>>>>>> + * distributed under the License is distributed on an "AS IS" BASIS, >>>>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>> implied. >>>>>>> + * See the license for the specific language governing permissions >> and >>>>>>> + * limitations under the license. >>>>>>> + */ >>>>>>> +package org.apache.logging.log4j.core.appender; >>>>>>> + >>>>>>> +import java.io.OutputStream; >>>>>>> +import java.io.Serializable; >>>>>>> + >>>>>>> +import org.apache.logging.log4j.core.Appender; >>>>>>> +import org.apache.logging.log4j.core.Core; >>>>>>> +import org.apache.logging.log4j.core.Filter; >>>>>>> +import org.apache.logging.log4j.core.Layout; >>>>>>> +import org.apache.logging.log4j.core.config.Property; >>>>>>> +import org.apache.logging.log4j.core.config.plugins.Plugin; >>>>>>> +import >>>> org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; >>>>>>> +import org.apache.logging.log4j.core.config.plugins.PluginFactory; >>>>>>> +import org.apache.logging.log4j.core.layout.PatternLayout; >>>>>>> +import org.apache.logging.log4j.core.util.CloseShieldOutputStream; >>>>>>> +import org.apache.logging.log4j.core.util.NullOutputStream; >>>>>>> + >>>>>>> +/** >>>>>>> + * Appends log events to a given output stream using a layout. >>>>>>> + * <p> >>>>>>> + * Character encoding is handled within the Layout. >>>>>>> + * </p> >>>>>>> + */ >>>>>>> +@Plugin(name = "OutputStream", category = Core.CATEGORY_NAME, >>>> elementType = Appender.ELEMENT_TYPE, printObject = true) >>>>>>> +public final class OutputStreamAppender extends >>>> AbstractOutputStreamAppender<OutputStreamManager> { >>>>>>> + >>>>>>> + /** >>>>>>> + * Builds OutputStreamAppender instances. >>>>>>> + * >>>>>>> + * @param <B> >>>>>>> + * The type to build. >>>>>>> + */ >>>>>>> + public static class Builder<B extends Builder<B>> extends >>>> AbstractOutputStreamAppender.Builder<B> >>>>>>> + implements >>>> org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> { >>>>>>> + >>>>>>> + private boolean follow = false; >>>>>>> + >>>>>>> + private final boolean ignoreExceptions = true; >>>>>>> + >>>>>>> + private OutputStream target; >>>>>>> + >>>>>>> + @Override >>>>>>> + public OutputStreamAppender build() { >>>>>>> + final Layout<? extends Serializable> layout = >> getLayout(); >>>>>>> + final Layout<? extends Serializable> actualLayout = >>>> layout == null ? PatternLayout.createDefaultLayout() >>>>>>> + : layout; >>>>>>> + return new OutputStreamAppender(getName(), actualLayout, >>>> getFilter(), getManager(target, follow, actualLayout), >>>>>>> + ignoreExceptions, getPropertyArray()); >>>>>>> + } >>>>>>> + >>>>>>> + public B setFollow(final boolean shouldFollow) { >>>>>>> + this.follow = shouldFollow; >>>>>>> + return asBuilder(); >>>>>>> + } >>>>>>> + >>>>>>> + public B setTarget(final OutputStream aTarget) { >>>>>>> + this.target = aTarget; >>>>>>> + return asBuilder(); >>>>>>> + } >>>>>>> + } >>>>>>> + >>>>>>> + /** >>>>>>> + * Holds data to pass to factory method. >>>>>>> + */ >>>>>>> + private static class FactoryData { >>>>>>> + private final Layout<? extends Serializable> layout; >>>>>>> + private final String name; >>>>>>> + private final OutputStream os; >>>>>>> + >>>>>>> + /** >>>>>>> + * Builds instances. >>>>>>> + * >>>>>>> + * @param os >>>>>>> + * The OutputStream. >>>>>>> + * @param type >>>>>>> + * The name of the target. >>>>>>> + * @param layout >>>>>>> + * A Serializable layout >>>>>>> + */ >>>>>>> + public FactoryData(final OutputStream os, final String type, >>>> final Layout<? extends Serializable> layout) { >>>>>>> + this.os = os; >>>>>>> + this.name = type; >>>>>>> + this.layout = layout; >>>>>>> + } >>>>>>> + } >>>>>>> + >>>>>>> + /** >>>>>>> + * Creates the manager. >>>>>>> + */ >>>>>>> + private static class OutputStreamManagerFactory implements >>>> ManagerFactory<OutputStreamManager, FactoryData> { >>>>>>> + >>>>>>> + /** >>>>>>> + * Creates an OutputStreamManager. >>>>>>> + * >>>>>>> + * @param name >>>>>>> + * The name of the entity to manage. >>>>>>> + * @param data >>>>>>> + * The data required to create the entity. >>>>>>> + * @return The OutputStreamManager >>>>>>> + */ >>>>>>> + @Override >>>>>>> + public OutputStreamManager createManager(final String name, >>>> final FactoryData data) { >>>>>>> + return new OutputStreamManager(data.os, data.name, >>>> data.layout, true); >>>>>>> + } >>>>>>> + } >>>>>>> + >>>>>>> + private static OutputStreamManagerFactory factory = new >>>> OutputStreamManagerFactory(); >>>>>>> + >>>>>>> + /** >>>>>>> + * Creates an OutputStream Appender. >>>>>>> + * >>>>>>> + * @param layout >>>>>>> + * The layout to use or null to get the default >> layout. >>>>>>> + * @param filter >>>>>>> + * The Filter or null. >>>>>>> + * @param target >>>>>>> + * an output stream. >>>>>>> + * @param follow >>>>>>> + * If true will follow changes to the underlying >>>> output stream. >>>>>>> + * Use false as the default. >>>>>>> + * @param name >>>>>>> + * The name of the Appender (required). >>>>>>> + * @param ignore >>>>>>> + * If {@code "true"} (default) exceptions encountered >>>> when >>>>>>> + * appending events are logged; otherwise they are >>>> propagated to >>>>>>> + * the caller. Use true as the default. >>>>>>> + * @return The ConsoleAppender. >>>>>>> + */ >>>>>>> + @PluginFactory >>>>>>> + public static OutputStreamAppender createAppender(Layout<? >>>> extends Serializable> layout, final Filter filter, >>>>>>> + final OutputStream target, final String name, final >>>> boolean follow, final boolean ignore) { >>>>>>> + if (name == null) { >>>>>>> + LOGGER.error("No name provided for >> OutputStreamAppender"); >>>>>>> + return null; >>>>>>> + } >>>>>>> + if (layout == null) { >>>>>>> + layout = PatternLayout.createDefaultLayout(); >>>>>>> + } >>>>>>> + return new OutputStreamAppender(name, layout, filter, >>>> getManager(target, follow, layout), ignore, null); >>>>>>> + } >>>>>>> + >>>>>>> + private static OutputStreamManager getManager(final OutputStream >>>> target, final boolean follow, >>>>>>> + final Layout<? extends Serializable> layout) { >>>>>>> + final OutputStream os = target == null ? >>>> NullOutputStream.getInstance() : new CloseShieldOutputStream(target); >>>>>>> + final OutputStream targetRef = target == null ? os : target; >>>>>>> + final String managerName = targetRef.getClass().getName() + >>>> "@" + Integer.toHexString(targetRef.hashCode()) >>>>>>> + + '.' + follow; >>>>>>> + return OutputStreamManager.getManager(managerName, new >>>> FactoryData(os, managerName, layout), factory); >>>>>>> + } >>>>>>> + >>>>>>> + @PluginBuilderFactory >>>>>>> + public static <B extends Builder<B>> B newBuilder() { >>>>>>> + return new Builder<B>().asBuilder(); >>>>>>> + } >>>>>>> + >>>>>>> + private OutputStreamAppender(final String name, final Layout<? >>>> extends Serializable> layout, final Filter filter, >>>>>>> + final OutputStreamManager manager, final boolean >>>> ignoreExceptions, final Property[] properties) { >>>>>>> + super(name, layout, filter, ignoreExceptions, true, >>>> properties, manager); >>>>>>> + } >>>>>>> + >>>>>>> +} >>>>>>> diff --git >>>> >> a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java >>>> >> b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java >>>>>>> index 00af014..c1448bf 100644 >>>>>>> --- >>>> >> a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java >>>>>>> +++ >>>> >> b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java >>>>>>> @@ -1,108 +1,122 @@ >>>>>>> -/* >>>>>>> - * Licensed to the Apache Software Foundation (ASF) under one or >> more >>>>>>> - * contributor license agreements. See the NOTICE file distributed >>>> with >>>>>>> - * this work for additional information regarding copyright >> ownership. >>>>>>> - * The ASF licenses this file to You under the Apache license, >>>> Version 2.0 >>>>>>> - * (the "License"); you may not use this file except in compliance >>>> with >>>>>>> - * the License. You may obtain a copy of the License at >>>>>>> - * >>>>>>> - * http://www.apache.org/licenses/LICENSE-2.0 >>>>>>> - * >>>>>>> - * Unless required by applicable law or agreed to in writing, >> software >>>>>>> - * distributed under the License is distributed on an "AS IS" BASIS, >>>>>>> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>> implied. >>>>>>> - * See the license for the specific language governing permissions >> and >>>>>>> - * limitations under the license. >>>>>>> - */ >>>>>>> -package org.apache.logging.log4j.core.appender; >>>>>>> - >>>>>>> -import java.io.BufferedOutputStream; >>>>>>> -import java.io.ByteArrayOutputStream; >>>>>>> -import java.io.OutputStream; >>>>>>> -import java.sql.SQLException; >>>>>>> - >>>>>>> -import org.apache.logging.log4j.LogManager; >>>>>>> -import org.apache.logging.log4j.Logger; >>>>>>> -import org.apache.logging.log4j.core.Appender; >>>>>>> -import org.apache.logging.log4j.core.LoggerContext; >>>>>>> -import org.apache.logging.log4j.core.config.Configuration; >>>>>>> -import org.apache.logging.log4j.core.layout.PatternLayout; >>>>>>> -import org.junit.Assert; >>>>>>> -import org.junit.Rule; >>>>>>> -import org.junit.Test; >>>>>>> -import org.junit.rules.TestName; >>>>>>> - >>>>>>> -/** >>>>>>> - * Tests {@link OutputStreamAppender}. >>>>>>> - */ >>>>>>> -public class OutputStreamAppenderTest { >>>>>>> - >>>>>>> - private static final String TEST_MSG = "FOO ERROR"; >>>>>>> - >>>>>>> - @Rule >>>>>>> - public TestName testName = new TestName(); >>>>>>> - >>>>>>> - private String getName(final OutputStream out) { >>>>>>> - return out.getClass().getSimpleName() + "." + >>>> testName.getMethodName(); >>>>>>> - } >>>>>>> - >>>>>>> - /** >>>>>>> - * Tests that you can add an output stream appender dynamically. >>>>>>> - */ >>>>>>> - private void addAppender(final OutputStream outputStream, final >>>> String outputStreamName) { >>>>>>> - final LoggerContext context = >> LoggerContext.getContext(false); >>>>>>> - final Configuration config = context.getConfiguration(); >>>>>>> - final PatternLayout layout = >>>> PatternLayout.createDefaultLayout(config); >>>>>>> - final Appender appender = >>>> OutputStreamAppender.createAppender(layout, null, outputStream, >>>> outputStreamName, false, true); >>>>>>> - appender.start(); >>>>>>> - config.addAppender(appender); >>>>>>> - ConfigurationTestUtils.updateLoggers(appender, config); >>>>>>> - } >>>>>>> - >>>>>>> - @Test >>>>>>> - public void testOutputStreamAppenderToBufferedOutputStream() >>>> throws SQLException { >>>>>>> - final ByteArrayOutputStream out = new >> ByteArrayOutputStream(); >>>>>>> - final OutputStream os = new BufferedOutputStream(out); >>>>>>> - final String name = getName(out); >>>>>>> - final Logger logger = LogManager.getLogger(name); >>>>>>> - addAppender(os, name); >>>>>>> - logger.error(TEST_MSG); >>>>>>> - final String actual = out.toString(); >>>>>>> - Assert.assertTrue(actual, actual.contains(TEST_MSG)); >>>>>>> - } >>>>>>> - >>>>>>> - @Test >>>>>>> - public void testOutputStreamAppenderToByteArrayOutputStream() >>>> throws SQLException { >>>>>>> - final OutputStream out = new ByteArrayOutputStream(); >>>>>>> - final String name = getName(out); >>>>>>> - final Logger logger = LogManager.getLogger(name); >>>>>>> - addAppender(out, name); >>>>>>> - logger.error(TEST_MSG); >>>>>>> - final String actual = out.toString(); >>>>>>> - Assert.assertTrue(actual, actual.contains(TEST_MSG)); >>>>>>> - } >>>>>>> - >>>>>>> - /** >>>>>>> - * Validates that the code pattern we use to add an appender on >>>> the fly >>>>>>> - * works with a basic appender that is not the new OutputStream >>>> appender or >>>>>>> - * new Writer appender. >>>>>>> - */ >>>>>>> - @Test >>>>>>> - public void testUpdatePatternWithFileAppender() { >>>>>>> - final LoggerContext ctx = (LoggerContext) >>>> LogManager.getContext(false); >>>>>>> - final Configuration config = ctx.getConfiguration(); >>>>>>> - // @formatter:off >>>>>>> - final Appender appender = FileAppender.newBuilder() >>>>>>> - .withFileName("target/" + getClass().getName() + ".log") >>>>>>> - >> .withAppend(false).setName("File").setIgnoreExceptions(false) >>>>>>> - .withBufferedIo(false) >>>>>>> - .withBufferSize(4000) >>>>>>> - .setConfiguration(config) >>>>>>> - .build(); >>>>>>> - // @formatter:on >>>>>>> - appender.start(); >>>>>>> - config.addAppender(appender); >>>>>>> - ConfigurationTestUtils.updateLoggers(appender, config); >>>>>>> - LogManager.getLogger().error("FOO MSG"); >>>>>>> - } >>>>>>> -} >>>>>>> +/* >>>>>>> + * Licensed to the Apache Software Foundation (ASF) under one or >> more >>>>>>> + * contributor license agreements. See the NOTICE file distributed >>>> with >>>>>>> + * this work for additional information regarding copyright >> ownership. >>>>>>> + * The ASF licenses this file to You under the Apache license, >>>> Version 2.0 >>>>>>> + * (the "License"); you may not use this file except in compliance >>>> with >>>>>>> + * the License. You may obtain a copy of the License at >>>>>>> + * >>>>>>> + * http://www.apache.org/licenses/LICENSE-2.0 >>>>>>> + * >>>>>>> + * Unless required by applicable law or agreed to in writing, >> software >>>>>>> + * distributed under the License is distributed on an "AS IS" BASIS, >>>>>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or >>>> implied. >>>>>>> + * See the license for the specific language governing permissions >> and >>>>>>> + * limitations under the license. >>>>>>> + */ >>>>>>> +package org.apache.logging.log4j.core.appender; >>>>>>> + >>>>>>> +import java.io.BufferedOutputStream; >>>>>>> +import java.io.ByteArrayOutputStream; >>>>>>> +import java.io.OutputStream; >>>>>>> +import java.sql.SQLException; >>>>>>> + >>>>>>> +import org.apache.logging.log4j.LogManager; >>>>>>> +import org.apache.logging.log4j.Logger; >>>>>>> +import org.apache.logging.log4j.core.Appender; >>>>>>> +import org.apache.logging.log4j.core.LoggerContext; >>>>>>> +import org.apache.logging.log4j.core.config.Configuration; >>>>>>> +import org.apache.logging.log4j.core.filter.NoMarkerFilter; >>>>>>> +import org.apache.logging.log4j.core.layout.PatternLayout; >>>>>>> +import org.junit.Assert; >>>>>>> +import org.junit.Rule; >>>>>>> +import org.junit.Test; >>>>>>> +import org.junit.rules.TestName; >>>>>>> + >>>>>>> +/** >>>>>>> + * Tests {@link OutputStreamAppender}. >>>>>>> + */ >>>>>>> +public class OutputStreamAppenderTest { >>>>>>> + >>>>>>> + private static final String TEST_MSG = "FOO ERROR"; >>>>>>> + >>>>>>> + @Rule >>>>>>> + public TestName testName = new TestName(); >>>>>>> + >>>>>>> + private String getName(final OutputStream out) { >>>>>>> + return out.getClass().getSimpleName() + "." + >>>> testName.getMethodName(); >>>>>>> + } >>>>>>> + >>>>>>> + /** >>>>>>> + * Tests that you can add an output stream appender dynamically. >>>>>>> + */ >>>>>>> + private void addAppender(final OutputStream outputStream, final >>>> String outputStreamName) { >>>>>>> + final LoggerContext context = >> LoggerContext.getContext(false); >>>>>>> + final Configuration config = context.getConfiguration(); >>>>>>> + final PatternLayout layout = >>>> PatternLayout.createDefaultLayout(config); >>>>>>> + final Appender appender = >>>> OutputStreamAppender.createAppender(layout, null, outputStream, >>>> outputStreamName, false, true); >>>>>>> + appender.start(); >>>>>>> + config.addAppender(appender); >>>>>>> + ConfigurationTestUtils.updateLoggers(appender, config); >>>>>>> + } >>>>>>> + >>>>>>> + @Test >>>>>>> + public void testBuildFilter() { >>>>>>> + final NoMarkerFilter filter = >>>> NoMarkerFilter.newBuilder().build(); >>>>>>> + // @formatter:off >>>>>>> + final OutputStreamAppender.Builder builder = >>>> OutputStreamAppender.newBuilder() >>>>>>> + .setName("test") >>>>>>> + .setFilter(filter); >>>>>>> + // @formatter:on >>>>>>> + Assert.assertEquals(filter, builder.getFilter()); >>>>>>> + final OutputStreamAppender appender = builder.build(); >>>>>>> + Assert.assertEquals(filter, appender.getFilter()); >>>>>>> + } >>>>>>> + >>>>>>> + @Test >>>>>>> + public void testOutputStreamAppenderToBufferedOutputStream() >>>> throws SQLException { >>>>>>> + final ByteArrayOutputStream out = new >> ByteArrayOutputStream(); >>>>>>> + final OutputStream os = new BufferedOutputStream(out); >>>>>>> + final String name = getName(out); >>>>>>> + final Logger logger = LogManager.getLogger(name); >>>>>>> + addAppender(os, name); >>>>>>> + logger.error(TEST_MSG); >>>>>>> + final String actual = out.toString(); >>>>>>> + Assert.assertTrue(actual, actual.contains(TEST_MSG)); >>>>>>> + } >>>>>>> + >>>>>>> + @Test >>>>>>> + public void testOutputStreamAppenderToByteArrayOutputStream() >>>> throws SQLException { >>>>>>> + final OutputStream out = new ByteArrayOutputStream(); >>>>>>> + final String name = getName(out); >>>>>>> + final Logger logger = LogManager.getLogger(name); >>>>>>> + addAppender(out, name); >>>>>>> + logger.error(TEST_MSG); >>>>>>> + final String actual = out.toString(); >>>>>>> + Assert.assertTrue(actual, actual.contains(TEST_MSG)); >>>>>>> + } >>>>>>> + >>>>>>> + /** >>>>>>> + * Validates that the code pattern we use to add an appender on >>>> the fly >>>>>>> + * works with a basic appender that is not the new OutputStream >>>> appender or >>>>>>> + * new Writer appender. >>>>>>> + */ >>>>>>> + @Test >>>>>>> + public void testUpdatePatternWithFileAppender() { >>>>>>> + final LoggerContext ctx = (LoggerContext) >>>> LogManager.getContext(false); >>>>>>> + final Configuration config = ctx.getConfiguration(); >>>>>>> + // @formatter:off >>>>>>> + final Appender appender = FileAppender.newBuilder() >>>>>>> + .withFileName("target/" + getClass().getName() + ".log") >>>>>>> + >> .withAppend(false).setName("File").setIgnoreExceptions(false) >>>>>>> + .withBufferedIo(false) >>>>>>> + .withBufferSize(4000) >>>>>>> + .setConfiguration(config) >>>>>>> + .build(); >>>>>>> + // @formatter:on >>>>>>> + appender.start(); >>>>>>> + config.addAppender(appender); >>>>>>> + ConfigurationTestUtils.updateLoggers(appender, config); >>>>>>> + LogManager.getLogger().error("FOO MSG"); >>>>>>> + } >>>>>>> +} >>>>>>> diff --git a/src/changes/changes.xml b/src/changes/changes.xml >>>>>>> index c3483bd..a9ec160 100644 >>>>>>> --- a/src/changes/changes.xml >>>>>>> +++ b/src/changes/changes.xml >>>>>>> @@ -33,6 +33,9 @@ >>>>>>> <action issue="LOG4J2-2639" dev="rgoers" type="add"> >>>>>>> Add builder pattern to Logger interface. >>>>>>> </action> >>>>>>> + <action issue="LOG4J2-2673" dev="ggregory" type="fix" >>>> due-to="Yuichi Sugimura, Gary Gregory"> >>>>>>> + OutputStreamAppender.Builder ignores setFilter(). >>>>>>> + </action> >>>>>>> </release> >>>>>>> <release version="2.12.1" date="2019-08-06" description="GA Release >>>> 2.12.1"> >>>>>>> <action issue="LOG4J2-1946" dev="rgoers" type="fix" due-to="Igor >>>> Perelyotov"> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>> >> >> >>
