/*
 * 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.mom.activemq;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import org.apache.activemq.jndi.ActiveMQInitialContextFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.categories.Appenders;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.mom.JmsAppender;
import org.apache.logging.log4j.core.appender.mom.JmsManager;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.layout.SerializedLayout;
import org.apache.logging.log4j.core.net.JndiManager;
import org.apache.logging.log4j.message.SimpleMessage;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import static org.junit.Assert.*;

/**
 * Integration test for JmsAppender using an embedded ActiveMQ broker.
 */
@Category(Appenders.Jms.class)
public class JmsAppenderIT {

    private static final String KEY_SERIALIZABLE_PACKAGES = "org.apache.activemq.SERIALIZABLE_PACKAGES";

    private static JmsManager jmsManager;

    private JmsAppender appender;

    @BeforeClass
    public static void setUpClass() {
        System.setProperty(KEY_SERIALIZABLE_PACKAGES,
                "org.apache.logging.log4j.core.impl,org.apache.logging.log4j.util,org.apache.logging.log4j");
        final Properties additional = new Properties();
        additional.setProperty("queue.TestQueue", "TestQueue");
        final JndiManager jndiManager = JndiManager.getJndiManager(ActiveMQInitialContextFactory.class.getName(),
            "vm://localhost?broker.persistent=false", null, null, null, additional);
        jmsManager = JmsManager.getJmsManager("JmsManager", jndiManager, "ConnectionFactory", "TestQueue", null, null);
    }

    @AfterClass
    public static void tearDownClass() {
        jmsManager.close();
        System.getProperties().remove(KEY_SERIALIZABLE_PACKAGES);
    }

    @Before
    public void setUp() throws Exception {
        // @formatter:off
        appender = JmsAppender.newBuilder().
            setName("JmsAppender").
            setLayout(SerializedLayout.createLayout()).
            setIgnoreExceptions(true).
            setJmsManager(jmsManager).
            build();
        // @formatter:off
        appender.start();
    }

    @Test
    public void testLogToQueue() throws Exception {
        final int messageCount = 100;
        final MessageConsumer messageConsumer = jmsManager.createMessageConsumer();
        final JmsQueueConsumer consumer = new JmsQueueConsumer(messageCount);
        messageConsumer.setMessageListener(consumer);
        final String messageText = "Hello, World!";
        final String loggerName = this.getClass().getName();
        for (int i = 0; i < messageCount; i++) {
            final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName(loggerName) //
                    .setLoggerFqcn(loggerName).setLevel(Level.INFO) //
                    .setMessage(new SimpleMessage(messageText)).setThreadName(Thread.currentThread().getName()) //
                    .setTimeMillis(System.currentTimeMillis()).build();
            appender.append(event);
        }
        consumer.awaitAndAssertAllMessagesConsumed();
    }

    private static class JmsQueueConsumer implements MessageListener {

        private final int messageCount;
        private final CountDownLatch countDownLatch;
        private final Collection<LogEvent> events;

        private JmsQueueConsumer(final int messageCount) {
            this.messageCount = messageCount;
            this.countDownLatch = new CountDownLatch(messageCount);
            this.events = new ArrayList<>(messageCount);
        }

        @Override
        public void onMessage(final Message message) {
            try {
                consume((ObjectMessage) message);
            } catch (final JMSException e) {
                e.printStackTrace();
            }
        }

        private void consume(final ObjectMessage message) throws JMSException {
            try {
                final LogEvent event = (LogEvent) message.getObject();
                events.add(event);
            } finally {
                countDownLatch.countDown();
            }
        }

        public void awaitAndAssertAllMessagesConsumed() throws InterruptedException {
            countDownLatch.await(5, TimeUnit.SECONDS);
            assertEquals(messageCount, events.size());
        }
    }
}

@@ -2472,16 +2472,25 @@
 ng.log4j
+,java.rmi
 %22);%0A    

Add java.rmi to org.apache.activemq.SERIALIZABLE_PACKAGES to pass the test.