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> > > > >