Thanks for your suggestions Keith, but this approch doesn't feel very straight 
forward. What I really like to, is to be able to forward these "sticky imports 
between script invocations" as a feature suggestion. This makes Groovy even 
more suitable as a language for quick embedded mock-ups. Who in the dev team 
can comment on this?

Regards
/David

> On 10 Feb 2018, at 21:25, Keith Suderman <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>
> 
> 
> 
> 

Reply via email to