-
Notifications
You must be signed in to change notification settings - Fork 291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Throwable capturing fields support for JDK16+ #7047
Conversation
Since JDK16 it's not possible to extract values by reflection for JDK modules without adding `--add-opens=java.base/java.lang=ALL-UNNAMED` so when capturing an exception (like in @exception) we are not allowed to capture fields like detailMessage, cause, stacktrace which can be valuable to troubleshoot. We introduce in WellKnownClasses the mechanism to fetch fields through dedicated call to getter for registered classes. In the special case of Throwable we are allowing any inherited classes to capture the Throwable fields as well as custom fields. Though to capture Throwable fields (like detailMessage) we need to call getter that could be overridden. Hence we are checking before calling them that they are not overridden by checking the declaring class of the getter. Add option in build to not allow reflection access for debugger tests to assess that we can access correctly even for recent JDKs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we please add tests to verify that all this works?
if (specialTypeAccess != null) { | ||
return specialTypeAccess; | ||
} | ||
if (value instanceof Throwable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend add support here for Optional with a single member and reduce some code. they doing the same logic with if type == X and member == Y return the value.
If this is the case we can just live specialTypeAccess logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
public static final String BECAUSE_OVERRIDDEN = | ||
"Special access method not safe to be called because overridden"; | ||
|
||
public static CapturedContext.CapturedValue detailMessage(Object o) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe refactor this.
private static captureValueIfNotOverridden(Object o, string method, string field, string type, callback callback) {
if (isOverridden(o, method, Throwable.class)) {
return CapturedContext.CapturedValue.notCapturedReason(field, type, BECAUSE_OVERRIDDEN);
}
return CapturedContext.CapturedValue.of(field, type, callback());
}
}
then every function can be a single line:
captureValueIfNotOverridden(o, "getMessage", "detailMessage", String.class.getTypeName(), () => ((Throwable) o).getMessage());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. a little more complex than what you suggest :)
refactor captureifOverridden
What Does This Do
We introduce in
WellKnownClasses
the mechanism to fetch fields through dedicated call to getter for registered classes.In the special case of
Throwable
we are allowing any inherited classes to capture theThrowable
fields as well as custom fields. Though, to captureThrowable
fields (likedetailMessage
) we need to call getter that could be overridden. Hence ,we are checking before calling them that they are not overridden by checking the declaring class of the getter.Add option in build to not allow reflection access for debugger tests to assess that we can access correctly even for recent JDKs
Motivation
Since JDK16 it's not possible to extract values by reflection for JDK modules without adding
--add-opens=java.base/java.lang=ALL-UNNAMED
so when capturing an exception (like in@exception
) we are not allowed to capture fields likedetailMessage
,cause
,stacktrace
which can be valuable to troubleshoot.Additional Notes
Results:
Jira ticket: DEBUG-2389