Discussion:
[groovy-dev] JSR-223 ScriptEngine and CompilerConfiguration
Maarten Boekhold
2015-02-01 09:27:16 UTC
Permalink
Hi all,

For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.

I see 2 ways to implement this:
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy
initialization of the GroovyClassLoader.

Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be 'misusing' the
ScriptContext a bit. In addition, if there is an error in your config
script, you would get an exception the first time you try to
eval/compile something, and not on instantiation of the ScriptEngine.

I wonder what others think of this? I'm willing to create a pull request
for this functionality, provided I get some direction on which approach
would be acceptable to the core team.

Maarten

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Sergey Egorov
2015-02-01 10:14:12 UTC
Permalink
(1) is also not threadsafe
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could instruct the GroovyScriptEngineImpl to use a CompilerConfiguration similar to the -configfile option to groovyc.
1. Use a system property that you set before requesting your ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable containing the configuration script name, and to do a lazy initialization of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each separate instance of GroovyScriptEngineImpl, which might not be what you want. Downside to (2) is that this seems to be 'misusing' the ScriptContext a bit. In addition, if there is an error in your config script, you would get an exception the first time you try to eval/compile something, and not on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull request for this functionality, provided I get some direction on which approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-01 10:31:18 UTC
Permalink
Hi,

What do you mean with "not thread safe"? I suppose you are referring to
2 threads both doing something like:

// second thread uses a different value for "path/to/my/file.groovy"
System.setProperty("groovy.jsr223.compiler.configurator",
"path/to/my/file.groovy");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByExtension("groovy");

If so, yes, that's not thread-safe obviously. But that's not really the
use case I'm thinking of anymore. I'm more thinking of simply:

java -Dgroovy.jsr223.compiler.configurator=/path/to/my/file.groovy ...

If you really want to control from code the creation of 2
GroovyScriptEngineImpl instances, each one using different compiler
configuration, then you can easily do that by just skipping
"ScriptEngineManager.getEngineByExtension()" and directly do "engine =
new GroovyScriptEngineImpl(gcl)" with a custom GroovyClassLoader. I mean
you are already making your code specific to groovy, so why not just
instantiate the whole engine manually?

Maarten
Post by Sergey Egorov
(1) is also not threadsafe
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could instruct the GroovyScriptEngineImpl to use a CompilerConfiguration similar to the -configfile option to groovyc.
1. Use a system property that you set before requesting your ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable containing the configuration script name, and to do a lazy initialization of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each separate instance of GroovyScriptEngineImpl, which might not be what you want. Downside to (2) is that this seems to be 'misusing' the ScriptContext a bit. In addition, if there is an error in your config script, you would get an exception the first time you try to eval/compile something, and not on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull request for this functionality, provided I get some direction on which approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-01 10:21:47 UTC
Permalink
Hmmm,

thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any existing/closed
application that relies on the javax.script API from using the proposed
functionality. So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).

Maarten
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy
initialization of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what
you want. Downside to (2) is that this seems to be 'misusing' the
ScriptContext a bit. In addition, if there is an error in your config
script, you would get an exception the first time you try to
eval/compile something, and not on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull
request for this functionality, provided I get some direction on which
approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-01 12:41:28 UTC
Permalink
Hi,

If you want something concrete to look at, here's the link to a feature
branch on my own fork of groovy-core that implements this:

https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig

No test cases/docs added yet, but existing test cases all pass. I also
know that the code I inserted in the default constructor /in theory/
works because I've used almost the same code in another project (and I
stole it from the groovyc source :)).

Maarten
Post by Maarten Boekhold
Hmmm,
thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any existing/closed
application that relies on the javax.script API from using the
proposed functionality. So I guess this would have to work based on a
System property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we
could instruct the GroovyScriptEngineImpl to use a
CompilerConfiguration similar to the -configfile option to groovyc.
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy
initialization of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what
you want. Downside to (2) is that this seems to be 'misusing' the
ScriptContext a bit. In addition, if there is an error in your config
script, you would get an exception the first time you try to
eval/compile something, and not on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull
request for this functionality, provided I get some direction on
which approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jim White
2015-02-01 20:18:52 UTC
Permalink
This excellent Maarten! I haven't done any JSR-223 in a long while and
didn't realize the ability to specify the CompilerConfiguration wasn't
supported (I did the original JSR-223 implementation for Groovy, Scala,
Jython, and a couple other languages as part of the development for IFCX
Wings <http://www.ifcx.org/wiki/Wings.html>).

Using a system property is indeed the correct design (you can see it used
elsewhere <https://github.com/jruby/jruby/wiki/RedBridge> the same way with
JRuby for example). Other options that would be useful to specify would be
the base script (--basescript) and configuration script (--configscript).

As for folks trying to persuade you to "use a Groovy specific API", I'm
sure you understand what they don't which is that where JSR-223 is used (a
standard Java API used in thousands of systems) that is a non-option.

You need to set up a JIRA issue to track this work.

Jim
Post by Maarten Boekhold
Hi,
If you want something concrete to look at, here's the link to a feature
master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all pass. I also
know that the code I inserted in the default constructor /in theory/ works
because I've used almost the same code in another project (and I stole it
from the groovyc source :)).
Maarten
Post by Maarten Boekhold
Hmmm,
thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any existing/closed
application that relies on the javax.script API from using the proposed
functionality. So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration similar
to the -configfile option to groovyc.
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy initialization
of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be 'misusing' the ScriptContext
a bit. In addition, if there is an error in your config script, you would
get an exception the first time you try to eval/compile something, and not
on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull request
for this functionality, provided I get some direction on which approach
would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-02 06:00:37 UTC
Permalink
Hi Jim,

--configscript is already taken care of by my
"groovy.jsr223.compiler.configurator" System property. This one takes
the name of a file, which has the same syntax as what you would provide
to the --configscript option.

Good point about --basescript. I've added this to my patch now, will
push soon after gradlew test completes. I can't work on the
documentation part from here. Due to a corporate firewall I've got big
trouble getting gradlew asciidoc to run, and I can't access my home
computer at the moment (port forwarding screwed up). Will see if I can
do anything about documentation later today/tomorrow.

