Hi David,

I am not a Groovy committer and I am not that familiar with the Groovy code 
base so _I_ can't revise the JSR-223 implementation.  I did take a quick look 
at the code, and other than having "GroovyScriptEngine" in their names the two 
classes (GroovyScriptEngine and GroovyScriptEngineImpl) have nothing in common 
and parse/load Groovy code in completely different ways.  I suspect adding a 
feature like you want would be a non-trivial undertaking.  Maybe one of the 
active committers (Paul, Daniel, et al)  can comment.

However, I suspect that the GroovyScriptEngineImpl class is "crippled" by 
JSR-223 itself as it caters to the lowest common denominator

- Keith

> On Oct 31, 2018, at 12:12 PM, David Ekholm <da...@jalbum.net> wrote:
> 
> Hi Keith,
> 
> I'm "resurrecting" this old thread in an attept to see if we can use Groovy 
> as the next scritpting language in jAlbum. What I'd really want to achive is 
> to supply a number of default star imports. This is expecially important as 
> Groovy sadly doesn't remember imports between script invocations.
> 
> I looked at your code suggetion below and tried to fit it to JSR-223 
> (javax.script API) but it fails as the GroovyScriptEngineImpl class I get 
> from that API doesn't extend the GroovyScriptEngine class. It's only the 
> GroovyScriptEngine class that supplies the important setConfig method.
> 
> Could you revise the JSR-223 implementation so it isn't unnecessary crippled 
> compared to the GroovyShell API, at very least add the setConfig method to 
> the GroovyScriptEngineImpl class? If we're to use the GroovyShell API, then 
> we need to introduce our own abstraction layer in order to continue 
> supporting multiple scripting languages in jAlbum.
> 
> Regards
> /David, jAlbum founder
> 
>> On 10 Feb 2018, at 21:25, Keith Suderman <suder...@anc.org 
>> <mailto:suder...@anc.org>> wrote:
>> 
>> Import statements are really just shortcuts to tell the compiler how to 
>> resolve class names so there is nothing to "remember" between invocations, 
>> that is, nothing gets added to the Binding.
>> 
>> I am not familiar with the javax.script API, but I suspect that you will 
>> have to provide your own ScriptEngine implementation as you will need to 
>> modify the CompilerConfiguration object the GroovyShell is using to compile 
>> the Groovy code.  For example:
>> 
>>         CompilerConfiguration configuration = new CompilerConfiguration()
>>         GroovyShell compiler = new GroovyShell(configuration)
>>         println compiler.evaluate('json=\'{"foo":"bar"}\'')
>>         println compiler.evaluate("groovy.json.JsonOutput.prettyPrint(json)")
>> 
>>         /* Fails: MissingPropertyException */
>>         /* println compiler.evaluate("JsonOutput.prettyPrint(json)") */
>> 
>>         ImportCustomizer imports = new ImportCustomizer()
>>         imports.addStarImports("groovy.json")
>>         configuration.addCompilationCustomizers(imports)
>>      // Works, the compiler can now resolve groovy.json.JsonOutput
>>         println compiler.evaluate("JsonOutput.prettyPrint(json)")
>> 
>> The difficult part will be "hooking" into the compiler to know when an 
>> import statement is used so you can update your CompilerConfiguration 
>> object.  I am sure the really clever programmers here could come up with 
>> some sort of AST transform that would do this.  However, depending on what 
>> you are allowed to do one option would be to tell your users that you have a 
>> "Groovy DSL" and then implement an "include" method that users would use to 
>> "import" Java packages.
>> 
>>         println eval('json=\'{"foo":"bar"}\'')
>>         println eval('include "groovy.json"')
>>         println eval('JsonOutput.prettyPrint(json)')
>>      
>>     Object eval(String code) {
>>         Script script = compiler.parse(code)
>>         ExpandoMetaClass metaClass = new ExpandoMetaClass(script.class, 
>> false)
>>         metaClass.include = { String name ->
>>             ImportCustomizer includes = new ImportCustomizer()
>>             includes.addStarImports(name)
>>             configuration.addCompilationCustomizers(includes)
>>             "Imported $name"
>>         }
>>         metaClass.initialize()
>>         script.metaClass = metaClass
>>         script.run()
>>     }
>> 
>> Hopefully that gives you some ideas.
>> 
>> Cheers,
>> Keith
>> 
>>> On Feb 8, 2018, at 3:47 PM, David Ekholm <da...@jalbum.net 
>>> <mailto:da...@jalbum.net>> wrote:
>>> 
>>> How do I do that via the javax.script API?
>>> 
>>> Even if this is possible via the javax.script API, chances are that a user 
>>> wishes to ad-hoc add another import, but as they are forgotten between 
>>> script invocations, it makes it hard to use Groovy to interactively create, 
>>> say a Swing or JavaFX UI one line at a time. With BeanShell, the user can 
>>> add the needed imports, execute that "script" and then continue to refer to 
>>> the imported classes in the following script invocations. Making Groovy 
>>> remember imports would make it behave in as nice fashion as the new JShell 
>>> tool in Java 9. JShell unfortunately cannot run embedded via the 
>>> javax.script API :-(
>>> 
>>> Regards
>>> /David
>>> 
>>>> On 8 Feb 2018, at 21:34, eric.mil...@thomsonreuters.com 
>>>> <mailto:eric.mil...@thomsonreuters.com> wrote:
>>>> 
>>>> You can add all the imports you want to your compiler configuration and 
>>>> they will be consistently available for all scripts.
>>>>  
>>>> From: David Ekholm [mailto:da...@jalbum.net <mailto:da...@jalbum.net>] 
>>>> Sent: Thursday, February 08, 2018 2:12 PM
>>>> To: dev@groovy.apache.org <mailto:dev@groovy.apache.org>
>>>> Subject: Remembering imports between script invocations 
>>>>  
>>>> We're considering supporting Groovy as an additional scripting language to 
>>>> our web gallery software jAlbum (http://jalbum.net 
>>>> <https://urldefense.proofpoint.com/v2/url?u=http-3A__jalbum.net&d=DwMFAg&c=4ZIZThykDLcoWk-GVjSLmy8-1Cr1I4FWIvbLFebwKgY&r=tPJuIuL_GkTEazjQW7vvl7mNWVGXn3yJD5LGBHYYHww&m=39n_uU4e7-n_s_WwrNC_8tQYLfhWKgmT_dDWwJw8ctA&s=jGwsu2zf5Pm3kG3GKLFFxalyi30aoXq_-izsMrEy_iQ&e=>),
>>>>  but one aspect bugs me: It doesn't seem like import statements are 
>>>> remembered between script invocations. This makes it far harder to use 
>>>> Groovy to prototype UIs within jAlbum's scripting console than for 
>>>> instance BeanShell (using the javax.script API). We currently support the 
>>>> slow BeanShell scripting language and JavaScript. BeanShell behaves well 
>>>> in this regard, remembering earlier imported packages between script 
>>>> invocations. Can this be added to Groovy or is there some API flag we can 
>>>> set?
>>>>  
>>>> Regards
>>>> /David, jAlbum founder and client lead developer.
>>> 
>> 
>> ----------------------
>> Keith Suderman
>> Research Associate
>> Department of Computer Science
>> Vassar College, Poughkeepsie NY
>> suder...@cs.vassar.edu <mailto:suder...@cs.vassar.edu>
>> 
>> 
>> 
>> 
> 



----------------------
Keith Suderman
Research Associate
Department of Computer Science
Vassar College, Poughkeepsie NY
suder...@cs.vassar.edu




Reply via email to