Conversation
foo.bar never resolved to a record's generated bar() accessor, only to getBar()/isBar(), a public field, or duck-typed get(Object). Add a RecordGetExecutor that matches property to record component and lets Introspector resolve the actual accessor Method, so it still goes through the usual permission checks. Detection is done entirely via reflection (Class#isRecord(), Class#getRecordComponents()) since this module still targets Java 8; on such a runtime these methods simply don't exist and discovery quietly reports no match. The new test compiles its record fixtures on the fly with javax.tools.JavaCompiler and skips itself below Java 16, since 'record' isn't valid syntax at this module's source level either.
…ture Move the Class#isRecord()/getRecordComponents() reflection out of RecordGetExecutor and into the existing ClassTool backport utility, resolved via MethodHandle to match how it already backports Java 9+ module reflection, instead of duplicating a separate Method-based lookup. Fix RecordPropertyAccessTest's on-the-fly compiled record fixture to actually compile into org.apache.commons.jexl3 (it previously compiled with no package, then looked itself up under that package, which does not resolve). Also switch the test to extend JexlTestCase and use the shared restricted-permissions engine instead of a bespoke UNRESTRICTED-permissions one, matching the rest of the suite. Builds on the record accessor support originally proposed by Aurelien Mino in #415. Co-Authored-By: Claude Code <noreply@anthropic.com>
- Builds on the record accessor support originally proposed by Aurelien Mino in #415. - Move the Class#isRecord()/getRecordComponents() reflection out of RecordGetExecutor and into the existing ClassTool backport utility, resolved via MethodHandle to match how it already backports Java 9+ module reflection, instead of duplicating a separate Method-based lookup. - Fix RecordPropertyAccessTest's on-the-fly compiled record fixture to actually compile into org.apache.commons.jexl3. Also switch the test to extend JexlTestCase and use the shared restricted-permissions engine instead of a bespoke UNRESTRICTED-permissions one, matching the rest of the suite. - Correct @SInCE on the namespaceInstantiation additions (JexlFeatures, JexlOptions) from stale 3.6 to 3.7.1, and RecordGetExecutor from 3.7.2 to 3.7.1, matching the actual in-flight version. - Reorder actions within each changes.xml section by descending JEXL issue number.
There was a problem hiding this comment.
🟡 Changes recommended
Test artifacts are not cleaned up, and unrelated Checkstyle and ignore exclusions should be removed.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds Java record component accessor support as JEXL properties with Java 8-compatible reflective discovery.
Changes:
- Adds record-aware introspection and property execution.
- Adds runtime-compiled record property tests.
- Updates API metadata, release notes, and build configuration.
File summaries
| File | Summary |
|---|---|
src/test/java/org/apache/commons/jexl3/RecordPropertyAccessTest.java |
Tests record property access. |
src/main/java/org/apache/commons/jexl3/JexlOptions.java |
Updates API version metadata. |
src/main/java/org/apache/commons/jexl3/JexlFeatures.java |
Updates API version metadata. |
src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java |
Integrates record getter resolution. |
src/main/java/org/apache/commons/jexl3/internal/introspection/RecordGetExecutor.java |
Resolves record component accessors. |
src/main/java/org/apache/commons/jexl3/internal/introspection/ClassTool.java |
Provides reflective record introspection. |
src/changes/changes.xml |
Documents JEXL-472. |
pom.xml |
Adds Checkstyle exclusions. |
.gitignore |
Ignores scratch files. |
Review details
Suppressed comments (1)
src/test/java/org/apache/commons/jexl3/RecordPropertyAccessTest.java:60
- Each invocation creates a source/class-file tree under
java.io.tmpdirand never removes it. Repeated test runs therefore accumulatejexl-record-test*directories; close the class loader and recursively deletedirin afinallyblock after loading the class.
final Path dir = Files.createTempDirectory("jexl-record-test");
final Path javaFile = dir.resolve(name + ".java");
Files.write(javaFile, source.getBytes(StandardCharsets.UTF_8));
- Files reviewed: 8/9 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
The Checkstyle configurations are inconsistent, and the public resolver documentation omits record accessor support.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java:352
- The
PROPERTYresolver's public documentation still says it only seeksget{P,p}andis{P,p}methods (JexlUberspect.java:48-49). This branch also resolves record component accessors namedfoo(), so please update that contract documentation or users configuring resolver strategies will not know that record properties are supported.
if (executor == null) {
// or a record component accessor, foo() rather than getFoo()
executor = RecordGetExecutor.discover(is, clazz, property);
- Files reviewed: 8/9 changed files
- Comments generated: 1
- Review effort level: Lite
…ses?), fix by avoidance;
No description provided.