https://github.com/boekhold/groovy-core/compare/feature/JSR-223-CompilerConfig

Maarten
Post by Jim White
This excellent Maarten! I haven't done any JSR-223 in a long while
and didn't realize the ability to specify the CompilerConfiguration
wasn't supported (I did the original JSR-223 implementation for
Groovy, Scala, Jython, and a couple other languages as part of the
development for IFCX Wings <http://www.ifcx.org/wiki/Wings.html>).
Using a system property is indeed the correct design (you can see it
used elsewhere <https://github.com/jruby/jruby/wiki/RedBridge> the
same way with JRuby for example). Other options that would be useful
to specify would be the base script (--basescript) and configuration
script (--configscript).
As for folks trying to persuade you to "use a Groovy specific API",
I'm sure you understand what they don't which is that where JSR-223 is
used (a standard Java API used in thousands of systems) that is a
non-option.
You need to set up a JIRA issue to track this work.
Jim
Hi,
If you want something concrete to look at, here's the link to a
https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all pass. I
also know that the code I inserted in the default constructor /in
theory/ works because I've used almost the same code in another
project (and I stole it from the groovyc source :)).
Maarten
Hmmm,
thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any
existing/closed application that relies on the javax.script
API from using the proposed functionality. So I guess this
would have to work based on a System property
(groovy.jsr223.compiler.configurator=XXXX).
Maarten
Hi all,
For a while now I've had this idea that it would be useful
if we could instruct the GroovyScriptEngineImpl to use a
CompilerConfiguration similar to the -configfile option to groovyc.
1. Use a system property that you set before requesting
your ScriptEngine instance
2. Use the 'default ScriptContext' to set a special
context variable containing the configuration script name,
and to do a lazy initialization of the GroovyClassLoader.
Downside of (1) is that the specified config file would
apply to each separate instance of GroovyScriptEngineImpl,
which might not be what you want. Downside to (2) is that
this seems to be 'misusing' the ScriptContext a bit. In
addition, if there is an error in your config script, you
would get an exception the first time you try to
eval/compile something, and not on instantiation of the
ScriptEngine.
I wonder what others think of this? I'm willing to create
a pull request for this functionality, provided I get some
direction on which approach would be acceptable to the
core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Jim White
2015-02-02 06:49:14 UTC
Permalink
Ah, yes I see. Very nice.

I have a minor stylistic suggestion to make the naming more like the groovy
main executable options. Something along the lines of:

COMPILER_CONFIG_SYSTEM_PROPERTY = "groovy.jsr223.option.configscript"
BASE_SCRIPT_SYSTEM_PROPERTY = "groovy.jsr223.option.basescript"

Not sure when I'll be able to give this a whirl. No hurry on getting the
JIRA and such set up but if you get stuck then I can help you out with that.

Good work!

Jim
Post by Maarten Boekhold
Hi Jim,
--configscript is already taken care of by my
"groovy.jsr223.compiler.configurator" System property. This one takes the
name of a file, which has the same syntax as what you would provide to the
--configscript option.
Good point about --basescript. I've added this to my patch now, will push
soon after gradlew test completes. I can't work on the documentation part
from here. Due to a corporate firewall I've got big trouble getting gradlew
asciidoc to run, and I can't access my home computer at the moment (port
forwarding screwed up). Will see if I can do anything about documentation
later today/tomorrow.
https://github.com/boekhold/groovy-core/compare/feature/JSR-223-CompilerConfig
Maarten
This excellent Maarten! I haven't done any JSR-223 in a long while and
didn't realize the ability to specify the CompilerConfiguration wasn't
supported (I did the original JSR-223 implementation for Groovy, Scala,
Jython, and a couple other languages as part of the development for IFCX
Wings <http://www.ifcx.org/wiki/Wings.html>).
Using a system property is indeed the correct design (you can see it
used elsewhere <https://github.com/jruby/jruby/wiki/RedBridge> the same
way with JRuby for example). Other options that would be useful to specify
would be the base script (--basescript) and configuration script
(--configscript).
As for folks trying to persuade you to "use a Groovy specific API", I'm
sure you understand what they don't which is that where JSR-223 is used (a
standard Java API used in thousands of systems) that is a non-option.
You need to set up a JIRA issue to track this work.
Jim
Post by Maarten Boekhold
Hi,
If you want something concrete to look at, here's the link to a feature
https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all pass. I also
know that the code I inserted in the default constructor /in theory/ works
because I've used almost the same code in another project (and I stole it
from the groovyc source :)).
Maarten
Post by Maarten Boekhold
Hmmm,
thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any existing/closed
application that relies on the javax.script API from using the proposed
functionality. So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration similar
to the -configfile option to groovyc.
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy initialization
of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be 'misusing' the ScriptContext
a bit. In addition, if there is an error in your config script, you would
get an exception the first time you try to eval/compile something, and not
on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull
request for this functionality, provided I get some direction on which
approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Cédric Champeau
2015-02-02 07:35:15 UTC
Permalink
Ok let me be clear why I think using a Groovy specific API is better in
this case. First of all, JSR-223 was born with Groovy, so the the script
engines are pretty similar. But Groovy has evolved a lot, and JSR-223 is
far behind in terms of what you can do to configure the engine (in
short, nothing). The advantage of JSR-223 is if you want to switch from
one engine (Groovy) to another (Nashorn) or if you want to support
multiple scripting languages for the same application. So far so good,
but as you noticed Groovy unleashes its full potential when you
configure the engine, allowing you to have much better DSLs. Otherwise
integration is pretty ridiculous.

So, naturally, you want to configure the engine and JSR-223 does not let
you do this. So if you really need to leverage JSR-223 (which IMHO is
not the case for 95% of integration cases), you have a problem. There
are two options:

