Skip to content
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

getBuildCauses(...) performs safer checks for determining if the specified cause type is a subclass of the current build Cause #83

Closed
wants to merge 2 commits into from

Conversation

mikecirioli
Copy link
Contributor

@mikecirioli mikecirioli commented Dec 6, 2018

getBuildCauses(...) now uses the uber classloader so that classes provided by other extension points can be found. Also provides sane error handling when a CNF exception does happen (logs a warning and returns an empty JSONArray)

Removed the use of class loading altogether in favor of doing direct comparisons against class names, recursively checking parent class. Feedback appreciated if there is a better way to handle inner$classes

provided by other extension points can be found.  Also provides sane error
handling when a CNF exception does happen (logs a warning and returns an
empty JSONArray)
@mikecirioli
Copy link
Contributor Author

@jtnord @svanoort @jglick

private boolean isClassOrSubclass(Class<?> clazz, String classNameToCheck) {
String causeClassName = clazz.getName();
if (causeClassName.equals("java.lang.Object")) {
return false;
Copy link
Member

@jtnord jtnord Dec 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return causeClassName.equals(classNameToCheck) incase the user enters "java.lang.Object")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also to exit the recursion...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object.class.getSuperclass will return null, so maybe easier to use that as the base case and handle Object with the next if just like other classes.

} else if (causeClassName.equals(classNameToCheck)) {
return true;
} else {
if (causeClassName.contains("$")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the cause is foo.bar.Wibble$Cause would you not expect the user to enter that? Are there any instances of this, worth writing a test for?

Copy link
Contributor Author

@mikecirioli mikecirioli Dec 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into writing a test but i think its already covered. Take the case of hudson.build.Cause$UserCause - if the user wants to check to see if a cause is of that type, they have to enter that string. I found that clazz.getClass().getSuperClass().getName() was returning java.lang.Object when it was passed to the next level of recursion (which makes sense i believe) which is why i added the check to pass clazz.getEnclosingClass() when needed. It is a bit odd to me though, because class.getClass().getSuperClass().getName() returns the enclosing class when evaluated in the ide (prior to being passed to the next level of the recursion).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@dwnusbaum dwnusbaum Dec 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also confused by this check. It seems like you'd never want to check the enclosing class, since that is just about source-level organization, not about the actual sub/superclass relationships which should be handled by the recursive calls to getSuperclass().

It is a bit odd to me though, because class.getClass().getSuperClass().getName() returns the enclosing class when evaluated in the ide

In the case of hudson.build.Cause$UserCause, UserCause directly extends hudson.build.Cause, so hudson.build.Cause is both the superclass and the enclosing class. Is that what was happening?

Also, you can have a class with $ in the name literally, which would be broken by this check (e.g. public class User$Cause { ... } in User$Cause.java), although I'd be surprised to see it in practice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this clause can be dropped.

Copy link
Member

@jtnord jtnord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it will work, but left a comment or two

@mikecirioli mikecirioli changed the title getBuildCauses(...) now uses the uber classloader getBuildCauses(...) performs safer checks for determining if the specified cause type is a subclass of the current build Cause Dec 7, 2018
} else if (causeClassName.equals(classNameToCheck)) {
return true;
} else {
if (causeClassName.contains("$")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this clause can be dropped.

if (causeClassName.contains("$")) {
return isClassOrSubclass(clazz.getEnclosingClass(), classNameToCheck);
} else {
return isClassOrSubclass(clazz.getClass().getSuperclass(), classNameToCheck);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that you are not checking implemented interfaces here. Which is fine IMO—I am not sure even checking superclasses is necessary, since I know of no meaningful hierarchy among Causes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am starting to think that this has become overly complex, and that the most likely use case would be for checking for an exact match (ie. show me only causes of type hudson.model.Cause$UserIdCause)

@mikecirioli
Copy link
Contributor Author

In the spirit of YAGNI, i'm closing this PR in favor of #85, which provides for simple filtering of build causes by a specific type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants