fix: null-check LoggerDynamicMBean addAppender and AppenderDynamicMBean setLayout - #4185
fix: null-check LoggerDynamicMBean addAppender and AppenderDynamicMBean setLayout#4185SebTardif wants to merge 9 commits into
Conversation
OptionConverter.instantiateByClassName returns null when the class is missing or not an Appender. addAppender immediately called setName and NPE'd on invalid JMX addAppender class names. Skip attach and log an error instead.
|
@SebTardif Thank you for catching and fixing this NPE. This is your 4th PR, and we truly appreciate your ongoing support. If possible, could you consider picking up some items from the issue list? That would be incredibly helpful for our team. Of course, please continue submitting fixes for NPEs and other issues as you find them—they are always welcome. I will aim to review and close this PR this weekend. |
OptionConverter.instantiateByClassName returns null when the class is missing or not a Layout. setLayout immediately called appender.setLayout and could NPE on invalid JMX setLayout class names. Log an error and skip attach instead. Sibling of the LoggerDynamicMBean.addAppender guard (apache#4185). Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Folded from closed apache#4219 per review request; both JMX null-guards ship here. Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
|
@ramanathan1504 Folded the AppenderDynamicMBean Local check: export JAVA_HOME=$(/usr/libexec/java_home -v 17)
./mvnw -pl log4j-1.2-api -am test \
-Dtest=LoggerDynamicMBeanTest,AppenderDynamicMBeanTest \
-Dsurefire.failIfNoSpecifiedTests=falseAll 4 tests pass. Ready for re-review when convenient. |
Because of added related code from #4219, so need to review again
ramanathan1504
left a comment
There was a problem hiding this comment.
One question before I re-approve: setLayout returns the string
"Could not instantiate layout class." from invoke(). A JMX client cannot
tell that apart from a successful result — should it throw an MBeanException
instead, or is returning a diagnostic string the established convention for this
MBean? Happy either way, I just want it to be deliberate.
Returning a diagnostic string from a void-declared JMX operation is easy for clients to treat as success. Throw MBeanException with an IllegalArgumentException target instead so failure is unambiguous, while still logging the error. Update the regression test to assert MBeanException. Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Good catch. I looked at the package conventions and chose throw
Pushed in Note (out of scope for this PR): Local verification: export JAVA_HOME=$(/usr/libexec/java_home -v 17)
./mvnw -pl log4j-1.2-api -am test \
-Dtest=LoggerDynamicMBeanTest,AppenderDynamicMBeanTest \
-Dsurefire.failIfNoSpecifiedTests=falseAll 4 tests pass. Ready for re-approve when convenient. Thanks again for the careful review. |
… MBeanException for invalid class names
ramanathan1504
left a comment
There was a problem hiding this comment.
Thanks @SebTardif. I pushed two commits on top: addAppender now throws MBeanException like setLayout so both sites fail the same way, and the tests go through mbean.invoke(...) with a registered MBeanServer so the success path is actually exercised. Changelog consolidated into one entry.
LGTM — Only thing left: the description still says "log an error and skip attach", could you update it to match?
|
@ramanathan1504 Updated the PR description to match the tip: both sites log and throw |
vy
left a comment
There was a problem hiding this comment.
LGTM, dropped some minor remarks.
@SebTardif, @ramanathan1504, great work! Thanks so much!
- Drop redundant assertNotNull beside assertInstanceOf in AppenderDynamicMBeanTest (assertInstanceOf already fails on null). - Register LoggerDynamicMBean with MBeanServer before invoke, same pattern as AppenderDynamicMBeanTest / HierarchyDynamicMBean naming.
|
@vy Follow-ups from your review are on the tip (
Could you take another look when you have a moment? |
What Problem This Solves
log4j-1.2-api JMX helpers call
OptionConverter.instantiateByClassName(..., null)and immediately use the result. When the class name is invalid or not the expected type, instantiation returnsnulland the next line NPEs. That surfaces through JMX operations with a bad class name.Two sibling sites:
LoggerDynamicMBean.addAppender→ NPE onappender.setName(...)AppenderDynamicMBean.setLayout→ NPE onappender.setLayout(...)(folded from closed fix: null-check AppenderDynamicMBean setLayout instantiation #4219)Failure scenario
Fix
Null-check after instantiation. On failure, log via
cat.error(...)and throwMBeanExceptionwrappingIllegalArgumentExceptionso JMX clients get a clear operation failure (void operations already returnnullon success; a free-form diagnostic string is not a reliable client signal).Both
addAppenderandsetLayoutuse the same fail-closed path. Regression tests exercise the operations throughmbean.invoke(...)on a registeredMBeanServer, including the success path.Tests
invokefails withMBeanException; appender/layout remains unsetConsoleAppender/PatternLayout: object attached via registered MBeanServer invokeSibling audit
registerLayoutMBean: already null-safeinstantiateByClassName+ immediate dereference inlog4j-1.2-apiJMX packageChangelog
Consolidated into one entry under
src/changelog/.2.x.x/, linked to this PR (#4185).Note
#4219 carried only the AppenderDynamicMBean half and was closed with a request to fold into this PR. Done in follow-up commits on this branch.