1. find *workarounds* in the Groovy JSR 223 engine to be able to fetch
configuration magically
2. work on an improved JSR 223 allowing to pass at least a map for
configuration data of the engine (I don't think we need more than that).

Of course as a user, you can't do 2, but you can submit the idea. So
what's left is 1. Unfortunately, as you noticed, "magically" has a lot
of drawbacks. It forces the Groovy JSR-223 engine to be inherently
unsafe *and* limited. Getting the configuration "magically" implies that
the engine fetches the configuration from a global dataset. Options are:

1. system properties. Easiest to implement, but global, so impossible to
have two distinct configurations for two kind of scripts. Can be very
problematic if you use Groovy in two applications hosted in the same app
server for example, because it could just break one application. And as
Jochen said, it's not thread-safe.
2. Thread locals. You can store the configuration local inside the
current thread, used to compile the script. The "Safest" approach, as
long as you take care of removing the configuration data from the thread
after the script is compiled, otherwise you create a memory leak.
3. Files. The script engine could search for configuration data in the
file system, in a specific place. Not any better than 1, and not thread
safe.
4. Classpath. It is a variant of 1 and 3, where you could push on
classpath a resource file that would be picked by the script engine. Is
has the advantage of isolating one application from the other, but
still, configuration is global in a single application.

So really, I think the questions need to be asked in that order:

1. do you *really* need to rely on JSR 223
2. if yes, then do we want to build an inherently unsafe script engine
to be able to workaround JSR limitations?
Post by Jim White
Ah, yes I see. Very nice.
I have a minor stylistic suggestion to make the naming more like the
COMPILER_CONFIG_SYSTEM_PROPERTY = "groovy.jsr223.option.configscript"
BASE_SCRIPT_SYSTEM_PROPERTY = "groovy.jsr223.option.basescript"
Not sure when I'll be able to give this a whirl. No hurry on getting
the JIRA and such set up but if you get stuck then I can help you out
with that.
Good work!
Jim
Hi Jim,
--configscript is already taken care of by my
"groovy.jsr223.compiler.configurator" System property. This one
takes the name of a file, which has the same syntax as what you
would provide to the --configscript option.
Good point about --basescript. I've added this to my patch now,
will push soon after gradlew test completes. I can't work on the
documentation part from here. Due to a corporate firewall I've got
big trouble getting gradlew asciidoc to run, and I can't access my
home computer at the moment (port forwarding screwed up). Will see
if I can do anything about documentation later today/tomorrow.
https://github.com/boekhold/groovy-core/compare/feature/JSR-223-CompilerConfig
Maarten
Post by Jim White
This excellent Maarten! I haven't done any JSR-223 in a long
while and didn't realize the ability to specify the
CompilerConfiguration wasn't supported (I did the original
JSR-223 implementation for Groovy, Scala, Jython, and a couple
other languages as part of the development for IFCX Wings
<http://www.ifcx.org/wiki/Wings.html>).
Using a system property is indeed the correct design (you can see
it used elsewhere <https://github.com/jruby/jruby/wiki/RedBridge>
the same way with JRuby for example). Other options that would
be useful to specify would be the base script (--basescript) and
configuration script (--configscript).
As for folks trying to persuade you to "use a Groovy specific
API", I'm sure you understand what they don't which is that where
JSR-223 is used (a standard Java API used in thousands of
systems) that is a non-option.
You need to set up a JIRA issue to track this work.
Jim
On Sun, Feb 1, 2015 at 4:41 AM, Maarten Boekhold
Hi,
If you want something concrete to look at, here's the link to
a feature branch on my own fork of groovy-core that
https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all
pass. I also know that the code I inserted in the default
constructor /in theory/ works because I've used almost the
same code in another project (and I stole it from the groovyc
source :)).
Maarten
Hmmm,
thinking about this a bit more, I think that option 2
(using ScriptContext) is a dead-end: it would prevent any
existing/closed application that relies on the
javax.script API from using the proposed functionality.
So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Hi all,
For a while now I've had this idea that it would be
useful if we could instruct the
GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.
1. Use a system property that you set before
requesting your ScriptEngine instance
2. Use the 'default ScriptContext' to set a special
context variable containing the configuration script
name, and to do a lazy initialization of the
GroovyClassLoader.
Downside of (1) is that the specified config file
would apply to each separate instance of
GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be
'misusing' the ScriptContext a bit. In addition, if
there is an error in your config script, you would
get an exception the first time you try to
eval/compile something, and not on instantiation of
the ScriptEngine.
I wonder what others think of this? I'm willing to
create a pull request for this functionality,
provided I get some direction on which approach would
be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
--
Cédric Champeau
Groovy language developer
http://twitter.com/CedricChampeau
http://melix.github.io/blog
Maarten Boekhold
2015-02-02 08:06:38 UTC
Permalink
Cedric,

I think you are missing the point somewhat. I don't have access to the
code of the application that uses the JSR-223 API, so I CANNOT change it
to use the Groovy APIs.

And I still don't understand why using system properties is not thread-safe?

To answer your last 2 questions:

1. do you *really* need to rely on JSR 223

Yes, I have no choice. I need to write groovy scripts for a
closed-source app that uses the JSR-223 API.

2. if yes, then do we want to build an inherently unsafe script engine
to be able to workaround JSR limitations?

Apart from your comment on multiple applications inside the same
appserver, I still don't really see how "unsafe" this is. The 3 ASTs
that I think would be used with this are:

- @Log injection: I would imagine that this is something you *want* for
*all* your compiled scripts. It's just a feature you provide to the
users who write the scripts to say "you have automatic access to a
variable called LOG that has methods info/debug/warn/error".
- SecureASTCustomizer: as the administrator of the application, I want
to prevent my "script writing users" from doing stuff like System.exit()
- Import Customizer: as the administrator of the app, I want to tell
users "you can access anything under my.custom.package without having to
add any imports to the script"

None of that is unsafe in my view.

Maarten
Post by Cédric Champeau
Ok let me be clear why I think using a Groovy specific API is better
in this case. First of all, JSR-223 was born with Groovy, so the the
script engines are pretty similar. But Groovy has evolved a lot, and
JSR-223 is far behind in terms of what you can do to configure the
engine (in short, nothing). The advantage of JSR-223 is if you want to
switch from one engine (Groovy) to another (Nashorn) or if you want to
support multiple scripting languages for the same application. So far
so good, but as you noticed Groovy unleashes its full potential when
you configure the engine, allowing you to have much better DSLs.
Otherwise integration is pretty ridiculous.
So, naturally, you want to configure the engine and JSR-223 does not
let you do this. So if you really need to leverage JSR-223 (which IMHO
is not the case for 95% of integration cases), you have a problem.
1. find *workarounds* in the Groovy JSR 223 engine to be able to fetch
configuration magically
2. work on an improved JSR 223 allowing to pass at least a map for
configuration data of the engine (I don't think we need more than that).
Of course as a user, you can't do 2, but you can submit the idea. So
what's left is 1. Unfortunately, as you noticed, "magically" has a lot
of drawbacks. It forces the Groovy JSR-223 engine to be inherently
unsafe *and* limited. Getting the configuration "magically" implies
that the engine fetches the configuration from a global dataset.
1. system properties. Easiest to implement, but global, so impossible
to have two distinct configurations for two kind of scripts. Can be
very problematic if you use Groovy in two applications hosted in the
same app server for example, because it could just break one
application. And as Jochen said, it's not thread-safe.
2. Thread locals. You can store the configuration local inside the
current thread, used to compile the script. The "Safest" approach, as
long as you take care of removing the configuration data from the
thread after the script is compiled, otherwise you create a memory leak.
3. Files. The script engine could search for configuration data in the
file system, in a specific place. Not any better than 1, and not
thread safe.
4. Classpath. It is a variant of 1 and 3, where you could push on
classpath a resource file that would be picked by the script engine.
Is has the advantage of isolating one application from the other, but
still, configuration is global in a single application.
1. do you *really* need to rely on JSR 223
2. if yes, then do we want to build an inherently unsafe script engine
to be able to workaround JSR limitations?
Post by Jim White
Ah, yes I see. Very nice.
I have a minor stylistic suggestion to make the naming more like the
COMPILER_CONFIG_SYSTEM_PROPERTY = "groovy.jsr223.option.configscript"
BASE_SCRIPT_SYSTEM_PROPERTY = "groovy.jsr223.option.basescript"
Not sure when I'll be able to give this a whirl. No hurry on getting
the JIRA and such set up but if you get stuck then I can help you out
with that.
Good work!
Jim
Hi Jim,
--configscript is already taken care of by my
"groovy.jsr223.compiler.configurator" System property. This one
takes the name of a file, which has the same syntax as what you
would provide to the --configscript option.
Good point about --basescript. I've added this to my patch now,
will push soon after gradlew test completes. I can't work on the
documentation part from here. Due to a corporate firewall I've
got big trouble getting gradlew asciidoc to run, and I can't
access my home computer at the moment (port forwarding screwed
up). Will see if I can do anything about documentation later
today/tomorrow.
https://github.com/boekhold/groovy-core/compare/feature/JSR-223-CompilerConfig
Maarten
Post by Jim White
This excellent Maarten! I haven't done any JSR-223 in a long
while and didn't realize the ability to specify the
CompilerConfiguration wasn't supported (I did the original
JSR-223 implementation for Groovy, Scala, Jython, and a couple
other languages as part of the development for IFCX Wings
<http://www.ifcx.org/wiki/Wings.html>).
Using a system property is indeed the correct design (you can
see it used elsewhere
<https://github.com/jruby/jruby/wiki/RedBridge> the same way
with JRuby for example). Other options that would be useful to
specify would be the base script (--basescript) and
configuration script (--configscript).
As for folks trying to persuade you to "use a Groovy specific
API", I'm sure you understand what they don't which is that
where JSR-223 is used (a standard Java API used in thousands of
systems) that is a non-option.
You need to set up a JIRA issue to track this work.
Jim
On Sun, Feb 1, 2015 at 4:41 AM, Maarten Boekhold
Hi,
If you want something concrete to look at, here's the link
to a feature branch on my own fork of groovy-core that
https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all
pass. I also know that the code I inserted in the default
constructor /in theory/ works because I've used almost the
same code in another project (and I stole it from the
groovyc source :)).
Maarten
Hmmm,
thinking about this a bit more, I think that option 2
(using ScriptContext) is a dead-end: it would prevent
any existing/closed application that relies on the
javax.script API from using the proposed functionality.
So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Hi all,
For a while now I've had this idea that it would be
useful if we could instruct the
GroovyScriptEngineImpl to use a
CompilerConfiguration similar to the -configfile
option to groovyc.
1. Use a system property that you set before
requesting your ScriptEngine instance
2. Use the 'default ScriptContext' to set a special
context variable containing the configuration script
name, and to do a lazy initialization of the
GroovyClassLoader.
Downside of (1) is that the specified config file
would apply to each separate instance of
GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be
'misusing' the ScriptContext a bit. In addition, if
there is an error in your config script, you would
get an exception the first time you try to
eval/compile something, and not on instantiation of
the ScriptEngine.
I wonder what others think of this? I'm willing to
create a pull request for this functionality,
provided I get some direction on which approach
would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
--
Cédric Champeau
Groovy language developer
http://twitter.com/CedricChampeau
http://melix.github.io/blog
Cédric Champeau
2015-02-02 08:30:26 UTC
Permalink
Post by Maarten Boekhold
Cedric,
I think you are missing the point somewhat. I don't have access to the
code of the application that uses the JSR-223 API, so I CANNOT change it to
use the Groovy APIs.
No really I see why you would be forced to use it, but my answer is to the
more general question about how to workaround the limited jsr-223 api, not
your specific use case (because since you are trying to modify Groovy to
adapt to this use case, then if it has to go to Groovy jsr-223 module, then
we need to ensure it is the best solution).
Post by Maarten Boekhold
And I still don't understand why using system properties is not thread-safe?
Because system properties are by definition system wide. So even if in your
mind, the idea is to provide a system property at startup and never change
it, you can be pretty sure that people will abuse it. By abuse it, I mean
face the situation I described where you need 2 different configurations
for 2 different kind of scripts. And the Groovy script engine documentation
will say something like "the script engine will search for a script
configuration file which path is defined through the xxx system property".
Ohhh, right, I just need to set the system property before creating the
engine?

System.setProperty("xxx", "path/to/config.groovy"); createEngine();

Imagine that you do this in 2 distinct threads and bad things will happen.
Our responsability is to avoid that kind of situations as much as possible,
so avoid, IMHO, promoting situations which are unsafe. A system property
should IMHO always be considered as a last resort workaround. Last but not
least, each call to System.getProperty() is blocking. That means that if
the application tries to read the system property from different threads,
for example one script in each thread, then you have a race condition.
Post by Maarten Boekhold
1. do you *really* need to rely on JSR 223
Yes, I have no choice. I need to write groovy scripts for a closed-source
app that uses the JSR-223 API.
Ok so legitimate to ask, and reinforces my idea that we need a better
JSR-223 :)
Post by Maarten Boekhold
2. if yes, then do we want to build an inherently unsafe script engine to
be able to workaround JSR limitations?
Apart from your comment on multiple applications inside the same
appserver, I still don't really see how "unsafe" this is. The 3 ASTs that I
*all* your compiled scripts. It's just a feature you provide to the users
who write the scripts to say "you have automatic access to a variable
called LOG that has methods info/debug/warn/error".
- SecureASTCustomizer: as the administrator of the application, I want to
prevent my "script writing users" from doing stuff like System.exit()
- Import Customizer: as the administrator of the app, I want to tell users
"you can access anything under my.custom.package without having to add any
imports to the script"
None of that is unsafe in my view.
Unsafe as described in the system property case: we have to think about
the general case, where bad things will happen.
Post by Maarten Boekhold
Maarten
Ok let me be clear why I think using a Groovy specific API is better in
this case. First of all, JSR-223 was born with Groovy, so the the script
engines are pretty similar. But Groovy has evolved a lot, and JSR-223 is
far behind in terms of what you can do to configure the engine (in short,
nothing). The advantage of JSR-223 is if you want to switch from one engine
(Groovy) to another (Nashorn) or if you want to support multiple scripting
languages for the same application. So far so good, but as you noticed
Groovy unleashes its full potential when you configure the engine, allowing
you to have much better DSLs. Otherwise integration is pretty ridiculous.
So, naturally, you want to configure the engine and JSR-223 does not let
you do this. So if you really need to leverage JSR-223 (which IMHO is not
the case for 95% of integration cases), you have a problem. There are two
1. find *workarounds* in the Groovy JSR 223 engine to be able to fetch
configuration magically
2. work on an improved JSR 223 allowing to pass at least a map for
configuration data of the engine (I don't think we need more than that).
Of course as a user, you can't do 2, but you can submit the idea. So
what's left is 1. Unfortunately, as you noticed, "magically" has a lot of
drawbacks. It forces the Groovy JSR-223 engine to be inherently unsafe
*and* limited. Getting the configuration "magically" implies that the
1. system properties. Easiest to implement, but global, so impossible to
have two distinct configurations for two kind of scripts. Can be very
problematic if you use Groovy in two applications hosted in the same app
server for example, because it could just break one application. And as
Jochen said, it's not thread-safe.
2. Thread locals. You can store the configuration local inside the current
thread, used to compile the script. The "Safest" approach, as long as you
take care of removing the configuration data from the thread after the
script is compiled, otherwise you create a memory leak.
3. Files. The script engine could search for configuration data in the
file system, in a specific place. Not any better than 1, and not thread
safe.
4. Classpath. It is a variant of 1 and 3, where you could push on
classpath a resource file that would be picked by the script engine. Is has
the advantage of isolating one application from the other, but still,
configuration is global in a single application.
1. do you *really* need to rely on JSR 223
2. if yes, then do we want to build an inherently unsafe script engine to
be able to workaround JSR limitations?
Ah, yes I see. Very nice.
I have a minor stylistic suggestion to make the naming more like the
COMPILER_CONFIG_SYSTEM_PROPERTY = "groovy.jsr223.option.configscript"
BASE_SCRIPT_SYSTEM_PROPERTY = "groovy.jsr223.option.basescript"
Not sure when I'll be able to give this a whirl. No hurry on getting
the JIRA and such set up but if you get stuck then I can help you out with
that.
Good work!
Jim
Post by Maarten Boekhold
Hi Jim,
--configscript is already taken care of by my
"groovy.jsr223.compiler.configurator" System property. This one takes the
name of a file, which has the same syntax as what you would provide to the
--configscript option.
Good point about --basescript. I've added this to my patch now, will push
soon after gradlew test completes. I can't work on the documentation part
from here. Due to a corporate firewall I've got big trouble getting gradlew
asciidoc to run, and I can't access my home computer at the moment (port
forwarding screwed up). Will see if I can do anything about documentation
later today/tomorrow.
https://github.com/boekhold/groovy-core/compare/feature/JSR-223-CompilerConfig
Maarten
This excellent Maarten! I haven't done any JSR-223 in a long while and
didn't realize the ability to specify the CompilerConfiguration wasn't
supported (I did the original JSR-223 implementation for Groovy, Scala,
Jython, and a couple other languages as part of the development for IFCX
Wings <http://www.ifcx.org/wiki/Wings.html>).
Using a system property is indeed the correct design (you can see it
used elsewhere <https://github.com/jruby/jruby/wiki/RedBridge> the same
way with JRuby for example). Other options that would be useful to specify
would be the base script (--basescript) and configuration script
(--configscript).
As for folks trying to persuade you to "use a Groovy specific API", I'm
sure you understand what they don't which is that where JSR-223 is used (a
standard Java API used in thousands of systems) that is a non-option.
You need to set up a JIRA issue to track this work.
Jim
Post by Maarten Boekhold
Hi,
If you want something concrete to look at, here's the link to a feature
https://github.com/boekhold/groovy-core/compare/groovy:master...feature/JSR-223-CompilerConfig
No test cases/docs added yet, but existing test cases all pass. I also
know that the code I inserted in the default constructor /in theory/ works
because I've used almost the same code in another project (and I stole it
from the groovyc source :)).
Maarten
Post by Maarten Boekhold
Hmmm,
thinking about this a bit more, I think that option 2 (using
ScriptContext) is a dead-end: it would prevent any existing/closed
application that relies on the javax.script API from using the proposed
functionality. So I guess this would have to work based on a System
property (groovy.jsr223.compiler.configurator=XXXX).
Maarten
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration similar
to the -configfile option to groovyc.
1. Use a system property that you set before requesting your
ScriptEngine instance
2. Use the 'default ScriptContext' to set a special context variable
containing the configuration script name, and to do a lazy initialization
of the GroovyClassLoader.
Downside of (1) is that the specified config file would apply to each
separate instance of GroovyScriptEngineImpl, which might not be what you
want. Downside to (2) is that this seems to be 'misusing' the ScriptContext
a bit. In addition, if there is an error in your config script, you would
get an exception the first time you try to eval/compile something, and not
on instantiation of the ScriptEngine.
I wonder what others think of this? I'm willing to create a pull
request for this functionality, provided I get some direction on which
approach would be acceptable to the core team.
Maarten
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
--
Cédric Champeau
Groovy language developerhttp://twitter.com/CedricChampeauhttp://melix.github.io/blog
Maarten Boekhold
2015-02-02 08:53:36 UTC
Permalink
Hi,
Post by Cédric Champeau
Because system properties are by definition system wide. So even if in
your mind, the idea is to provide a system property at startup and
never change it, you can be pretty sure that people will abuse it. By
abuse it, I mean face the situation I described where you need 2
different configurations for 2 different kind of scripts. And the
Groovy script engine documentation will say something like "the script
engine will search for a script configuration file which path is
defined through the xxx system property". Ohhh, right, I just need to
set the system property before creating the engine?
System.setProperty("xxx", "path/to/config.groovy"); createEngine();
Imagine that you do this in 2 distinct threads and bad things will
happen. Our responsability is to avoid that kind of situations as much
as possible, so avoid, IMHO, promoting situations which are unsafe. A
system property should IMHO always be considered as a last resort
workaround. Last but not least, each call to System.getProperty() is
blocking. That means that if the application tries to read the system
property from different threads, for example one script in each
thread, then you have a race condition.
OK, I see that point. On the other hand, you are now thinking about a
situation where a user clearly has access to the source code. So
following your earlier logic, since they are trying to do something
groovy-specific, they should just use the groovy API directly instead of
the JSR-223 API.

