9

I've recently written a small specialist scripting language and used the Maven to export an OSGi compliant bundle that also exports a service descriptor into the "META-INF/services/javax.script.ScriptEngineFactory" service registry file.

The problem is that although the OSGi import and export packages are fine, the service registry appears to be incompatible with OSGi (as OSGi keeps its bundles off the general classpath and uses separate classloaders for modules).

My question is, am I correct in thinking that OSGi is incompatible with the Service Discovery mechanism, and if not, what can I add to my bundle metadata so that ScriptEngineManager.getEngineFactories() will list my script engine in an OSGi environment?

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Chris
  • 4,450
  • 3
  • 38
  • 49
  • 1
    Another JSR-223 and OSGi mismatch is that at runtime scripts will typically desire to import classes. However, OSGi prefers bundles to specify imports at build time by declaring them in the bundle's JAR META-INF/MANIFEST.MF. The DynamicImports-Package directive with a wildcard can workaround this issue at the price of watering down OSGi's JAR version management. – buzz3791 Jun 21 '12 at 20:19

3 Answers3

7

Apache Sling does use this mechanism in an OSGi environment to manage its JSR-233 compatible script engines, mostly via its ScriptEngineManagerFactory class [1]. See also [2] for an example custom script engine.

Adding your script engine to Sling should work if it's JSR-233 compatible. The simplest way to test that is probably to follow the "Sling in 15 minutes" tutorial [3] using your language instead of the server-side javascript language that's used there.

[1] http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/core/src/main/java/org/apache/sling/scripting/core/impl/ScriptEngineManagerFactory.java

[2] http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/javascript

[3] http://sling.apache.org/site/discover-sling-in-15-minutes.html

Bertrand Delacretaz
  • 6,100
  • 19
  • 24
  • Thanks for the link. I guess I can refer users to your reply if they wish to integrate my script language within an OSGi environment. – Chris Jul 04 '11 at 10:58
  • I am aware this is a very old post, but it seems the last link doesn't contain the same examples what it used to. I am struggling referencing the service in my servlet – Thomas May 04 '16 at 08:36
5

Matt F. blogged about an alternative solution [1]

When providing scripting in a Java application, scripting engines conforming to JSR 223 (e.g. Groovy, JRuby, Scala, ...) can easily be embedded using something along the lines of

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getByName("groovy");

However, in an OSGi-based application, the ScriptEngineManager fails to discover scripting engines located in installed bundles, due to the way it discovers engines available on the class path. Luckily, the Apache Felix project has already solved this problem, there are

  • OSGiScriptEngineManager [2]
  • OSGiScriptEngineFactory [3]
  • OSGiScriptEngine [4]

which provide an OSGi-compliant way to discover and load scripting engines installed as OSGi bundles.

ScriptEngineManager scriptEngineManager = new OSGiScriptEngineManager(bundleContext);
ScriptEngine scriptEngine = scriptEngineManager.getByName("groovy");

Now that we've had several years of scripting and OSGi experience, one challenge is simplifying script access to OSGi services. Using the ServiceTracker api [5] seems to be the only approach; but this effort is high for simple scripts. We've worked towards a means for scripts to express which OSGi services they want and automate the ServiceTracker calls on behalf of the scripts but it is fragile. Looking forward to the OSGi specification offering better support in the future.

[1] http://devnotesblog.wordpress.com/2011/09/07/scripting-using-jsr-223-in-an-osgi-environment/

[2] http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngineManager.java

[3] http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngineFactory.java

[4] http://svn.apache.org/repos/asf/felix/trunk/mishell/src/main/java/org/apache/felix/mishell/OSGiScriptEngine.java

[5] https://osgi.org/javadoc/osgi.core/7.0.0/org/osgi/util/tracker/ServiceTracker.html

buzz3791
  • 1,683
  • 2
  • 20
  • 38
0

Just to chime in that there is a standard general solution to consuming these types of services in an OSGi environment, as ScriptEngineFactory is not the only such case. It is a part of the OSGi Enterprise spec. and the reference implementation can be found here: http://aries.apache.org/modules/spi-fly.html

It is trivial to recreate the functionality of the Apache Spring classes via this mechanism, and imo this method is far cleaner and more sensible, but I do understand the desire to avoid reimplementing the wheel so to speak.

Elias Vasylenko
  • 1,524
  • 11
  • 21