Skip to content

fix: Prefer accessible interface methods over internal implementation classes (backport #485 to ognl-3-4-x)#503

Merged
lukaszlenart merged 1 commit intoognl-3-4-xfrom
fix/issue-286-backport-pr-485
Nov 29, 2025
Merged

fix: Prefer accessible interface methods over internal implementation classes (backport #485 to ognl-3-4-x)#503
lukaszlenart merged 1 commit intoognl-3-4-xfrom
fix/issue-286-backport-pr-485

Conversation

@lukaszlenart
Copy link
Copy Markdown
Collaborator

Summary

This PR backports #485 from the main branch (Java 17+) to the ognl-3-4-x branch (Java 8 compatible).

Fixes: #286 - OGNL choosing method on unexported class rather than exported interface

Problem:
When calling methods on objects, OGNL was selecting methods from internal JDK implementation classes (e.g., sun.security.x509.X509CertImpl) instead of the public interface (java.security.cert.X509Certificate). This causes IllegalAccessException because the Java module system doesn't export internal packages.

Solution:

  • Added isLikelyAccessible() helper method to detect potentially inaccessible classes
  • Enhanced findBestMethod() tie-breaking logic to prefer accessible methods over internal ones
  • Added comprehensive test coverage (36 new tests)

Changes

Production Code (1 file modified):

  • src/main/java/ognl/OgnlRuntime.java
    • Added isLikelyAccessible() method (45 lines, package-private for testing)
    • Modified findBestMethod() tie-breaking logic (20 lines)

Test Files (6 files created):

  • src/test/java/sun/test/PublicTestInterface.java - Test helper interface
  • src/test/java/sun/test/SimulatedInternalClass.java - Simulates internal sun.* class
  • src/test/java/com/sun/test/AnotherInternalClass.java - Tests com.sun.* detection
  • src/test/java/ognl/OgnlRuntimeAccessibilityTest.java - 10 unit tests for isLikelyAccessible()
  • src/test/java/ognl/test/Issue286Test.java - 26 integration tests for the fix

Java 8 Adaptations

This backport required several adaptations from the original PR #485 to maintain Java 8 compatibility:

  1. API Changes:

    • clazz.getPackageName()clazz.getPackage().getName() (getPackageName() is Java 9+)
    • Removed Module API checks entirely (Module API is Java 9+ only)
    • Rely solely on package name heuristics to detect internal packages
  2. Test Framework:

    • Converted from JUnit 5 to JUnit 4 (ognl-3-4-x uses JUnit 4)
    • Changed all test classes from class to public class
    • Changed all test methods from void method() to public void method()
    • Swapped assertion parameter order (message first in JUnit 4 vs last in JUnit 5)
    • Replaced assertDoesNotThrow() with try-catch pattern (doesn't exist in JUnit 4)
  3. Java 8 API:

    • List.of()Arrays.asList() (List.of() is Java 9+)
    • Added import java.util.Arrays;

Test Results

All 993 tests pass (957 existing + 36 new):

  • OgnlRuntimeAccessibilityTest: 10 unit tests
  • Issue286Test: 26 integration tests
  • All existing tests still pass (0 regressions)

Backward Compatibility

Fully backward compatible

  • No API changes
  • Existing code paths unchanged
  • Fix only activates for same-signature method conflicts
  • Defaults to "accessible" when uncertain (conservative approach)

References

Test Plan

  • All 957 existing tests pass (no regressions)
  • All 36 new tests pass
  • Compiles with Java 8 target (source/target 1.8)
  • Issue Ognl choosing method on unexported class rather than exported interface #286 scenario fixed (prefers interface over internal class)
  • Simulated sun.* and com.sun.* classes detected as inaccessible
  • Standard JDK classes detected as accessible
  • Interfaces always detected as accessible
  • Backward compatibility verified (existing code unaffected)

🤖 Generated with Claude Code

@lukaszlenart lukaszlenart added this to the 3.4.9 milestone Nov 29, 2025
@lukaszlenart lukaszlenart force-pushed the fix/issue-286-backport-pr-485 branch from a49f656 to ebfe03f Compare November 29, 2025 12:58
…backport #485 to ognl-3-4-x)

Fixes #286 - OGNL choosing method on unexported class rather than exported interface

This backport adapts PR #485 from main branch for Java 8 compatibility:
- Added isLikelyAccessible() helper method (Java 8 compatible)
- Enhanced findBestMethod() tie-breaking logic to prefer accessible methods
- Added comprehensive test coverage (36 new tests: 10 unit + 26 integration)

Java 8 adaptations:
- Use clazz.getPackage().getName() instead of getPackageName()
- Remove Module API checks (Java 9+ only)
- Use Arrays.asList() instead of List.of() in tests
- Convert from JUnit 5 to JUnit 4
- Swap assertion parameter order (message first in JUnit 4)
- Replace assertDoesNotThrow() with try-catch pattern

Test results: 993 tests passed (957 existing + 36 new), 0 failures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@lukaszlenart lukaszlenart force-pushed the fix/issue-286-backport-pr-485 branch from ebfe03f to fb97bb1 Compare November 29, 2025 13:01
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
79.2% Coverage on New Code (required ≥ 80%)
C Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@lukaszlenart lukaszlenart merged commit 88adaad into ognl-3-4-x Nov 29, 2025
4 of 5 checks passed
@lukaszlenart lukaszlenart deleted the fix/issue-286-backport-pr-485 branch November 29, 2025 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant