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