log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java [128:359]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        @Override
        public JmsManager createManager(final String name, final JmsManagerConfiguration data) {
            if (JndiManager.isJndiJmsEnabled()) {
                try {
                    return new JmsManager(name, data);
                } catch (final Exception e) {
                    logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
                    return null;
                }
            }
            logger().error("JNDI must be enabled by setting log4j2.enableJndiJms=true");
            return null;
        }
    }

    /**
     * Handles reconnecting to JMS on a Thread.
     */
    private final class Reconnector extends Log4jThread {

        private final CountDownLatch latch = new CountDownLatch(1);

        private volatile boolean shutdown;

        private final Object owner;

        private Reconnector(final Object owner) {
            super("JmsManager-Reconnector");
            this.owner = owner;
        }

        public void latch() {
            try {
                latch.await();
            } catch (final InterruptedException ex) {
                // Ignore the exception.
            }
        }

        void reconnect() throws NamingException, JMSException {
            final JndiManager jndiManager2 = getJndiManager();
            final Connection connection2 = createConnection(jndiManager2);
            final Session session2 = createSession(connection2);
            final Destination destination2 = createDestination(jndiManager2);
            final MessageProducer messageProducer2 = createMessageProducer(session2, destination2);
            connection2.start();
            synchronized (owner) {
                jndiManager = jndiManager2;
                connection = connection2;
                session = session2;
                destination = destination2;
                messageProducer = messageProducer2;
                reconnector = null;
                shutdown = true;
            }
            logger().debug("Connection reestablished to {}", configuration);
        }

        @Override
        public void run() {
            while (!shutdown) {
                try {
                    sleep(configuration.getReconnectIntervalMillis());
                    reconnect();
                } catch (final InterruptedException | JMSException | NamingException e) {
                    logger().debug(
                                    "Cannot reestablish JMS connection to {}: {}",
                                    configuration,
                                    e.getLocalizedMessage(),
                                    e);
                } finally {
                    latch.countDown();
                }
            }
        }

        public void shutdown() {
            shutdown = true;
        }
    }

    static final JmsManagerFactory FACTORY = new JmsManagerFactory();

    /**
     * Gets a JmsManager using the specified configuration parameters.
     *
     * @param name
     *            The name to use for this JmsManager.
     * @param connectionFactoryName
     *            The binding name for the {@link javax.jms.ConnectionFactory}.
     * @param destinationName
     *            The binding name for the {@link javax.jms.Destination}.
     * @param userName
     *            The userName to connect with or {@code null} for no authentication.
     * @param password
     *            The password to use with the given userName or {@code null} for no authentication.
     * @param immediateFail
     *            Whether or not to fail immediately with a {@link AppenderLoggingException} when connecting to JMS
     *            fails.
     * @param reconnectIntervalMillis
     *            How to log sleep in milliseconds before trying to reconnect to JMS.
     * @param jndiProperties
     *            JNDI properties.
     * @return The JmsManager as configured.
     */
    public static JmsManager getJmsManager(
            final String name,
            final Properties jndiProperties,
            final String connectionFactoryName,
            final String destinationName,
            final String userName,
            final char[] password,
            final boolean immediateFail,
            final long reconnectIntervalMillis) {
        final JmsManagerConfiguration configuration = new JmsManagerConfiguration(
                jndiProperties,
                connectionFactoryName,
                destinationName,
                userName,
                password,
                immediateFail,
                reconnectIntervalMillis);
        return getManager(name, FACTORY, configuration);
    }

    private final JmsManagerConfiguration configuration;

    private volatile Reconnector reconnector;
    private volatile JndiManager jndiManager;
    private volatile Connection connection;
    private volatile Session session;
    private volatile Destination destination;
    private volatile MessageProducer messageProducer;

    private JmsManager(final String name, final JmsManagerConfiguration configuration) {
        super(null, name);
        this.configuration = configuration;
        this.jndiManager = configuration.getJndiManager();
        try {
            this.connection = createConnection(this.jndiManager);
            this.session = createSession(this.connection);
            this.destination = createDestination(this.jndiManager);
            this.messageProducer = createMessageProducer(this.session, this.destination);
            this.connection.start();
        } catch (NamingException | JMSException e) {
            this.reconnector = createReconnector();
            this.reconnector.start();
        }
    }

    private boolean closeConnection() {
        if (connection == null) {
            return true;
        }
        final Connection temp = connection;
        connection = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS Connection: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private boolean closeJndiManager() {
        if (jndiManager == null) {
            return true;
        }
        final JndiManager tmp = jndiManager;
        jndiManager = null;
        tmp.close();
        return true;
    }

    private boolean closeMessageProducer() {
        if (messageProducer == null) {
            return true;
        }
        final MessageProducer temp = messageProducer;
        messageProducer = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS MessageProducer: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private boolean closeSession() {
        if (session == null) {
            return true;
        }
        final Session temp = session;
        session = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS Session: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private Connection createConnection(final JndiManager jndiManager) throws NamingException, JMSException {
        final ConnectionFactory connectionFactory = jndiManager.lookup(configuration.getConnectionFactoryName());
        if (configuration.getUserName() != null && configuration.getPassword() != null) {
            return connectionFactory.createConnection(
                    configuration.getUserName(),
                    configuration.getPassword() == null ? null : String.valueOf(configuration.getPassword()));
        }
        return connectionFactory.createConnection();
    }

    private Destination createDestination(final JndiManager jndiManager) throws NamingException {
        return jndiManager.lookup(configuration.getDestinationName());
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



log4j-jakarta-jms/src/main/java/org/apache/logging/log4j/core/appender/mom/jakarta/JmsManager.java [125:356]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        @Override
        public JmsManager createManager(final String name, final JmsManagerConfiguration data) {
            if (JndiManager.isJndiJmsEnabled()) {
                try {
                    return new JmsManager(name, data);
                } catch (final Exception e) {
                    logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
                    return null;
                }
            }
            logger().error("JNDI must be enabled by setting log4j2.enableJndiJms=true");
            return null;
        }
    }

    /**
     * Handles reconnecting to JMS on a Thread.
     */
    private final class Reconnector extends Log4jThread {

        private final CountDownLatch latch = new CountDownLatch(1);

        private volatile boolean shutdown;

        private final Object owner;

        private Reconnector(final Object owner) {
            super("JmsManager-Reconnector");
            this.owner = owner;
        }

        public void latch() {
            try {
                latch.await();
            } catch (final InterruptedException ex) {
                // Ignore the exception.
            }
        }

        void reconnect() throws NamingException, JMSException {
            final JndiManager jndiManager2 = getJndiManager();
            final Connection connection2 = createConnection(jndiManager2);
            final Session session2 = createSession(connection2);
            final Destination destination2 = createDestination(jndiManager2);
            final MessageProducer messageProducer2 = createMessageProducer(session2, destination2);
            connection2.start();
            synchronized (owner) {
                jndiManager = jndiManager2;
                connection = connection2;
                session = session2;
                destination = destination2;
                messageProducer = messageProducer2;
                reconnector = null;
                shutdown = true;
            }
            logger().debug("Connection reestablished to {}", configuration);
        }

        @Override
        public void run() {
            while (!shutdown) {
                try {
                    sleep(configuration.getReconnectIntervalMillis());
                    reconnect();
                } catch (final InterruptedException | JMSException | NamingException e) {
                    logger().debug(
                                    "Cannot reestablish JMS connection to {}: {}",
                                    configuration,
                                    e.getLocalizedMessage(),
                                    e);
                } finally {
                    latch.countDown();
                }
            }
        }

        public void shutdown() {
            shutdown = true;
        }
    }

    static final JmsManagerFactory FACTORY = new JmsManagerFactory();

    /**
     * Gets a JmsManager using the specified configuration parameters.
     *
     * @param name
     *            The name to use for this JmsManager.
     * @param connectionFactoryName
     *            The binding name for the {@link javax.jms.ConnectionFactory}.
     * @param destinationName
     *            The binding name for the {@link javax.jms.Destination}.
     * @param userName
     *            The userName to connect with or {@code null} for no authentication.
     * @param password
     *            The password to use with the given userName or {@code null} for no authentication.
     * @param immediateFail
     *            Whether or not to fail immediately with a {@link AppenderLoggingException} when connecting to JMS
     *            fails.
     * @param reconnectIntervalMillis
     *            How to log sleep in milliseconds before trying to reconnect to JMS.
     * @param jndiProperties
     *            JNDI properties.
     * @return The JmsManager as configured.
     */
    public static JmsManager getJmsManager(
            final String name,
            final Properties jndiProperties,
            final String connectionFactoryName,
            final String destinationName,
            final String userName,
            final char[] password,
            final boolean immediateFail,
            final long reconnectIntervalMillis) {
        final JmsManagerConfiguration configuration = new JmsManagerConfiguration(
                jndiProperties,
                connectionFactoryName,
                destinationName,
                userName,
                password,
                immediateFail,
                reconnectIntervalMillis);
        return getManager(name, FACTORY, configuration);
    }

    private final JmsManagerConfiguration configuration;

    private volatile Reconnector reconnector;
    private volatile JndiManager jndiManager;
    private volatile Connection connection;
    private volatile Session session;
    private volatile Destination destination;
    private volatile MessageProducer messageProducer;

    private JmsManager(final String name, final JmsManagerConfiguration configuration) {
        super(null, name);
        this.configuration = configuration;
        this.jndiManager = configuration.getJndiManager();
        try {
            this.connection = createConnection(this.jndiManager);
            this.session = createSession(this.connection);
            this.destination = createDestination(this.jndiManager);
            this.messageProducer = createMessageProducer(this.session, this.destination);
            this.connection.start();
        } catch (NamingException | JMSException e) {
            this.reconnector = createReconnector();
            this.reconnector.start();
        }
    }

    private boolean closeConnection() {
        if (connection == null) {
            return true;
        }
        final Connection temp = connection;
        connection = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS Connection: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private boolean closeJndiManager() {
        if (jndiManager == null) {
            return true;
        }
        final JndiManager tmp = jndiManager;
        jndiManager = null;
        tmp.close();
        return true;
    }

    private boolean closeMessageProducer() {
        if (messageProducer == null) {
            return true;
        }
        final MessageProducer temp = messageProducer;
        messageProducer = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS MessageProducer: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private boolean closeSession() {
        if (session == null) {
            return true;
        }
        final Session temp = session;
        session = null;
        try {
            temp.close();
            return true;
        } catch (final JMSException e) {
            StatusLogger.getLogger()
                    .debug(
                            "Caught exception closing JMS Session: {} ({}); continuing JMS manager shutdown",
                            e.getLocalizedMessage(),
                            temp,
                            e);
            return false;
        }
    }

    private Connection createConnection(final JndiManager jndiManager) throws NamingException, JMSException {
        final ConnectionFactory connectionFactory = jndiManager.lookup(configuration.getConnectionFactoryName());
        if (configuration.getUserName() != null && configuration.getPassword() != null) {
            return connectionFactory.createConnection(
                    configuration.getUserName(),
                    configuration.getPassword() == null ? null : String.valueOf(configuration.getPassword()));
        }
        return connectionFactory.createConnection();
    }

    private Destination createDestination(final JndiManager jndiManager) throws NamingException {
        return jndiManager.lookup(configuration.getDestinationName());
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



