groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dinko Srkoč <dinko.sr...@gmail.com>
Subject Re: No Such Property - When executing script from Java.
Date Fri, 19 Jun 2015 06:49:18 GMT
On 19 June 2015 at 03:09, Erick Nelson <ericksn@gmail.com> wrote:
>
> Well, i know see what is causing my problem , but i can't say I understand why it is
a problem.
> Maybe a misunderstanding I have on exaction how @Field works?
>
> I was declaring my object like this....
>
>      @Field Action mailSent
>      mailSent = new Action("Mail Sent")
>
> or like this...
>
>      @Field mailSent
>      mailSent = new Action("Mail Sent")
>
> Both of these ways of declare an instance of Action causes an error.
>
> When I change it to your way ...
>
>      @Field mailSent = new Action("Mail Sent")
>
> or this...
>
>      @Field Action mailSent = new Action("Mail Sent")
>
> The problem goes away when run from java.
>
> I don't see any problems when running as Groovy with any of the above declarations.
>

    @Field mailSent
    mailSent = new Action("Mail Sent")

Even though `mailSent` is a field it is still initialised in the `run`
method, thus is `null` when you call ìnvoke` from java.

    @Field mailSent = new Action("Mail Sent")

This time `mailSent` is initialised during script object construction.

Cheers,
Dinko

>
> Here is my full stacktrace
>
> Exception in thread "main" java.lang.NullPointerException: Cannot invoke method execute()
on null object
> at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:88)
> at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
> at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
> at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:32)
> at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
> at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
> at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:114)
> at TestGroovy.invoke(TestGroovy.groovy:48)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:483)
> at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
> at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:807)
> at groovy.lang.GroovyObjectSupport.invokeMethod(GroovyObjectSupport.java:44)
> at groovy.lang.Script.invokeMethod(Script.java:78)
> at MyTest.main(MyTest.java:13)
>
>
> On Thu, Jun 18, 2015 at 3:37 PM, Paul Henry <paul.henry@futrix.com> wrote:
>>
>> Hi All,
>>
>> Thanks for the help. Using the @Field annotation has solved the issue. (And it works
for me both within Eclipse on Windows, and deployed within Tomcat on Windows)
>>
>> Looking at the docs on the @Field Annotation also helped me to understand why this
was happening. If I understand correctly when a script is compiled into a Script class, locally
defined properties are actually placed inside the generated run method, and are not compiled
to properties of the Script class itself. The @Field annotation changes that behaviour and
makes them private fields of the script class. Which then means that other methods within
the script class can reference them.
>>
>> Makes sense now that I know what was going on, but was kinda frustrating at the time...
>>
>>
>>
>>
>>
>>
>> Paul Henry
>> Senior Technical Developer |
>> 79 Boulcott Street, Level 2, Wellington 6011, New Zealand
>> tel +64 4 499 1327 | mob +64 22 161 8700
>> paul.henry@futrix.com | www.futrix.com | LinkedIn
>>
>>
>>
>> On 19 June 2015 at 03:36, Erick Nelson <ericksn@gmail.com> wrote:
>>>
>>> I'll try from a linux box then... later today. Maybe it has something to do with
running in Eclipse....
>>>
>>> On Thu, Jun 18, 2015 at 1:35 AM, Dinko Srkoč <dinko.srkoc@gmail.com> wrote:
>>>>
>>>> On 17 June 2015 at 18:08, Erick Nelson <ericksn@gmail.com> wrote:
>>>>>
>>>>> Yes, removing the &execute and changing invoke back to...
>>>>>
>>>>> void invoke (String action) {
>>>>>     this."${action}".execute()
>>>>> }
>>>>>
>>>>> does work , from Groovy, but when called from Java ....
>>>>>
>>>>>         File file = new File("src", "TestGroovy.groovy");
>>>>>         Class groovyClass = new GroovyClassLoader().parseClass(file);
>>>>>         GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
>>>>>         groovyObject.invokeMethod("invoke", new String [] { "mailSent"
});
>>>>>
>>>>> I get an error ...
>>>>>
>>>>> Exception in thread "main" java.lang.NullPointerException: Cannot invoke
method execute() on null object. This is thrown from the this."${action}".execute() line.
>>>>>
>>>>> It is only when I use the &execute that it works in both Java and
Groovy.
>>>>
>>>>
>>>> Hmmm. It works on my machine (my favourite line ;-) ):
>>>>
>>>> -----------------------------------------
>>>> $ java -version
>>>> java version "1.7.0_76"
>>>> Java(TM) SE Runtime Environment (build 1.7.0_76-b13)
>>>> Java HotSpot(TM) 64-Bit Server VM (build 24.76-b04, mixed mode)
>>>> $ cat Bugger.groovy
>>>> import groovy.transform.Field
>>>>
>>>> class Action {
>>>>     String actionName
>>>>     Action(actionName) {
>>>>         this.actionName = actionName
>>>>     }
>>>>     void execute() {
>>>>         println "Doing $actionName"
>>>>     }
>>>> }
>>>>
>>>> @Field formFilled = new Action("Form Filled")
>>>>
>>>> @Field mailSent = new Action("Mail Sent")
>>>>
>>>> def invoke(action) {
>>>>     this."$action".execute()
>>>> }
>>>> $ cat Main.java
>>>> import java.io.File;
>>>> import groovy.lang.GroovyClassLoader;
>>>> import groovy.lang.GroovyObject;
>>>>
>>>> public class Main {
>>>>
>>>>     public static void main (String [] args) {
>>>>         try {
>>>>             File file = new File("Bugger.groovy");
>>>>             Class grClass = new GroovyClassLoader().parseClass(file);
>>>>             GroovyObject groovyInstance = (GroovyObject) grClass.newInstance();
>>>>             groovyInstance.invokeMethod("invoke", new String[] { "mailSent"});
>>>>         } catch (Exception e) {
>>>>             e.printStackTrace();
>>>>         }
>>>>     }
>>>> }
>>>> $ javac -cp $GROOVY_HOME/embeddable/groovy-all-2.4.3.jar Main.java
>>>> $ java -cp $GROOVY_HOME/embeddable/groovy-all-2.4.3.jar:. Main
>>>> Doing Mail Sent
>>>> $
>>>> -----------------------------------------
>>>>
>>>> Cheers,
>>>> Dinko
>>>>
>>>
>>
>

Mime
View raw message