Skip to content

WIP: Fix Class.getMethod() to reject non-public interface methods#23384

Draft
tomal-majumder wants to merge 1 commit intoeclipse-openj9:masterfrom
tomal-majumder:fix-getMethod-issue-22448
Draft

WIP: Fix Class.getMethod() to reject non-public interface methods#23384
tomal-majumder wants to merge 1 commit intoeclipse-openj9:masterfrom
tomal-majumder:fix-getMethod-issue-22448

Conversation

@tomal-majumder
Copy link

@tomal-majumder tomal-majumder commented Feb 20, 2026

Fix Class.getMethod() to throw NoSuchMethodException for non-public interface methods

Problem

Class.getMethod() must return only public methods or throw NoSuchMethodException as per Java specification. Previously, when invoked on interface types with non-public methods (private static or non-static), the method incorrectly returned null instead of throwing the required exception.

Root Cause

The issue was in the initialResultShouldBeReplaced code path in getMethodHelper(). When publicOnly was true but the initial result was a non-public method, and no public alternatives were found, the method returned null instead of calling throwExceptionOrReturnNull().

Tests

Test coverage added in Java9andUp/GetMethodTests.

Fixes: #22448

@tomal-majumder tomal-majumder force-pushed the fix-getMethod-issue-22448 branch from bc81b56 to a9b77e9 Compare February 20, 2026 23:28
Copy link
Contributor

@babsingh babsingh Feb 23, 2026

Choose a reason for hiding this comment

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

The proposed fix may not be the best way to address the reported failure.

Can you try the following fix? The comment above (in line 2057) indicates that no public method was found, which results in a null return value. The private interface method is therefore being correctly filtered. However, directly returning null here ignores the throwException input parameter, which is set to true in the case of Class.getMethod.

Suggested change
return throwExceptionOrReturnNull(throwException, name, parameterTypes);

Copy link
Author

Choose a reason for hiding this comment

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

Yes, this block does correctly filter out private interface methods. I tested the suggested change, and it produces the expected java.lang.NoSuchMethodException when a private interface method is requested via Class.getMethod().

My initial approach was to enforce the visibility constraint earlier by filtering out the private method returned by getDeclaredMethodImpl().

Copy link
Contributor

Choose a reason for hiding this comment

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

The initial approach is incomplete because it only filters out non-public methods in the this.isInterface() branch, but does not address the root contract violation in getMethodHelper.

Class.getMethod() must either return a public method or throw NoSuchMethodException. Currently, getMethodHelper can still return null in the initialResultShouldBeReplaced path, even when throwException == true. Your change does not modify that logic.

As a result:

  • it fixes the specific interface path scenario,
  • but it does not guarantee that getMethod() will always throw instead of returning null in all non-public cases, and
  • it does not cover non-interface code paths that may hit the same logic.

We are also missing test coverage. Please also add Java test cases covering these scenarios to ensure the contract is enforced consistently across both interface and non-interface paths.

@babsingh
Copy link
Contributor

Also, the commit guidelines are not followed: https://github.com/eclipse-openj9/openj9/blob/master/CONTRIBUTING.md#commit-guidelines -> The body should be wrapped at 72 characters.

@tomal-majumder tomal-majumder force-pushed the fix-getMethod-issue-22448 branch 3 times, most recently from d323ab2 to 39ac334 Compare February 27, 2026 01:11
if (initialResultShouldBeReplaced) {
// The initial result is not a public method to be searched, and no other public methods found.
return null;
return throwExceptionOrReturnNull(throwException, name, parameterTypes);
Copy link
Author

@tomal-majumder tomal-majumder Feb 27, 2026

Choose a reason for hiding this comment

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

@babsingh Added tests for Class.getMethod() on private interface methods (static and non-static), which are the only cases that reach this path. Other scenarios involving superinterfaces or implementing classes are handled and rejected earlier in the method.

@@ -0,0 +1,34 @@
/*
* Copyright IBM Corp. and others 2001
Copy link
Contributor

Choose a reason for hiding this comment

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

this reflects the year when the file was added

Suggested change
* Copyright IBM Corp. and others 2001
* Copyright IBM Corp. and others 2026

Comment on lines 28 to 34
public interface TestInterfaceForGetMethod {

private static void privateStaticMethod() {
}
private void privateNonStaticMethod() {
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

formatting nit

Suggested change
public interface TestInterfaceForGetMethod {
private static void privateStaticMethod() {
}
private void privateNonStaticMethod() {
}
}
public interface TestInterfaceForGetMethod {
private static void privateStaticMethod() {}
private void privateNonStaticMethod() {}
}

@@ -0,0 +1,60 @@
/*
* Copyright IBM Corp. and others 2001
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* Copyright IBM Corp. and others 2001
* Copyright IBM Corp. and others 2026

private static void privateStaticMethod() {
}
private void privateNonStaticMethod() {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

also include a test case for a public method to verify non-private behavior

Comment on lines 41 to 46
try {
TestInterfaceForGetMethod.class.getMethod("privateStaticMethod");
Assert.fail("Expected NoSuchMethodException for private static method in interface");
} catch (NoSuchMethodException e) {
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

the testcases can be concisely written using assertThrows. example:

assertThrows(NullPointerException.class, () -> {
myUnsafe.isFlatField(null);
});

Update getMethodHelper() to properly throw NoSuchMethodException
when Class.getMethod() is called on non-public interface methods.

Added test coverage in Java9andUp/GetMethodTests:
- Private static methods in interfaces throw NoSuchMethodException
- Private non-static methods in interfaces throw NoSuchMethodException
- Public methods successfully returns a Method

Fixes: eclipse-openj9#22448
Signed-off-by: Tomal Majumder <Tomal.Majumder@ibm.com>
@tomal-majumder tomal-majumder force-pushed the fix-getMethod-issue-22448 branch from 39ac334 to fc97f64 Compare February 27, 2026 23:22
@tomal-majumder
Copy link
Author

Updated! Also added tests for public methods.

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.

Class.getMethod() incorrectly returns private static method in interface

2 participants