In fact, that's something I do in another app that I *do* have source
access to. This app uses the JSR-223 API and expects CompiledScript
instances internally. Specifically for groovy, I create and set up a
GroovyClassLoader (with CompilerConfiguration), a
GroovyScriptEngineImpl, and then do something like:

final Class scriptClass =
groovyClassLoader.parseClass(code, basename);
final CompiledScript script = new
GroovyCompiledScript(groovyScriptEngine, scriptClass);

I use gcl.parseClass() because that gives me control over the name of
the generated class, which turns out to be convenient for this
particular application.

Maarten

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jim White
2015-02-02 08:59:25 UTC
Permalink
Post by Cédric Champeau
Post by Maarten Boekhold
And I still don't understand why using system properties is not thread-safe?
Because system properties are by definition system wide. So even if in
your mind, the idea is to provide a system property at startup and never
change it, you can be pretty sure that people will abuse it. By abuse it, I
mean face the situation I described where you need 2 different
configurations for 2 different kind of scripts. And the Groovy script
engine documentation will say something like "the script engine will search
for a script configuration file which path is defined through the xxx
system property". Ohhh, right, I just need to set the system property
before creating the engine?
System.setProperty("xxx", "path/to/config.groovy"); createEngine();
System properties are indeed a per VM singleton and they are a Java
standard method for configuring global options. Folks who need to set a
system property more than once can get into trouble but the API is there to
address those issues when they arise. If you want thread local system
properties then you must set a suitable implementation using
System.setProperties. Ah, the top google hit
<https://www.google.com/webhp?ie=UTF-8#q=java%20thread%20local%20system%20properties>
for "thread local system properties" is an SO article that even gives you
the code for it. There are of course other ways to handle such conflicts
like a global lock which is trivial to implement. The fact that Java
system properties aren't all that simple is demonstrated by the existence
of System.clearProperty.

But the point here is that how to set system properties is well known and
the systems that use the JSR-223 know how to handle them. Use cases range
from the simple with -D options on the command line to elaborate per-thread
schemes. Therefore Groovy's JSR-223 implementation needs to use standard
APIs when it is used by Java systems, not just Groovy developers. That is
called system design and supporting Groovy's full capabilities using a
simple standard API is a good thing.

Your objection to this feature is that you can imagine a scenario where
someone could have a complicated multi-engine, multi-threaded JVM execution
environment using JSR-223 but might not know that System.properties is a
global. Not really buying that here as being any sort of real case.

Jim
Jochen Theodorou
2015-02-02 09:50:02 UTC
Permalink
Am 02.02.2015 09:59, schrieb Jim White:
[...]
Post by Jim White
Your objection to this feature is that you can imagine a scenario where
someone could have a complicated multi-engine, multi-threaded JVM
execution environment using JSR-223 but might not know that
System.properties is a global. Not really buying that here as being any
sort of real case.
that does not quite hit the target. multi-engine, yes. multi-threaded
might be or not. And I am sure they know System.properties is global.
But does the scripting API require you to somehow isolate
System.properties? If yes, please point me to the javadoc for this.
Because if it is not documented, you can expect people not doing that.
And even the thread local approach will not solve the problem if two
eval calls are made in the same thread down the line.

bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jim White
2015-02-05 09:48:04 UTC
Permalink
There is nothing in this configuration option for the Groovy JSR-223
ScriptEngine that *requires* isolation of the system properties. As I said
that scenario only appears in the case Cedric proposed where a developer
built a multi-engine, multi-threaded environment but overlooked the need to
manage a variable correctly. The "requirement" is entirely dependent on
what that system needs to do and isn't specific to this ScriptEngine
implementation.

And there is no "down the line". The system property settings are only
used during the call to the factory to get a suitably configured engine.
This is exactly like thousands of other Java libraries as well as Java
itself.

Furthermore I pointed out that the JRuby folks also found precisely this
same solution for the same problem. Why will this solution work for them
but not Groovy?

Jim
Post by Jochen Theodorou
[...]
Post by Jim White
Your objection to this feature is that you can imagine a scenario where
someone could have a complicated multi-engine, multi-threaded JVM
execution environment using JSR-223 but might not know that
System.properties is a global. Not really buying that here as being any
sort of real case.
that does not quite hit the target. multi-engine, yes. multi-threaded
might be or not. And I am sure they know System.properties is global. But
does the scripting API require you to somehow isolate System.properties? If
yes, please point me to the javadoc for this. Because if it is not
documented, you can expect people not doing that. And even the thread local
approach will not solve the problem if two eval calls are made in the same
thread down the line.
bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Cédric Champeau
2015-02-05 15:43:38 UTC
Permalink
Post by Jim White
There is nothing in this configuration option for the Groovy JSR-223
ScriptEngine that *requires* isolation of the system properties. As I
said that scenario only appears in the case Cedric proposed where a
developer built a multi-engine, multi-threaded environment but overlooked
the need to manage a variable correctly.
That's not the case I fear worst. It's actually a different one which is
IMHO more problematic: developer A builds an application based on JSR-223
and the system property. Developer B does the same for his application.
Both are hosted in the same VM. Bad things happen. I am confident that it
is not a very common case, but it may happen.

The "requirement" is entirely dependent on what that system needs to do and
Post by Jim White
isn't specific to this ScriptEngine implementation.
And there is no "down the line". The system property settings are only
used during the call to the factory to get a suitably configured engine.
This is exactly like thousands of other Java libraries as well as Java
itself.
As I said I think it's a good idea to avoid system properties as much as
possible, because there are many, many drawbacks (JVM wide,
synchronization, locking issues, ...) which are too often overlooked.
Post by Jim White
Furthermore I pointed out that the JRuby folks also found precisely this
same solution for the same problem. Why will this solution work for them
but not Groovy?
I don't call it a solution. I call it a workaround. The solution is to
have a better JSR-223 that is aware that configuration is important.
Meanwhile, we have to find hacks, workarounds, "solutions", but it must be
understood that it is broken by design.
Post by Jim White
Jim
Post by Jochen Theodorou
[...]
Post by Jim White
Your objection to this feature is that you can imagine a scenario where
someone could have a complicated multi-engine, multi-threaded JVM
execution environment using JSR-223 but might not know that
System.properties is a global. Not really buying that here as being any
sort of real case.
that does not quite hit the target. multi-engine, yes. multi-threaded
might be or not. And I am sure they know System.properties is global. But
does the scripting API require you to somehow isolate System.properties? If
yes, please point me to the javadoc for this. Because if it is not
documented, you can expect people not doing that. And even the thread local
approach will not solve the problem if two eval calls are made in the same
thread down the line.
bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Jochen Theodorou
2015-02-06 10:23:50 UTC
Permalink
Am 05.02.2015 16:43, schrieb Cédric Champeau:
[...]
Post by Jim White
I don't call it a solution. I call it a workaround. The solution is to
have a better JSR-223 that is aware that configuration is important.
Meanwhile, we have to find hacks, workarounds, "solutions", but it must
be understood that it is broken by design.
I doubt there will be a better JSR-223 any time soon. I am torn in
regards to this solution, since I have the same fears and thought about
this for quite a while. Clearly stating the shortcomings in the
documentation should be enough. If then something bad happens, then it
happens, but they have been warned.

bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jim White
2015-02-07 07:23:55 UTC
Permalink
Post by Cédric Champeau
Post by Jim White
There is nothing in this configuration option for the Groovy JSR-223
ScriptEngine that *requires* isolation of the system properties. As I
said that scenario only appears in the case Cedric proposed where a
developer built a multi-engine, multi-threaded environment but overlooked
the need to manage a variable correctly.
That's not the case I fear worst. It's actually a different one which is
IMHO more problematic: developer A builds an application based on JSR-223
and the system property. Developer B does the same for his application.
Both are hosted in the same VM. Bad things happen. I am confident that it
is not a very common case, but it may happen.
Yes I agree. If you use a programming language that permits the writing
off bugs then there is that danger. Glad that can't happen with Groovy!
Post by Cédric Champeau
The "requirement" is entirely dependent on what that system needs to do
Post by Jim White
and isn't specific to this ScriptEngine implementation.
And there is no "down the line". The system property settings are only
used during the call to the factory to get a suitably configured engine.
This is exactly like thousands of other Java libraries as well as Java
itself.
As I said I think it's a good idea to avoid system properties as much as
possible, because there are many, many drawbacks (JVM wide,
synchronization, locking issues, ...) which are too often overlooked.
Sure. If you have a superior alternative please do suggest it.
Post by Cédric Champeau
Furthermore I pointed out that the JRuby folks also found precisely this
Post by Jim White
same solution for the same problem. Why will this solution work for them
but not Groovy?
I don't call it a solution. I call it a workaround. The solution is to
have a better JSR-223 that is aware that configuration is important.
Meanwhile, we have to find hacks, workarounds, "solutions", but it must be
understood that it is broken by design.
Sticks and stones etc. JSR-223 is a very successful Java standard. An
important concept that makes the fact that the JRuby designers chose this
same design is that from a JSR-223 systems there is no difference between
Ruby and Groovy. Your dislike of JSR-223 is a good reason for you to not
use it but it is not a good reason to hobble Groovy's implementation of it.

Jim

Jochen Theodorou
2015-02-02 08:26:57 UTC
Permalink
Post by Cédric Champeau
Ok let me be clear why I think using a Groovy specific API is better in
this case. First of all, JSR-223 was born with Groovy, so the the script
engines are pretty similar. But Groovy has evolved a lot, and JSR-223 is
far behind in terms of what you can do to configure the engine (in
short, nothing). The advantage of JSR-223 is if you want to switch from
one engine (Groovy) to another (Nashorn) or if you want to support
multiple scripting languages for the same application. So far so good,
but as you noticed Groovy unleashes its full potential when you
configure the engine, allowing you to have much better DSLs. Otherwise
integration is pretty ridiculous.
It is not explicitly said here, but assuming you have some core element
that works on the abstraction layer provided by JSR-223 only, then you
can still have a reason to use the engine. that would then be unfortunate.

