killme2008 / killme2008/aviatorscript
Accessing a field of a Java Record class throws NoSuchPropertyException
- Dominant language
- Java
- Stars
- 5.2k
- Forks
- 906
- PR merge metrics
- No merged PRs in 30d
Description
Hi!
When I try to access a field from a Java Record Class, AviatorJavaType#getProperty() throws a NoSuchPropertyException.
Here's a minimal example:
```java
@Test
void aviatorRecordType() {
record SubjectReq(String name) {}
record ObjectReq(String name) {}
enum ActionReq {action_one, action_two}
final Object result = AviatorEvaluator.execute("""
println(sub);
println(obj);
println(act);
println(sub.name);
println(obj.name);
return true;
""", Map.of(
"sub", new SubjectReq("sub_name"),
"obj", new ObjectReq("obj_name"),
"act", ActionReq.action_one));
assertTrue((Boolean) result);
}
```
logs:
```
SubjectReq[name=sub_name]
ObjectReq[name=obj_name]
action_one
```
throws:
```
com.googlecode.aviator.exception.ExpressionRuntimeException: Could not find variable sub.name
at com.googlecode.aviator.runtime.type.AviatorJavaType.getProperty(AviatorJavaType.java:442)
at com.googlecode.aviator.runtime.type.AviatorJavaType.getValueFromEnv(AviatorJavaType.java:331)
at com.googlecode.aviator.runtime.type.AviatorJavaType.getValue(AviatorJavaType.java:319)
at com.googlecode.aviator.runtime.function.system.PrintlnFunction.call(PrintlnFunction.java:54)
at ... script ...
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:44)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:237)
at com.googlecode.aviator.AviatorEvaluatorInstance.execute(AviatorEvaluatorInstance.java:1639)
at com.googlecode.aviator.AviatorEvaluator.execute(AviatorEvaluator.java:532)
at com.googlecode.aviator.AviatorEvaluator.execute(AviatorEvaluator.java:544)
at ...mytestclass...
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: com.googlecode.aviator.exception.NoSuchPropertyException: Property `name` not found in java bean: SubjectReq[name=sub_name]
at com.googlecode.aviator.utils.Reflector.throwNoSuchPropertyException(Reflector.java:268)
at com.googlecode.aviator.utils.Reflector.fastGetProperty(Reflector.java:256)
at com.googlecode.aviator.utils.Reflector.fastGetProperty(Reflector.java:816)
at com.googlecode.aviator.runtime.type.AviatorJavaType.getProperty(AviatorJavaType.java:432)
... 80 more
```
If I try to access a "normal" (+lombok) Object field, it works like expected:
Normal class test:
```java
@Test
void aviatorClassType() {
@Data
@AllArgsConstructor
class SubjectReqObj {
final String name;
}
@Data
@AllArgsConstructor
class ObjectReqObj {
final String name;
}
enum ActionReq {action_one, action_two}
final Object result = AviatorEvaluator.execute("""
println(sub);
println(obj);
println(act);
println(sub.name);
println(obj.name);
return true;
""", Map.of(
"sub", new SubjectReqObj("sub_name"),
"obj", new ObjectReqObj("obj_name"),
"act", ActionReq.action_one));
assertTrue((Boolean) result);
}
```
Normal class logs:
```
SubjectReqObj(name=sub_name)
ObjectReqObj(name=obj_name)
action_one
sub_name
obj_name
```
Is this something that is not implemented (yet) or am I using it wrong?
Kind Regards,
Marc
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in AviatorJavaType#getProperty(), identified in the stack trace, and reproduce the minimal JUnit example from the issue with Java record components. Compare that path with the working Lombok-backed class example. Done means expressions such as sub.name and obj.name resolve record component values without breaking normal Java bean property access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100