JRuby (please use github issues at http://bugs.jruby.org)
  1. JRuby (please use github issues at http://bugs.jruby.org)
  2. JRUBY-4057

JSR223 ScriptEngineManager cannot find both jython and jruby ScriptEngines when using maven assembly plugin

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: JRuby 1.4.0RC1
    • Fix Version/s: None
    • Component/s: Embedding
    • Labels:
      None
    • Environment:
    • Number of attachments :
      1

      Description

      See attached example maven project.

      If both jruby and jython are enabled using runtime dependencies*

      pom.xml:
      <dependencies>
      <dependency>
      <groupId>org.jruby</groupId>
      <artifactId>jruby</artifactId>
      <version>1.4.0RC1</version>
      <scope>runtime</scope>
      </dependency>
      <dependency>
      <groupId>org.python</groupId>
      <artifactId>jython</artifactId>
      <version>2.5.1</version>
      <scope>runtime</scope>
      </dependency>
      </dependencies>

      then the jar-with-dependencies assembly jar will fail to register both ScriptEngine implementations

      $ mvn assembly:assembly
      $ java -jar target/example-1.0-SNAPSHOT-jar-with-dependencies.jar
      could not find jruby engine

      whereas creating an explicit classpath works fine

      $ java -classpath "jython-2.5.1.jar;jruby-1.4.0RC1.jar;target/example-1.0-SNAPSHOT.jar" example.Jsr223Example
      ok

      It appears the JSR223 mechanism cannot handle multiple copies of its metadata in example-1.0-SNAPSHOT-jar-with-dependencies.jar.

      $ jar tvf target/example-1.0-SNAPSHOT-jar-with-dependencies.jar | grep javax.script.ScriptEngineFactory
      42 Wed Sep 16 13:39:46 CDT 2009 META-INF/services/javax.script.ScriptEngineFactory
      40 Sat Sep 26 13:48:04 CDT 2009 META-INF/services/javax.script.ScriptEngineFactory

      • - please note a jython-2.5.1.jar artifact is not yet available on maven central repo, will have to be installed manually

        Activity

        Hide
        Michael Heuer added a comment -

        This issue has also been posted to the Jython issue tracker at:

        http://bugs.jython.org/issue1485

        Show
        Michael Heuer added a comment - This issue has also been posted to the Jython issue tracker at: http://bugs.jython.org/issue1485
        Hide
        Yoko Harada added a comment -

        You got only a Jython engine when you ran:
        $ java -jar target/example-1.0-SNAPSHOT-jar-with-dependencies.jar
        right?

        This is because JSR223 uses Java6's discovery mechanism. ScriptEngineManager scans all jar archives in a classpath to find a META-INF/services/javax.script.ScriptEngineFactory file. If the file is found, a URL to the file is saved in Enumerator type instance. Perhaps, because it is URL, java.util.HashSet is used to eliminate duplication of the URLs to META-INF/services/javax.script.ScriptEngineFactory files. (see the code of sun.misc.Launcher#getBootstrapClassPath() method) This is why multiple factory files in the same archive don't work at the same time because those have the same URLs.

        As for the second case:
        $ java -classpath "jython-2.5.1.jar;jruby-1.4.0RC1.jar;target/example-1.0-SNAPSHOT.jar" example.Jsr223Example
        ScriptEngineManager got three engines, two Jython engines and one JRuby engine, right after it scanned all jar arcvhies. This was because URLs to META-INF/services/javax.script.ScriptEngineFactory files were different. However, while ScriptEngineManager was creating a collection of engines, the second Jython engine was eliminated. Here, java.util.HasSet is used to avoid duplication again. So, you got two engines.

        To allow multiple META-INF/services/javax.script.ScriptEngineFactory files in a single jar archive, ScriptEngineManager should have a substitute of java.lang.ClassLoader.getResources() method.

        Show
        Yoko Harada added a comment - You got only a Jython engine when you ran: $ java -jar target/example-1.0-SNAPSHOT-jar-with-dependencies.jar right? This is because JSR223 uses Java6's discovery mechanism. ScriptEngineManager scans all jar archives in a classpath to find a META-INF/services/javax.script.ScriptEngineFactory file. If the file is found, a URL to the file is saved in Enumerator type instance. Perhaps, because it is URL, java.util.HashSet is used to eliminate duplication of the URLs to META-INF/services/javax.script.ScriptEngineFactory files. (see the code of sun.misc.Launcher#getBootstrapClassPath() method) This is why multiple factory files in the same archive don't work at the same time because those have the same URLs. As for the second case: $ java -classpath "jython-2.5.1.jar;jruby-1.4.0RC1.jar;target/example-1.0-SNAPSHOT.jar" example.Jsr223Example ScriptEngineManager got three engines, two Jython engines and one JRuby engine, right after it scanned all jar arcvhies. This was because URLs to META-INF/services/javax.script.ScriptEngineFactory files were different. However, while ScriptEngineManager was creating a collection of engines, the second Jython engine was eliminated. Here, java.util.HasSet is used to avoid duplication again. So, you got two engines. To allow multiple META-INF/services/javax.script.ScriptEngineFactory files in a single jar archive, ScriptEngineManager should have a substitute of java.lang.ClassLoader.getResources() method.
        Hide
        Michael Heuer added a comment -

        Thank you for the analysis, Yoko.

        Should I submit an issue at the JSR 223 project at java.net?

        https://scripting.dev.java.net/servlets/ProjectIssues

        Issues there don't seem to be resolved in timely fashion, though. Perhaps I should submit an issue against the JDK itself.

        Show
        Michael Heuer added a comment - Thank you for the analysis, Yoko. Should I submit an issue at the JSR 223 project at java.net? https://scripting.dev.java.net/servlets/ProjectIssues Issues there don't seem to be resolved in timely fashion, though. Perhaps I should submit an issue against the JDK itself.
        Hide
        Yoko Harada added a comment -

        You should submit the issue to somewhere, but I don't think https://scripting.dev.java.net/servlets/ProjectIssues is the place. Since the problem is in javax.script.ScriptEngineManager, you'd better to file at http://openjdk.java.net/ or some other JDK implementation project.

        It might be possible to resolve the problem in org.jruby.embed.jsr223.JRubyScriptEngineManager temporarily. I'll look into it to see whether JRubyScriptEngineManager can make it or not.

        Show
        Yoko Harada added a comment - You should submit the issue to somewhere, but I don't think https://scripting.dev.java.net/servlets/ProjectIssues is the place. Since the problem is in javax.script.ScriptEngineManager, you'd better to file at http://openjdk.java.net/ or some other JDK implementation project. It might be possible to resolve the problem in org.jruby.embed.jsr223.JRubyScriptEngineManager temporarily. I'll look into it to see whether JRubyScriptEngineManager can make it or not.
        Hide
        Michael Heuer added a comment -
        Show
        Michael Heuer added a comment - Submitted against the JDK, http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6898734
        Hide
        Yoko Harada added a comment -

        Thank you, Michael. I'm hoping they understand the problem and fix it.

        Show
        Yoko Harada added a comment - Thank you, Michael. I'm hoping they understand the problem and fix it.
        Hide
        Johannes Buchner added a comment -

        The sun bug was closed as wont-fix, mentioning that the build tool should merge the duplicate file entries instead of copying them.

        Manually you can remove the META-INF/services/javax.script.ScriptEngineFactory from the resulting jar and replace it with one that contains all entries you want.

        With maven, you can specify that the dependency should not copy this particular file, and put your own file ScriptEngineFactory file there with both entries. This would be a crook that works.

        close?

        Show
        Johannes Buchner added a comment - The sun bug was closed as wont-fix, mentioning that the build tool should merge the duplicate file entries instead of copying them. Manually you can remove the META-INF/services/javax.script.ScriptEngineFactory from the resulting jar and replace it with one that contains all entries you want. With maven, you can specify that the dependency should not copy this particular file, and put your own file ScriptEngineFactory file there with both entries. This would be a crook that works. close?

          People

          • Assignee:
            Unassigned
            Reporter:
            Michael Heuer
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: