polygene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niclas Hedhman <hedh...@gmail.com>
Subject Re: javax.script
Date Sun, 09 Apr 2017 04:31:45 GMT
So, I have an isolated version running. A performance test would be
"interesting"...

This is now in libraries/scripting and I am dropping the libraries/lang-*
as they are no longer required.

Also, there are tons of languages that are integrated into the javax.script
for JVM. These I found by searching on my own,

Groovy (Apache)
Python (Jython)
Ruby (JRuby)
Kotlin (Jetbrains)
Scheme (Kawa from GNU)
R (Renjin)
LISP (Armed Bear Common Lisp)

but eventually I found
https://java.net/projects/scripting/sources/svn/show/trunk/engines
And that lists quite a few more languages.

Now, I don't intend to test for all of these, but I think we should enable
as many as possible if/when issues are reported. I.e. the ambition is to
support them all, but served on a case-by-case basis.

I am adding some convenience for common languages.

public class Scripting
{
    public static final Scripting JAVASCRIPT = new Scripting(
"nashorn", ".js" );
    public static final Scripting ECMASCRIPT = new Scripting(
"nashorn", ".js" );
    public static final Scripting GROOVY = new Scripting( "groovy", ".groovy" );
    public static final Scripting RUBY = new Scripting( "jruby", ".rb" );
    public static final Scripting PYTHON = new Scripting( "python", ".py" );
    public static final Scripting KOTLIN = new Scripting( "kotlin", ".kt" );


But constructors are public...

Currently I have language to be declared on the Composite type;

    module.transients( DomainType.class ).setMetaInfo(
Scripting.JAVASCRIPT ).withMixins( ScriptMixin.class );


But thinking that perhaps it is better to have the script name declared as
MetaInfo

    module.transients( DomainType.class ).setMetaInfo( new
Scripting("domain.py") ).withMixins( ScriptMixin.class );

OR, I could change it to not use any MetaInfo and search for implementation
by extension, and whatever is found is used.

Feedback on that is appreciated.


Reloading is supported with the interface ScriptReloadable, just like
before. Add the interface to the composite type to make it available.

Scripting allows redirect of stdout/stderr/stdin, and I support that. Just
add interface ScriptRedirect to the composite type.

The following bindings are made to the script environment (if I missed
something import, let me know)


    mixinBindings.put( "Polygene", spi );
    mixinBindings.put( "application", application );
    mixinBindings.put( "layer", layer );
    mixinBindings.put( "module", module );
    mixinBindings.put( "This", thisComposite );
    mixinBindings.put( "state", state );
    mixinBindings.put( "objectFactory", module.objectFactory() );
    mixinBindings.put( "unitOfWorkFactory", module.unitOfWorkFactory() );
    mixinBindings.put( "valueBuilderFactory", module.valueBuilderFactory() );
    mixinBindings.put( "transientBuilderFactory",
module.transientBuilderFactory() );
    mixinBindings.put( "serviceFinder", module.serviceFinder() );
    mixinBindings.put( "typeLookup", module.typeLookup() );


FInally, there is support for context attributes, but likely not used that
much. Both ENGINE and GLOBAL attributes are accessible via the
ScriptAttributes (ScriptAttributes.All) interface.

I find it quite hard to support "invokeMethod" in the invocable interface,
as one first would need to instantiate an object, in those languages that
has objects or equivalent, and then call methods there on. I think thar
"invokeFunction" is in reality enough, and other variants of what is
possible in "eval()" can be skipped for our purposes.

I have tried to update the documentation to the best of my abilities. More
meat is always welcome, as well as testing and docs for other languages,
especially those that I mark as supported.

This is quite a massive feature that was easy to implement. In 3.1, I think
we should expand this to somehow support other fragments to be implemented
in scripts as well. I think we are really living up to the POLYgene part.


Feedback?





On Sun, Apr 9, 2017 at 7:22 AM, Niclas Hedhman <hedhman@gmail.com> wrote:

>
> Ok, I will try to figure out if single compile per composite type is
> possible. My initial finding is that it is not.
>
> Expect it to complete today.
>
> On Apr 8, 2017 20:58, "Paul Merlin" <paulmerlin@apache.org> wrote:
>
> Having a script scope per composite instance makes sense to me. Script
> scopes allows scripts to hold state, we don't want to share state
> between composite instances. Just like you said, this is not a
> performance issue for Services. And if you need single use composites
> then that's probably because you don't want to share their state.
>
> Ideally we would be able to do the "compilation" once per composite type
> and then "clone" the scope, or use "sub-contexts" for each instance.
> Don't know if that's possible using the javax.scripting api though.
>
>
>
> Niclas Hedhman a écrit :
> > Hi,
> > I mentioned yesterday that I am working on putting javax.script as the
> > integration point with JavaScript and Groovy instead of our direct
> > dependencies on each.
> >
> > There is one thing that 'bothers me'; Scopes.
> >
> > So a single class ScriptMixin will handle the reading and invoking the
> > javax.script side, but what is the scope?
> >
> > ScriptMixin is the supplied Mixin to any number of Composite Types for
> any
> > number of interfaces and methods.
> >
> > I *could* create one ScriptEngine per method, or per
> method.declaringClass,
> > or per Composite primary type or per Polygene runtime.
> >
> > A ScriptEngine has ScriptContexts which in turn holds the Bindings. The
> > Bindings contain the integration objects (accessible in both Java and
> > script language) as well as the script itself. ScriptContext holds 2
> > Bindings (GLOBAL and ENGINE), and the handling of them internally is
> > non-intuituve.
> >
> > Now, the question is what is the scope of the script itself? Should it
> be a
> > global script per primary type, or should we isolate each composite
> > instance with its own script engine? Or should it be a global script
> > environment to really open the gates of problems?
> >
> > I tend to lean on "script engine per composite instance", but it feels a
> > bit heavy-handed. I guess it doesn't matter which one if the use is
> > Services, but for short-lived composites it would also mean one compile
> > cycle per creation (==slow?)
> >
> > Ideas and feedback most welcome.
> >
> >
> > For those who have no idea what I am talking about;
> >
> > It has been possible to implement the mixin methods of composites in
> other
> > languages, such as JavaScript and Groovy.
> >
> > package com.abc.script;
> >
> > @Mixins( ScriptMixin.class )
> > public interface SomeType extends ScriptReloadable
> > {
> >     String doMyBidding( String whatever );
> > }
> >
> > and then have (for instance) JavaScript in a resource
> > com/abc/script/SomeType.js with;
> >
> > function doMyBidding( whatever ) {
> >     return "Great: " + whatever;
> > }
> >
> > and the ScriptReloadable.reloadScript() will recompile it for next time,
> > i.e code replacement in runtime.
> >
> > Inside the script environment, things like serviceFinder,
> > valueBuilderFactory and so on are available as global variables.
> >
> > Cheers
>
>
>


-- 
Niclas Hedhman, Software Developer
http://zest.apache.org - New Energy for Java

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message