Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

E4/JavaScript

< E4

Historical Document: This component is functional but inactive

Introduction

One of the goals of e4 is to provide support for writing plugins in other languages - this page is the home of the effort to use JavaScript to write bundles in Eclipse. There are a number of excellent JavaScript runtimes made available by the browsers however as Eclipse in its current form is Java-based are initially targetting Rhino.

Development Resources

Development is currently being done in the E4 incubator in the "languages" sub-component.

Git: http://git.eclipse.org/c/e4/org.eclipse.e4.languages.git

The relevant projects are:

(bundles)
-org.eclipse.e4.languages.javascript
-org.eclipse.e4.languages.javascript.registry
(tests)
-org.eclipse.e4.languages.javascript.test
-org.eclipse.e4.languages.javascript.registry.test

Current Work

JavaScript Bundles

Eclipse has been very successful in its use of OSGi as a modularity and deployment technology for packaging Java classes and related resources. The work we're doing in this space aims to provide a similar clean and consistent integration for JavaScript both for working with existing Java resources as well as providing a similar dependency resolution and lifecycle management story for JavaScript components.

The org.eclipse.equinox.e4.languages.javascript bundle contains an OSGi inspired framework suitable for resolving and running JavaScript bundles that can call out to and are callable from the (java) Bundle that houses the script in the OSGi framework. One of the key classes JSFramework provides the means to install bundles and in general inspect the state of the system. Another class JSBundle allow you to observe and manage the state of an individual bundle. Many of the language level concepts in Java do not map well to JavaScript however many of the meta concerns of a component system do, so where possible the JavaScript framework tries to leverage OSGi concepts.

One difference is in the packaging; instead of a JAR file we use a JSON file. The contents of this file are more like an OSGi manifest than a JAR file in that the JSON file contains the JSBundle's metadata. A script "can" be encoded directly in the JSON file however the JSBundle format directly supports referencing script files by URI. An example will help illustrate this:

{
 "Bundle-SymbolicName":"sample.jsbundle",
 "Bundle-Version":"1.0",
 "Bundle-ScriptPath":"script.js",
 "Import-Package":"a.resource;version=[1.0.0,2.0.0)",
 "Export-Package":"sample.resource;version=1.0.0",
 "Require-Bundle:"some.other.bundle", 
}

Those familiar with OSGi manifests will hopefully see something somewhat familiar as we're re-using the OSGi dependendency resolution metadata. A more full list of the JSON headers, attributes, and directives supported can be found in the JSConstants class alongside JSFramework however you'll find many of the usual OSGi suspects are supported.

Another piece of functionaility worth mentioning is that the org.eclipse.e4.javascript bundle comes with built in support to automatically install a co-located JavaScript bundles from a host OSGi bundle. By declaring a "JavaScript-Bundle" header in your OSGi manifest you can reference a JSON file in your bundle. For example:

JavaScript-Bundle: scripts/bundle.json

This will cause the installation and resolution of your JSBundle as well as starting, stopping, and uninstalling along with the OSGi host bundle.

JavaScript Extension Registry Support

Once you have your JavaScript bundles installed and resolved interacting with your JavaScript code is done using the Rhino APIs. There are a few niceties exposed by JSBundle to make this interaction easier but there are also simpler ways like what provided in org.eclipse.e4.languages.javascript.registry. This bundle provides a class JavaScriptFactory that is an implementation of IExecutableExtensionFactory. You can use this factory where ever you reference a "class" in an extension and have a JavaScript implementation available. The syntax used to specify a JavaScript function to call is "org.eclipse.e4.languages.javascript.registry.JavaScriptFactory:{function name} where {functionName} is visible to the JavaScript bundle co-located with the bundle containing the plugin.xml.

For example, implementing a Servlet in JavasScript and calling it via the org.eclipe.equinox.http.registry.servlets extension point:

<extension
    point="org.eclipse.equinox.http.registry.servlets">
  <servlet
      alias="/jsHello"
      class="org.eclipse.e4.languages.javascript.registry.JavaScriptFactory:some.func">
  </servlet>
</extension>

In this case we're implementing a servlet in JavaScript however we still get our Java dependencies from the hosting bundle so in this case we have to ensure our OSGi manifest is importing java.sevlet and javax.servlet.http. Here's an example of a relevant chunk of JavaScript that would be referenced in the bundles JSON file for a simple Hello world servlet.

var some = some || {};
some.func = function() {
  var o = {
    "service" : function(req, resp) {
      this.super$service(req, resp); // this is very important
    },
    "doGet" : function(req, resp) {
      resp.getWriter().write("<html><body>");
      resp.getWriter().write("Hello World from a " + this.getServletInfo());
      resp.getWriter().write("</body></html>");
    },
    "getServletInfo" : function() {
      return "JavaScript Servlet";
    }
  };
return new JavaAdapter(Packages.javax.servlet.http.HttpServlet, o);
}

JavaScript Rhino Debugging Support

See JavaScript Debugging Support

Back to the top