groovy
  1. groovy
  2. GROOVY-1594

Bundle JSR 223 Support in Groovy

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0, 1.1-rc-3
    • Fix Version/s: 1.6-rc-1, 1.6-rc-2, 1.7.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      N/A
    • Number of attachments :
      1

      Description

      Now that Java 6 released, there's a lot of interest going around about the new JSR 223 scripting platform. Unfortunately, neither Java SE 6 nor the current Groovy builds support JSR 223-style Groovy out of the box.

      Fortunately, adding this to Groovy is trivial. The code is both simple and available from the JSR 223 reference implementation (https://scripting.dev.java.net/). The license permits redistributing as source or binary as long as mention that some code comes from Sun and release them from liability.

      Ideally, the Groovy project should integrate the three implementation classes and the service declaration into groovy-1.0.jar. If you do this, simply dropping Groovy into your classpath is enough to enable the Groovy engine. At the very least, we should bundle the RI's groovy-engine.jar into the groovy binary distribution. Finding and installing the Sun RI is a bit of a pain and will discourage would-be users.

      Behind the scenes, scripting engines get enabled by adding a file to the META-INF/services directory of a JAR as specified in the new Java 6 java.util.ServiceLoader (http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html). This file just tells the JVM that it can find a service implementation in a specific class. For JSR 223, the implementation is just a concrete ScriptEngineFactory and a couple of support classes:

      https://scripting.dev.java.net/source/browse/scripting/engines/groovy/src/META-INF/services/javax.script.ScriptEngineFactory?rev=1.1.1.1&view=auto&content-type=text/vnd.viewcvs-markup

      https://scripting.dev.java.net/source/browse/scripting/engines/groovy/src/com/sun/script/groovy/GroovyScriptEngineFactory.java?rev=1.4&view=auto&content-type=text/vnd.viewcvs-markup

      https://scripting.dev.java.net/source/browse/scripting/engines/groovy/src/com/sun/script/groovy/GroovyCompiledScript.java?rev=1.1.1.1&view=auto&content-type=text/vnd.viewcvs-markup

      https://scripting.dev.java.net/source/browse/scripting/engines/groovy/src/com/sun/script/groovy/GroovyScriptEngine.java?rev=1.4&view=auto&content-type=text/vnd.viewcvs-markup

      I'm happy to volunteer any assistance that might help make this part of the Groovy distribution. However, adding these classes and the service definition to groovy-1.0.jar should be trivial and will provide a great service (pun intended).

        Activity

        Hide
        John Wilson added a comment -

        Hi Andy!

        JSR 223 is largely irrelevant to Groovy.

        JSR 223 is really about trying to map language constructs from some arbitrary scripting language onto Java. So, basically it's a way of making a language which is Java unaware able to interact with Java code. It's like JNI in that respect (and about as beautiful!)

        Groovy is Java aware. We have spent all our time in reducing the impedance between Groovy and Java to zero. We really do not want to encourage the misapprehension that it requires some bit of plumbing to interface Groovy with Java. So My view is that we distance ourselves from JSR 223 and in no way encourage people to use it with Groovy.

        Show
        John Wilson added a comment - Hi Andy! JSR 223 is largely irrelevant to Groovy. JSR 223 is really about trying to map language constructs from some arbitrary scripting language onto Java. So, basically it's a way of making a language which is Java unaware able to interact with Java code. It's like JNI in that respect (and about as beautiful!) Groovy is Java aware. We have spent all our time in reducing the impedance between Groovy and Java to zero. We really do not want to encourage the misapprehension that it requires some bit of plumbing to interface Groovy with Java. So My view is that we distance ourselves from JSR 223 and in no way encourage people to use it with Groovy.
        Hide
        blackdrag blackdrag added a comment -

        irrelevant or not... we decided the 1.0 build should be doable with java 1.4, so we can't compile against java6.
        As you might see the groovy handling code there is partially from us or at last reviewed (thx to Guillaume Laforge). So if we provide a jar, then a separate one. We can put it on a page and talk about not to use it if you don't need to. But I see usage for JSR 223 in applications enabling users to change the engine and I see that they don't want to depend on special Groovy classes then.

        Show
        blackdrag blackdrag added a comment - irrelevant or not... we decided the 1.0 build should be doable with java 1.4, so we can't compile against java6. As you might see the groovy handling code there is partially from us or at last reviewed (thx to Guillaume Laforge). So if we provide a jar, then a separate one. We can put it on a page and talk about not to use it if you don't need to. But I see usage for JSR 223 in applications enabling users to change the engine and I see that they don't want to depend on special Groovy classes then.
        Hide
        Sarah Gerweck added a comment -

        I strongly disagree that Groovy won't benefit from JSR 223. I think this idea springs from a misunderstanding of JSR 223.

        A big piece of JSR 223 is a standardization and integration of Apache BSF. While JSR 223 is irrelevant if you want to write some of your application in Groovy and run like native Java code, it's very relevant if you want to use Groovy as an embedded scripting language.

        I have a couple of applications where I've been planning to integrate Groovy in just this way. To add customer-specific behavior in a back-end application, I store the scripting language and the text of the script in a database which the application queries before running a process. If an entry is present, it adds a step to (or replaces an existing step in) the process workflow. This is a fairly typical use case for interpreted embedding which is traditional role of a scripting language. I could use BSF, but I like the new standard—especially that I can add new scripting engines simply by putting them in my classpath thanks to Java 6's ServiceLoader.

        Groovy is a nice dynamic language useful for much more than scripting applications like those I described above. However, there are many perfectly good use cases where JSR 223 will help Groovy. Sure, I might get a little more functionality embedding Groovy directly, but I lose the ability to use JavaScript and dozens of other languages. There are important cases where you want to have a language-independent scripting API.

        Because of situations like these, I think it would be a mistake to discourage people from using JSR 223. It does make sense to point out that direct Groovy is much better for many applications and give guidance on where JSR 223 is beneficial.

        • Java 6 vs Java 1.4 *

        With respect to Java 6, you have a reasonable point. It really only needs the new javax.script interfaces and runs fine with Java 5 if you include the JSR 223 API. I think there are too many Java 5 features to get it easily building on Java 1.4.

        I should point out that the JVM won't complain about incompatible classes as long as you don't load them. There's no reason you couldn't bundle in the new classes and let them go unused on older JVMs. As long as the rest of Groovy were targeted for 1.4, it would work fine ... just a thought, not a (completely) serious proposal.

        I understand the desire to support J2SE 1.4, and would be happy enough if we just bundle in groovy-engine.jar with the standard distribution. In the long term, it might make sense to have a build option that bundles the engine classes into groovy.jar.

        Show
        Sarah Gerweck added a comment - I strongly disagree that Groovy won't benefit from JSR 223. I think this idea springs from a misunderstanding of JSR 223. A big piece of JSR 223 is a standardization and integration of Apache BSF. While JSR 223 is irrelevant if you want to write some of your application in Groovy and run like native Java code, it's very relevant if you want to use Groovy as an embedded scripting language. I have a couple of applications where I've been planning to integrate Groovy in just this way. To add customer-specific behavior in a back-end application, I store the scripting language and the text of the script in a database which the application queries before running a process. If an entry is present, it adds a step to (or replaces an existing step in) the process workflow. This is a fairly typical use case for interpreted embedding which is traditional role of a scripting language. I could use BSF, but I like the new standard—especially that I can add new scripting engines simply by putting them in my classpath thanks to Java 6's ServiceLoader. Groovy is a nice dynamic language useful for much more than scripting applications like those I described above. However, there are many perfectly good use cases where JSR 223 will help Groovy. Sure, I might get a little more functionality embedding Groovy directly, but I lose the ability to use JavaScript and dozens of other languages. There are important cases where you want to have a language-independent scripting API. Because of situations like these, I think it would be a mistake to discourage people from using JSR 223. It does make sense to point out that direct Groovy is much better for many applications and give guidance on where JSR 223 is beneficial. Java 6 vs Java 1.4 * With respect to Java 6, you have a reasonable point. It really only needs the new javax.script interfaces and runs fine with Java 5 if you include the JSR 223 API. I think there are too many Java 5 features to get it easily building on Java 1.4. I should point out that the JVM won't complain about incompatible classes as long as you don't load them. There's no reason you couldn't bundle in the new classes and let them go unused on older JVMs. As long as the rest of Groovy were targeted for 1.4, it would work fine ... just a thought, not a (completely) serious proposal. I understand the desire to support J2SE 1.4, and would be happy enough if we just bundle in groovy-engine.jar with the standard distribution. In the long term, it might make sense to have a build option that bundles the engine classes into groovy.jar.
        Hide
        blackdrag blackdrag added a comment -

        "JVM won't complain about incompatible classes as long as you don't load them", that might be right, but it means that we won't be able to test the classes.

        Show
        blackdrag blackdrag added a comment - "JVM won't complain about incompatible classes as long as you don't load them", that might be right, but it means that we won't be able to test the classes.
        Hide
        Guillaume Laforge added a comment -

        Andy,

        To benefit from JSR-223's Groovy engine, what is the minimal requirement?
        We just need the groovy-engine.jar as well as a JDK 1.6?
        If groovy-engine.jar were available in the maven repositories, it'd be very easy to bundle this jar with the Groovy distribution.
        Could you take care of this and see whether it's possible?

        Additionally, I think we could bundle the javax.script.* package recompiled for Java 1.5 as a jar, so that people using an 1.5 JVM can benefit from the JDK 6 scripting APIs.

        However, of course, as John explained, JSR-223 isn't the ideal mechanism to integrate Groovy into your applications. But I understand the desire to use a common API for various engines.

        Guillaume

        Show
        Guillaume Laforge added a comment - Andy, To benefit from JSR-223's Groovy engine, what is the minimal requirement? We just need the groovy-engine.jar as well as a JDK 1.6? If groovy-engine.jar were available in the maven repositories, it'd be very easy to bundle this jar with the Groovy distribution. Could you take care of this and see whether it's possible? Additionally, I think we could bundle the javax.script.* package recompiled for Java 1.5 as a jar, so that people using an 1.5 JVM can benefit from the JDK 6 scripting APIs. However, of course, as John explained, JSR-223 isn't the ideal mechanism to integrate Groovy into your applications. But I understand the desire to use a common API for various engines. Guillaume
        Hide
        Paul King added a comment -

        Remove specific version from issue title

        Show
        Paul King added a comment - Remove specific version from issue title
        Hide
        blackdrag blackdrag added a comment -

        since the discussion seems to have died, I close this RFE as well.

        Show
        blackdrag blackdrag added a comment - since the discussion seems to have died, I close this RFE as well.
        Hide
        Jim White added a comment -

        As Paul King suggested on groovy-dev, we should consider integrating JSR-223 support (like we do for BSF).

        I have extensive experience using JSR-223 with Groovy (notably the award winning Groovy For OpenOffice) and have an update in the works.

        If someone really thinks we shouldn't do this, speak up!

        Show
        Jim White added a comment - As Paul King suggested on groovy-dev, we should consider integrating JSR-223 support (like we do for BSF). I have extensive experience using JSR-223 with Groovy (notably the award winning Groovy For OpenOffice) and have an update in the works. If someone really thinks we shouldn't do this, speak up!
        Hide
        Jim White added a comment -

        Candidate implementation.

        Show
        Jim White added a comment - Candidate implementation.
        Hide
        Jim White added a comment -

        I've created an proposed implementation. It includes a very trivial test case and I've tested it for both JDK 1.5 and JDK 1.4 (I'm very pleased to see the retro stuff working!).

        If there are no objections within the next day or so, I will commit this to the trunk.

        We can then discuss further whether to merge to 1.6 (which would make good sense as it would match the javax.script support in JDK 1.6).

        Show
        Jim White added a comment - I've created an proposed implementation. It includes a very trivial test case and I've tested it for both JDK 1.5 and JDK 1.4 (I'm very pleased to see the retro stuff working!). If there are no objections within the next day or so, I will commit this to the trunk. We can then discuss further whether to merge to 1.6 (which would make good sense as it would match the javax.script support in JDK 1.6).
        Hide
        Jim White added a comment -

        Previous version was missing the META-INF/services file.

        Show
        Jim White added a comment - Previous version was missing the META-INF/services file.
        Hide
        blackdrag blackdrag added a comment -

        I would suggest you rename GroovySscriptEngine into GroovyEngine, because GroovyScriptEngine is used somewhere else in a different context and the new naming would match the naming of the BSF part.

        Show
        blackdrag blackdrag added a comment - I would suggest you rename GroovySscriptEngine into GroovyEngine, because GroovyScriptEngine is used somewhere else in a different context and the new naming would match the naming of the BSF part.
        Hide
        Jim White added a comment -

        I see what you mean, and although I don't believe there is a real conflict, I'll go along with a name change.

        I'll use GroovyScriptEngineImpl because the interface for JSR-223 is ScriptEngine (rather than BSFEngine as it is in BSF).

        Show
        Jim White added a comment - I see what you mean, and although I don't believe there is a real conflict, I'll go along with a name change. I'll use GroovyScriptEngineImpl because the interface for JSR-223 is ScriptEngine (rather than BSFEngine as it is in BSF).
        Hide
        Jim White added a comment -

        I just committed this (with the class name change) to the trunk.

        Testing is minimal so far, but I'm mainly concerned about not breaking anything at this point.

        The only really significant change is the addition of a dependency on LiveTribe's JSR-223 API implementation (which itself has a dependency on JUnit).

        Show
        Jim White added a comment - I just committed this (with the class name change) to the trunk. Testing is minimal so far, but I'm mainly concerned about not breaking anything at this point. The only really significant change is the addition of a dependency on LiveTribe's JSR-223 API implementation (which itself has a dependency on JUnit).
        Hide
        Sarah Gerweck added a comment -

        If you do this right, this new dependency should only occur at build time, and wouldn't exist if you do your builds in Java 6. You also shouldn't need JUnit just to do a build: you're just need something to declare the ScriptEngine API so the compiler can do its type checking.

        I haven't reviewed the patch, but you should be able to drop it in without any run-time requirements change. As long as you don't use the class, you won't need the JSR-223 support classes there.

        Show
        Sarah Gerweck added a comment - If you do this right, this new dependency should only occur at build time, and wouldn't exist if you do your builds in Java 6. You also shouldn't need JUnit just to do a build: you're just need something to declare the ScriptEngine API so the compiler can do its type checking. I haven't reviewed the patch, but you should be able to drop it in without any run-time requirements change. As long as you don't use the class, you won't need the JSR-223 support classes there.
        Hide
        Jim White added a comment -

        The original patch does break the JDK 1.4 build (my setup wasn't actually testing under JDK 1.4 before). That should be fixed now (changeset 14027).

        The remaining issue is managing the JSR-223 API implementation (LiveTribe). It is only needed for JDK 1.5, but I don't think it is causing any problem being present in JDK 1.4 and JDK 1.6. But do folks think there is something special we should do for those environments?

        Show
        Jim White added a comment - The original patch does break the JDK 1.4 build (my setup wasn't actually testing under JDK 1.4 before). That should be fixed now (changeset 14027). The remaining issue is managing the JSR-223 API implementation (LiveTribe). It is only needed for JDK 1.5, but I don't think it is causing any problem being present in JDK 1.4 and JDK 1.6. But do folks think there is something special we should do for those environments?
        Hide
        Jim White added a comment -

        In order to avoid confusing folks about whether they should use the livetribe-jsr223.jar or not (it is only needed by JDK 1.5 users), I've changed the dependency to use 'provided' scope. That will bring it in for compilation and testing but won't appear in runtime (even though it isn't needed for JDK 1.6 compile & test, it won't hurt anything and may actually be better). JDK 1.5 users will have to track this JAR down themselves (just as they do currently), but at least having it appear in the POM should help them out.

        Show
        Jim White added a comment - In order to avoid confusing folks about whether they should use the livetribe-jsr223.jar or not (it is only needed by JDK 1.5 users), I've changed the dependency to use 'provided' scope. That will bring it in for compilation and testing but won't appear in runtime (even though it isn't needed for JDK 1.6 compile & test, it won't hurt anything and may actually be better). JDK 1.5 users will have to track this JAR down themselves (just as they do currently), but at least having it appear in the POM should help them out.
        Hide
        Jim White added a comment -

        Merged to GROOVY_1_6_X (cs 14075).

        Show
        Jim White added a comment - Merged to GROOVY_1_6_X (cs 14075).
        Hide
        Jim White added a comment -

        Not tested very much, but seems OK so far.

        Show
        Jim White added a comment - Not tested very much, but seems OK so far.

          People

          • Assignee:
            Jim White
            Reporter:
            Sarah Gerweck
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: