Camel
  1. Camel
  2. CAMEL-3481

camel-script doesn't work in OSGi

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.5.0
    • Fix Version/s: 2.8.0
    • Component/s: camel-script
    • Labels:
      None
    • Patch Info:
      Patch Available

      Description

      In an OSGi environment, the ScriptEngineManager that ScriptBuilder uses can't find any scripting engines except the ones packaged in the JDK (Rhino, maybe AppleScript, etc.). It's possible that setting a better ClassLoader would work, or perhaps using a singleton ScriptEngineManager and setting up the scripting engines in an OSGi Activator instead of relying on the META-INF lookup every time a script is invoked.

      1. camel-core.patch
        6 kB
        Aaron Mulder
      2. camel-script.patch
        4 kB
        Aaron Mulder

        Issue Links

          Activity

          Hide
          Hendy Irawan added a comment -

          In my experience, "the ScriptEngineManager that ScriptBuilder uses can't find any scripting engines except the ones packaged in the JDK" seems incorrect assumption, at least on ServiceMix 4.3.0 / Camel 2.6.0, as I got this:

          09:39:26,649 | ERROR | rint Extender: 2 | BlueprintContainerImpl | 7 - org.apache.aries.blueprint - 0.2.0.incubating | Unable to start blueprint container for bundle marioteguh-to-tumblr_v2.blueprint.xml due to unresolved dependencies [(&(language=simple)(objectClass=org.apache.camel.spi.LanguageResolver)), (&(component=rss)(objectClass=org.apache.camel.spi.ComponentResolver)), (&(language=js)(objectClass=org.apache.camel.spi.LanguageResolver)), (&(component=smtp)(objectClass=org.apache.camel.spi.ComponentResolver))]
          java.util.concurrent.TimeoutException
          at org.apache.aries.blueprint.container.BlueprintContainerImpl$1.run(BlueprintContainerImpl.java:273)[7:org.apache.aries.blueprint:0.2.0.incubating]
          at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)[:1.6.0_22]
          at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)[:1.6.0_22]
          at java.util.concurrent.FutureTask.run(FutureTask.java:166)[:1.6.0_22]
          at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:165)[:1.6.0_22]
          at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:266)[:1.6.0_22]
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)[:1.6.0_22]
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)[:1.6.0_22]
          at java.lang.Thread.run(Thread.java:679)[:1.6.0_22]

          This seems to be the culprit:

          (&(language=js)(objectClass=org.apache.camel.spi.LanguageResolver))

          I can confirm that there seems to be no bundle that exports this service:

          camel-script (210) provides:
          ----------------------------
          language =
          objectClass = org.apache.camel.spi.LanguageResolver
          service.id = 350


          objectClass = org.apache.camel.spi.LanguageResolver
          resolver = default
          service.id = 351

          I reported this as bug SMXCOMP-895.

          Show
          Hendy Irawan added a comment - In my experience, "the ScriptEngineManager that ScriptBuilder uses can't find any scripting engines except the ones packaged in the JDK" seems incorrect assumption, at least on ServiceMix 4.3.0 / Camel 2.6.0, as I got this: 09:39:26,649 | ERROR | rint Extender: 2 | BlueprintContainerImpl | 7 - org.apache.aries.blueprint - 0.2.0.incubating | Unable to start blueprint container for bundle marioteguh-to-tumblr_v2.blueprint.xml due to unresolved dependencies [(&(language=simple)(objectClass=org.apache.camel.spi.LanguageResolver)), (&(component=rss)(objectClass=org.apache.camel.spi.ComponentResolver)), (&(language=js)(objectClass=org.apache.camel.spi.LanguageResolver)), (&(component=smtp)(objectClass=org.apache.camel.spi.ComponentResolver))] java.util.concurrent.TimeoutException at org.apache.aries.blueprint.container.BlueprintContainerImpl$1.run(BlueprintContainerImpl.java:273) [7:org.apache.aries.blueprint:0.2.0.incubating] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [:1.6.0_22] at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [:1.6.0_22] at java.util.concurrent.FutureTask.run(FutureTask.java:166) [:1.6.0_22] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:165) [:1.6.0_22] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:266) [:1.6.0_22] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [:1.6.0_22] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [:1.6.0_22] at java.lang.Thread.run(Thread.java:679) [:1.6.0_22] This seems to be the culprit: (&(language=js)(objectClass=org.apache.camel.spi.LanguageResolver)) I can confirm that there seems to be no bundle that exports this service: camel-script (210) provides: ---------------------------- language = objectClass = org.apache.camel.spi.LanguageResolver service.id = 350 objectClass = org.apache.camel.spi.LanguageResolver resolver = default service.id = 351 I reported this as bug SMXCOMP-895 .
          Hide
          Claus Ibsen added a comment -

          Yeah I had some issue with Apache for Git and had to try a simple commit and push to see if it worked. So I remembered this one.

          Show
          Claus Ibsen added a comment - Yeah I had some issue with Apache for Git and had to try a simple commit and push to see if it worked. So I remembered this one.
          Hide
          Willem Jiang added a comment -

          @Claus,

          I just found you already updated the code, thanks

          Show
          Willem Jiang added a comment - @Claus, I just found you already updated the code, thanks
          Hide
          Claus Ibsen added a comment -

          Willem can you add the try .. finally in the code where you change the classloader on the context. We must be sure we don't mess with that, in case an exception or something happens.

          Show
          Claus Ibsen added a comment - Willem can you add the try .. finally in the code where you change the classloader on the context. We must be sure we don't mess with that, in case an exception or something happens.
          Hide
          Willem Jiang added a comment -

          Applied patch with thanks to Aaron.
          I did some change on the patch of ScriptBuilder which leverage the Activator to detect the OSGi environment and moved the most reflection invocations into the Activator.

          When I did some OSGi integration test on the script code, I just found using the org.apache.servicemix.specs.scripting-api-1.0 spec bundle code work around such issue, as the scripting api can find the script engine from OSGi rightly.

          Anyway, current patch can help us to use the scripting api which provides by the JVM rightly.

          Show
          Willem Jiang added a comment - Applied patch with thanks to Aaron. I did some change on the patch of ScriptBuilder which leverage the Activator to detect the OSGi environment and moved the most reflection invocations into the Activator. When I did some OSGi integration test on the script code, I just found using the org.apache.servicemix.specs.scripting-api-1.0 spec bundle code work around such issue, as the scripting api can find the script engine from OSGi rightly. Anyway, current patch can help us to use the scripting api which provides by the JVM rightly.
          Hide
          Claus Ibsen added a comment -

          The code in camel-script would be better to be moved into camel-core-osgi so we can use the OSGi API directly instead of all the hacked reflection invocations.

          We have X number of resolvers in camel-core-osgi that does that.

          Willem can you take a look?
          Would be nice to get this working as ppl want to use eg Groovy scripts in OSGi/SMX

          Show
          Claus Ibsen added a comment - The code in camel-script would be better to be moved into camel-core-osgi so we can use the OSGi API directly instead of all the hacked reflection invocations. We have X number of resolvers in camel-core-osgi that does that. Willem can you take a look? Would be nice to get this working as ppl want to use eg Groovy scripts in OSGi/SMX
          Hide
          Claus Ibsen added a comment -

          Aaron I looked at the patch and it looks good. Just a few minor comments

          • checkstyle
          • you should prefer to use try .. finally when changing the ClassLoader

          About checkstyle, you can see more here
          http://camel.apache.org/building.html

          We prefer the code to pass the checkstyle before committing. Especially for the core and most used components.

          Show
          Claus Ibsen added a comment - Aaron I looked at the patch and it looks good. Just a few minor comments checkstyle you should prefer to use try .. finally when changing the ClassLoader About checkstyle, you can see more here http://camel.apache.org/building.html We prefer the code to pass the checkstyle before committing. Especially for the core and most used components.
          Hide
          Claus Ibsen added a comment -

          Yep lets push this for 2.8. Thanks for the reminder.

          Show
          Claus Ibsen added a comment - Yep lets push this for 2.8. Thanks for the reminder.
          Hide
          Hadrian Zbarcea added a comment -

          Yes, but we need to wait a few days until 2.7.0 is officially released.

          Show
          Hadrian Zbarcea added a comment - Yes, but we need to wait a few days until 2.7.0 is officially released.
          Hide
          Antoine Toulme added a comment -

          Claus, Camel 2.7 is JDK6 now, so can we integrate this patch ?

          Show
          Antoine Toulme added a comment - Claus, Camel 2.7 is JDK6 now, so can we integrate this patch ?
          Hide
          Claus Ibsen added a comment -

          Camel 3.0 will be JDK 1.6+ only so we target this for Camel 3

          Show
          Claus Ibsen added a comment - Camel 3.0 will be JDK 1.6+ only so we target this for Camel 3
          Hide
          Aaron Mulder added a comment -

          Patch files for review. Note that the camel-core patch introduces a dependency on javax.script

          Show
          Aaron Mulder added a comment - Patch files for review. Note that the camel-core patch introduces a dependency on javax.script
          Hide
          Aaron Mulder added a comment -

          I have a patch that resolves this issue. It relies on looking for script engines in org.apache.camel.impl.osgi.Activator (same as when it looks for components and data formats and the like). Then in ScriptBuider in camel-script, if the normal mechanism for loading script engines fails, it checks whether OSGi is available and attempts to load the script engines found by the Activator.

          The main issue with this approach is that it adds a dependency on javax.script to camel-core (where the OSGi Activator lives). It uses the same pattern as the other stuff in there – a ScriptEngineResolver that uses the ScriptEngineFactory and so on. This is fine for Java 6 and up (where javax.script is integrated). I'm not clear whether people feel it's OK to add the javax.script dependency for Java 5 support.

          Thoughts on that?

          I also have a new test for camel-itest-osgi that demonstrates the problem and solution, and I will go ahead and commit that in any case. However, the test will be @Ignore'd because it doesn't run even with the new code without a JRuby OSGi bundle and the default JRuby distribution in Maven does not seem to work for that.

          Show
          Aaron Mulder added a comment - I have a patch that resolves this issue. It relies on looking for script engines in org.apache.camel.impl.osgi.Activator (same as when it looks for components and data formats and the like). Then in ScriptBuider in camel-script, if the normal mechanism for loading script engines fails, it checks whether OSGi is available and attempts to load the script engines found by the Activator. The main issue with this approach is that it adds a dependency on javax.script to camel-core (where the OSGi Activator lives). It uses the same pattern as the other stuff in there – a ScriptEngineResolver that uses the ScriptEngineFactory and so on. This is fine for Java 6 and up (where javax.script is integrated). I'm not clear whether people feel it's OK to add the javax.script dependency for Java 5 support. Thoughts on that? I also have a new test for camel-itest-osgi that demonstrates the problem and solution, and I will go ahead and commit that in any case. However, the test will be @Ignore'd because it doesn't run even with the new code without a JRuby OSGi bundle and the default JRuby distribution in Maven does not seem to work for that.

            People

            • Assignee:
              Willem Jiang
              Reporter:
              Aaron Mulder
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development