[...]
Post by Cédric Champeau
1. system properties. Easiest to implement, but global, so impossible to
have two distinct configurations for two kind of scripts. Can be very
problematic if you use Groovy in two applications hosted in the same app
server for example, because it could just break one application. And as
Jochen said, it's not thread-safe.
Wasn't me, was Sergey ;)
Post by Cédric Champeau
2. Thread locals. You can store the configuration local inside the
current thread, used to compile the script. The "Safest" approach, as
long as you take care of removing the configuration data from the thread
after the script is compiled, otherwise you create a memory leak.
3. Files. The script engine could search for configuration data in the
file system, in a specific place. Not any better than 1, and not thread
safe.
4. Classpath. It is a variant of 1 and 3, where you could push on
classpath a resource file that would be picked by the script engine. Is
has the advantage of isolating one application from the other, but
still, configuration is global in a single application.
those parts are not so critical in my eyes. I mean the approach of the
engine itself is not really safe already, so I care a bit less about
these points. The problem I see more with any of this approach is, that
using them will result in the configuration of all of the usage of the
engine, even those, that might be hidden from you. So even if you use
the engine only in a certain context, something else might do it different.

Why can't we use ScriptEngine.put(String,Object) for this? Ah wait... if
you have no rule over the API that uses the engine, you may also not
have access to the actually ScriptEngine instance used... bummer.

Still one point seems to hold... the scripting API is not made to have
non-global configuration. The script itself then needs to control that I
would assume.

bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Jochen Theodorou
2015-02-01 15:12:37 UTC
Permalink
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.
before diving into this further I would like to know one thing... The
purpose of that JSR223 script engine is to allow an abstraction layer
for different script engines of different languages... what you now
propose is something very specific to one engine. So the part I am
wondering about is, why this is done in the frame of JSR223 then?

I am asking specifically because the framework of JSR223 is quite limiting

bye blackdrag
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-01 15:21:54 UTC
Permalink
Hi,

- automatically apply @Slf4j annotation to generated script classes
- import customizers
- SecureASTCustomizer to limit what your users can do

These are very useful features, but you can't use them if the software
you are working with can only execute scripts through the JSR223 API.

Maarten
Post by Jochen Theodorou
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.
before diving into this further I would like to know one thing... The
purpose of that JSR223 script engine is to allow an abstraction layer
for different script engines of different languages... what you now
propose is something very specific to one engine. So the part I am
wondering about is, why this is done in the frame of JSR223 then?
I am asking specifically because the framework of JSR223 is quite limiting
bye blackdrag
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Cédric Champeau
2015-02-01 16:40:28 UTC
Permalink
Definitely. That is also why I think we need a better JSR-223. But... If
you start doing something specific to Groovy, be it with a system variable
or anything else, then you have a special case in your code to handle
Groovy code... Then why not go directly through the richer Groovy specific
API?

One big issue I see with system properties is that they are global, so it
assumes that all scripts share the same configuration, which is in general
not true...
Post by Maarten Boekhold
Hi,
- import customizers
- SecureASTCustomizer to limit what your users can do
These are very useful features, but you can't use them if the software you
are working with can only execute scripts through the JSR223 API.
Maarten
Post by Jochen Theodorou
Post by Maarten Boekhold
Hi all,
For a while now I've had this idea that it would be useful if we could
instruct the GroovyScriptEngineImpl to use a CompilerConfiguration
similar to the -configfile option to groovyc.
before diving into this further I would like to know one thing... The
purpose of that JSR223 script engine is to allow an abstraction layer for
different script engines of different languages... what you now propose is
something very specific to one engine. So the part I am wondering about is,
why this is done in the frame of JSR223 then?
I am asking specifically because the framework of JSR223 is quite limiting
bye blackdrag
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Maarten Boekhold
2015-02-01 18:34:09 UTC
Permalink
Hi,

No, no need for any changes in your (jsr223) code, just a "-D...=..." on
your java command line. And I'm not aware of any Java app where you
don't have the option of adding additional system properties to the
command line in one way or another.

With system properties, yes, the effect is global, but I think the 3
cases I listed below are general enough that a global option can apply.

I didn't actually bring this up out of a pure theoretical point of view.
I do actually have a use case myself where I would want this.
Unfortunately in my case my proposed patch won't help, because the app
I'm working with is still using groovy 2.1.8 and it won't upgrade
anytime soon. But I figured if I could use this, then so could others,
possibly...

Maarten
Post by Cédric Champeau
Definitely. That is also why I think we need a better JSR-223. But...
If you start doing something specific to Groovy, be it with a system
variable or anything else, then you have a special case in your code
to handle Groovy code... Then why not go directly through the richer
Groovy specific API?
One big issue I see with system properties is that they are global, so
it assumes that all scripts share the same configuration, which is in
general not true...
Hi,
- import customizers
- SecureASTCustomizer to limit what your users can do
These are very useful features, but you can't use them if the
software you are working with can only execute scripts through the
JSR223 API.
Maarten Boekhold
2015-02-03 12:27:24 UTC
Permalink
Hi all,

I've created https://jira.codehaus.org/browse/GROOVY-7286 to track this
enhancement request.

Maarten
Post by Maarten Boekhold
Hi,
No, no need for any changes in your (jsr223) code, just a "-D...=..."
on your java command line. And I'm not aware of any Java app where you
don't have the option of adding additional system properties to the
command line in one way or another.
With system properties, yes, the effect is global, but I think the 3
cases I listed below are general enough that a global option can apply.
I didn't actually bring this up out of a pure theoretical point of
view. I do actually have a use case myself where I would want this.
Unfortunately in my case my proposed patch won't help, because the app
I'm working with is still using groovy 2.1.8 and it won't upgrade
anytime soon. But I figured if I could use this, then so could others,
possibly...
Maarten
Post by Cédric Champeau
Definitely. That is also why I think we need a better JSR-223. But...
If you start doing something specific to Groovy, be it with a system
variable or anything else, then you have a special case in your code
to handle Groovy code... Then why not go directly through the richer
Groovy specific API?
One big issue I see with system properties is that they are global,
so it assumes that all scripts share the same configuration, which is
in general not true...
Hi,
- import customizers
- SecureASTCustomizer to limit what your users can do
These are very useful features, but you can't use them if the
software you are working with can only execute scripts through
the JSR223 API.
Loading...