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">
>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>> 
>> 
>> 
>> 


Reply via email to