Description
ThrowableAttributeConverter (log4j-jpa) cannot round-trip a Throwable whose message contains line breaks.
convertToDatabaseColumn writes Throwable.toString() verbatim, one stack trace frame per line.
convertToEntityAttribute splits the column on line breaks and interprets it by line prefix:
- any line starting with
Caused by starts a new cause, whose class is loaded by name;
- every other line is parsed as a stack trace frame by
StackTraceElementAttributeConverter.
Since exception messages are arbitrary text, a message such as
first line
Caused by com.example.SomeClass: second line
is read back as a cause of type com.example.SomeClass, and other lines make the frame parser throw.
Moreover, getThrowable loads the class with LoaderUtil.loadClass, which initializes it
before checking that it is a Throwable subclass.
Expected behavior:
convertToDatabaseColumn escapes line breaks in the message (and convertToEntityAttribute unescapes them),
so the column layout does not depend on the message content.
getThrowable loads the class without initializing it (Class.forName(name, false, loader))
and checks Throwable.class.isAssignableFrom before instantiating it.
- A line that cannot be parsed as a stack trace frame does not fail the whole conversion.
Configuration
Version: 2.26.1 (and 2.x at d631e82)
Operating system: any
JDK: any
Logs
A message line that is neither a frame nor a Caused by line makes
StackTraceElementAttributeConverter.convertString fail with a StringIndexOutOfBoundsException.
Reproduction
@Test
void messageWithLineBreaksRoundTrips() {
final ThrowableAttributeConverter converter = new ThrowableAttributeConverter();
final Throwable original = new IllegalStateException("first line\nCaused by java.lang.Error: second line");
final Throwable restored = converter.convertToEntityAttribute(converter.convertToDatabaseColumn(original));
assertThat(restored).isInstanceOf(IllegalStateException.class);
assertThat(restored.getMessage()).isEqualTo(original.getMessage());
assertThat(restored.getCause()).isNull();
}
Description
ThrowableAttributeConverter(log4j-jpa) cannot round-trip aThrowablewhose message contains line breaks.convertToDatabaseColumnwritesThrowable.toString()verbatim, one stack trace frame per line.convertToEntityAttributesplits the column on line breaks and interprets it by line prefix:Caused bystarts a new cause, whose class is loaded by name;StackTraceElementAttributeConverter.Since exception messages are arbitrary text, a message such as
is read back as a cause of type
com.example.SomeClass, and other lines make the frame parser throw.Moreover,
getThrowableloads the class withLoaderUtil.loadClass, which initializes itbefore checking that it is a
Throwablesubclass.Expected behavior:
convertToDatabaseColumnescapes line breaks in the message (andconvertToEntityAttributeunescapes them),so the column layout does not depend on the message content.
getThrowableloads the class without initializing it (Class.forName(name, false, loader))and checks
Throwable.class.isAssignableFrombefore instantiating it.Configuration
Version: 2.26.1 (and
2.xatd631e82)Operating system: any
JDK: any
Logs
A message line that is neither a frame nor a
Caused byline makesStackTraceElementAttributeConverter.convertStringfail with aStringIndexOutOfBoundsException.Reproduction