[
https://issues.apache.org/jira/browse/LOG4J2-3680?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Piotr Karwasz resolved LOG4J2-3680.
-----------------------------------
Fix Version/s: 2.23.0
Resolution: Fixed
[~peterdm],
Can you check if the newest snapshot in the Maven repo
{{https://repository.apache.org/snapshots}} fixes your problem?
If it does, please close the issue.
> Some log events are no longer serialized correctly
> --------------------------------------------------
>
> Key: LOG4J2-3680
> URL: https://issues.apache.org/jira/browse/LOG4J2-3680
> Project: Log4j 2
> Issue Type: Bug
> Components: Core
> Affects Versions: 2.22.0
> Reporter: Peter De Maeyer
> Assignee: Piotr Karwasz
> Priority: Major
> Fix For: 2.23.0
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> We noticed a regression between 2.21.1 and 2.22.0 in the serilialization of
> log events. The below test succeeds with 2.21.1, but fails with 2.22.0. I had
> a look at the source code, and I think it's because of changes in the
> {{ObjectMessage.read/writeObject}} implementation.
> {code:java}
> import static org.apache.logging.log4j.LogManager.getLogger;
> import static org.junit.jupiter.api.Assertions.assertEquals;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.IOException;
> import java.io.ObjectInputStream;
> import java.io.ObjectOutputStream;
> import java.io.Serializable;
> import java.util.ArrayList;
> import java.util.List;
> import org.apache.logging.log4j.core.Appender;
> import org.apache.logging.log4j.core.ErrorHandler;
> import org.apache.logging.log4j.core.Layout;
> import org.apache.logging.log4j.core.LogEvent;
> import org.apache.logging.log4j.core.Logger;
> import org.junit.jupiter.api.AfterEach;
> import org.junit.jupiter.api.BeforeEach;
> import org.junit.jupiter.api.Test;
> class Log4jSerializationTest {
> private final Logger logger = (Logger)
> getLogger(Log4jSerializationTest.class);
> private final RecordingAppender appender = new
> RecordingAppender(Log4jSerializationTest.class.getName());
> @BeforeEach
> void addRecordingAppender() {
> appender.start();
> logger.addAppender(appender);
> }
> @AfterEach
> void removeRecordingAppender() {
> logger.removeAppender(appender);
> appender.stop();
> }
> @Test
> void logEventSerialization() {
> RuntimeException exception = new RuntimeException("induced by test");
> logger.error(exception, exception);
> LogEvent event = appender.getEvents().get(0);
> assertEquals(RuntimeException.class.getName() + ": induced by test",
> event.getMessage().getFormattedMessage());
> }
> static class RecordingAppender implements Appender {
> private final List<LogEvent> events = new ArrayList();
> private State state = State.STOPPED;
> private final String name;
> private ErrorHandler handler;
> public RecordingAppender(String name) {
> this.name = name;
> }
> @Override
> public State getState() {
> return state;
> }
> @Override
> public void initialize() {
> state = State.INITIALIZED;
> }
> @Override
> public boolean isStarted() {
> return state == State.STARTED;
> }
> @Override
> public boolean isStopped() {
> return !isStarted();
> }
> @Override
> public void start() {
> events.clear();
> state = State.STARTED;
> }
> @Override
> public void stop() {
> events.clear();
> state = State.STOPPED;
> }
> @Override
> public synchronized void append(LogEvent event) {
> // The event is a mutable one, Log4j2 emits the same event
> instance but changes the message each time.
> // If we want to hold on to the event details, we need to clone
> the event.
> // LogEvent is not an instance of Cloneable, but it IS an
> instance of Serializable.
> // So we clone by serializing and deserializing.
> ByteArrayOutputStream out = new ByteArrayOutputStream();
> try (ObjectOutputStream objectOut = new ObjectOutputStream(out)) {
> objectOut.writeObject(event);
> } catch (IOException e) {
> throw new RuntimeException(e);
> }
> LogEvent clone;
> try (ObjectInputStream objectInput = new ObjectInputStream(new
> ByteArrayInputStream(out.toByteArray()))) {
> clone = (LogEvent) objectInput.readObject();
> } catch (IOException | ClassNotFoundException e) {
> throw new RuntimeException(e);
> }
> events.add(clone);
> }
> @Override
> public ErrorHandler getHandler() {
> return handler;
> }
> @Override
> public Layout<? extends Serializable> getLayout() {
> return null;
> }
> @Override
> public String getName() {
> return name;
> }
> @Override
> public boolean ignoreExceptions() {
> return true;
> }
> @Override
> public void setHandler(ErrorHandler handler) {
> this.handler = handler;
> }
> public synchronized List<LogEvent> getEvents() {
> return events;
> }
> }
> }
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)