groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Winnebeck, Jason" <Jason.Winneb...@windstream.com>
Subject RE: Failing to change the value of a Java variable from wihtin a Groovy script (potential issue?)
Date Tue, 08 Mar 2016 16:45:58 GMT
Unfortunately static compile can be pretty flaky at times and I run into bugs often with it
and have to redesign code. For small scripts I would advise against it (if you need type checking,
use TypeChecked). I'm wondering if the script is getting compiled to get field x from the
base class but favors setting binding.x = 'two' in the script.

I would try without static compilation and see if it works. If it does work without static
compilation, upgrade to the very latest Groovy (2.4.6) as bugs are fixed in static compiler
all the time. If that doesn't fix the problem, then change the Java field to private and create
a getX() and setX(String). If that doesn't work and you still need static compile, try an
explicit setX('two') or this.x = 'two' in the script. Historically the static compiler has
been more reliable when you are more explicit.

Jason

From: Thierry Hanser [mailto:Thierry.Hanser@lhasalimited.org]
Sent: Tuesday, March 08, 2016 11:32 AM
To: 'users@groovy.apache.org' <users@groovy.apache.org>
Subject: Failing to change the value of a Java variable from wihtin a Groovy script (potential
issue?)

Hi,

The following very simple code is behaving really strangely.
Could anyone please tell me if this is an issue in Groovy or something I am not doing properly
(I would like to vote for the latter, yet...).

In Java

x='one';
System.out.println("init x: " + x);

In Groovy

println '1 = ' + x
x = 'two'
println '2 = ' + x

Output:

init x: one  <- initial value assignement OK

1 = one      <- successfully accessing 'x' from within the compiled script OK
                the Groovy script has picked up the value of the Java variable;
                the implicit getX() has been called

2 = one                <- should be 'two' as per Groovy code (second line)
                but is unchanged ???

It seems that the Groovy script can't change the value of 'x' (can't access setX()). However
there is no compilation error ('x' is not read-only)
When implementing getX/setX methods, only the getter is called (in both print statements,
line 1,3) but during the assignment instruction (line 2), the setter is silently ignored (the
value of 'x' remains 'one' instead of 'two'.

The Java/Groovy binding is operational since the 'one' value of 'x' in the Java  base class
is successfully retrieved. So could anyone please tell me where the issue is?
The confusing part is that even within in the Groovy context alone, the assignment 'x='two'
is not honoured (and yet there are no compilation/runtime error)

Note that I tried all combinations of setters/getters/visibility and can at the best read
but never modify the variable 'x'. The same behaviour occurs with using the GroovyScriptEngine
or GroovyClassLoader

Thank you very much in advance for your help.

Thierry
-

PS: (I am not sure if my previous message went through as I was still in the mailing list
registration process, apologies if it is a duplicate)

Full code:

import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;

import groovy.lang.Binding;
import groovy.lang.Closure
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyShell;
import groovy.transform.CompileStatic;;

abstract class GroovyDemoScript extends Script
{
    public String x;

    public GroovyDemoScript()
    {
           x='one';
           System.out.println("init x: " + x);
    }

    public static void main(String...args) throws Throwable
    {
           ////
           // Compilation configuration
           CompilerConfiguration configuration = new CompilerConfiguration();
           configuration.addCompilationCustomizers(new ASTTransformationCustomizer(CompileStatic.class));

                                // make sure we use the Java base class where 'x' is defined
           configuration.setScriptBaseClass(GroovyDemoScript.class.name);

           GroovyShell shell = new GroovyShell(this.getClass().getClassLoader(), new Binding(),
configuration);

           // source code
           String scriptSource= "println '1 = ' + x; x = 'two'; println '2 = ' + x\n";

           // compile the source code and run the compiled script
           GroovyDemoScript compiledScript = shell.parse(scriptSource);
           compiledScript.run();
    }
}

________________________________
Switchboard: +44 (0)113 394 6020
Technical Support: +44 (0)113 394 6030
________________________________
Lhasa Limited, a not-for-profit organisation, promotes scientific knowledge & understanding
through the development of computer-aided reasoning & information systems in chemistry
& the life sciences. Registered Charity Number 290866. Registered Office: Granary Wharf
House, 2 Canal Wharf, Leeds, LS11 5PS. Company Registration Number 01765239. Registered in
England and Wales.
This communication, including any associated attachments, is intended for the use of the addressee
only and may contain confidential, privileged or copyright material. If you are not the intended
recipient, you must not copy this message or attachment or disclose the contents to any other
person. If you have received this transmission in error, please notify the sender immediately
and delete the message and any attachment from your system. Except where specifically stated,
any views expressed in this message are those of the individual sender and do not represent
the views of Lhasa Limited. Lhasa Limited cannot accept liability for any statements made
which are the sender's own. Lhasa Limited does not guarantee that electronic communications,
including any attachments, are free of viruses. Virus scanning is recommended and is the responsibility
of the recipient.

----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended recipient(s).
Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the
intended recipient, please contact the sender by reply email and destroy all copies of the
original message and any attachments.

Mime
View raw message