Equinox is Eclipse’s implementation of OSGi modular environment. It’s one existing implementation developed by Eclipse Foundation for its Eclipse IDE 3.0. Originally was OSGi designed to be used in resource-constrained environments like set-top boxes, car computers etc. Despite this “minimalism” origin, OSGi is during the years recognized as the one of the most influencing technology in Java and Equinox has became of the most prominent implementation today.
Equinox parts ∞
Equinox is quite large project comprised of number domain areas implementing OSGi specifications but also Equinox-specific features.
- OSGi Framework itself (
org.eclipse.osgi_<version>.jar)– main part of our interest, implementation of OSGi Core
- OSGi Compendium services — Log Service, HTTP Service, Configuration Admin Service, User Admin Service, Declarative Services, Event Admin service, …
- native launchers — Equinox-only enhancement producing platform-specific executables to run Equinox (yourApp.exe for Windows, …).
p2 (provisioning platform) — Equinox-only tools for automated installing, uninstalling and updating bundles or group of bundles (features, products) in OSGi-based applications.
This and the following posts assume you have downloaded “All of Equinox” (aka
equinox-SDK-<version>.zip from Equinox download page.
Equinox versioning ∞
Equinox has been versioned in accordance with Eclipse IDE, thus Eclipse IDE 3.7 (Indigo) has been shipped with Equinox 3.7 etc.
While current Eclipse release 4.2 (Juno) is being shipped with Equinox 3.8. The planned further Eclipse Kepler will contain Equinox 3.9.
Starting OSGi framework ∞
Single jar file
org.eclipse.osgi_<version>.jar is enough to run core OSGi framework:
$ java -jar org.eclipse.osgi_<version>.jar
but issuing this does nothing at first sight. This is because framework is not configured what to do yet. There is a bunch of commandline arguments like
-console and system properties like
osgi.bundles. All available arguments are documented in (Juno) online help.
$ java -jar org.eclipse.osgi_<version>.jar -console
Many arguments can be also be specified as a system property from commandline and vice-versa. For example, an equivalent of
-console argument is
$ java -Dosgi.console -jar org.eclipse.osgi_<version>.jar
Although this will start console, all valuable messages will go into
.log files under
configuration/ folder created by Equinox for that purpose. So another “survival” argument is
-consoleLog that send logs also to stdout.
$ java -jar org.eclipse.osgi_<version>.jar -console -consoleLog
Update for Equinox 3.8 console (part of Eclipse 4.2 (Juno)) ∞
Equinox 3.8 has a brand new console that isn’t part of core
org.eclipse.osgi_<version>.jar framework anymore, thus above instruction will fail for Equinox 3.8 (unfortunately without any helpful errors).
It’s necessary to start framework with additional bundles comprising console feature:
These bundles have to be specified with
osgi.bundles property from commandline (change versions to match your installation):
$ java -Dosgi.bundles=org.eclipse.equinox.console_1.0.0.v20120522-1841.jar@start,org.apache.felix.gogo.command_0.8.0.v201108120515.jar@start,org.apache.felix.gogo.runtime_0.8.0.v201108120515.jar@start,org.apache.felix.gogo.shell_0.8.0.v201110170705.jar@start -jar org.eclipse.osgi_3.8.0.v20120529-1548.jar -console
Or, better, in
config.ini file that is described in more detail bellow.
Also, Equinox 3.8 console offers many enhancements like SSH support, tab key completion, JAAS based authentication and many more. Again, see documentation in Equinox online help.
Hopefully, builtin console known from previous Equinox releases is still there. To enable it, pass a system property osgi.console.enable.builtin=true.
Basic OSGi console commands ∞
Basic command that will list all available commands. In Equinox 3.8 it is not helpful in anyway anymore and just flood your terminal with unpaginated many screen long list of commands without any practical usage information.
Short status. Lists installed bundles and their statuses.
Same but lists only bundles containing “virtage” in their name.
Starts bundle of specified ID.
Stops bundle of specified ID.
Reports any resolution problems for the bundle with the given numeric or symbolic id.
Installs the bundle from the given URL like
Uninstalls bundle specified by ID or bundle symbolic name.
Prints information of bundle like registered and used services.
Lists all available services or only services matching to LDAP-style filter (e.g.
services (objectClass="*virtage*") will print only services having “virtage” in their class name.
As mentioned in Equinox overview there is also launcher subproject that itself has two parts:
- Java launcher (yes, written in Java) — in
org.eclipse.equinox.launcher_<version>.jarthat helps setup the framework classloader and launches the Framework (in
native launcher (written in C) — platform-specific executable binary that (1) helps finds and runs Java launcher and (2) shows splash screen during start-up sequence.
Native launcher is split into
- native executable (e.g. .exe for Windows) in
platform-specific library (e.g.
eclipse_1503.dllfor Windows or
eclipse_1502.sofor Linux) living in
Launcher itself is small executable program written in C. In Windows, it has a
.exe extension. Launcher filename is usually branded to match your application name in product definition editor:
Why launcher if we’ve seen how to easily launch OSGi Framework? Launcher adds more platform-specific feel and convenience. Double click on
ourApp.exe is surely more to attracting to users then
$ java -jar .....
Above described system property or commandline argument to configure are good for learning or testing. For real-life scenarios, there is just one another way. Launcher will look for
configuration/ subfolder (called configuration area) in the current working directory. In this subfolder might be
config.ini file that is searched for properties and processed as they would specified in commandline.
Note that configuration area folder may be also located outside workdir of
org.eclipse.osgi_<version>.jar using argument
-configuration <location>. Actually, nearly everything described bellow can be customized with properties listed in (Juno) online help
|-- configuration/ | \-- config.ini |-- bundleA.jar |-- bundleB.jar |-- ... \-- bundleN.jar
Bare OSGi application’s
config.ini may look akin to this:
osgi.bundles.defaultStartLevel=4 osgi.bundles=bundleA.jar, bundleB.jar@start,\ bundleC.jar,\ bundleN.jar osgi.noShutdown=true eclipse.ignoreApp=true
We’ve used some common properties. Let’s review them.
Every bundle is run when certain start level becomes active. Applications should generally not depend on start levels. When it is necessary, you can change Equinox default start level 4 to something else with this
osgi.bundles is key property and you remember it from section about launching console in Equinox 3.8 above. As you likely already assume, this property tells to OSGi Framework what bundles should be installed or started when framework itself is started.
Minimal Equinox-based application must define list these bundles
osgi.bundles=org.eclipse.equinox.common,\ org.eclipse.core.runtime,\ org.eclipse.equinox.launcher,\ org.eclipse.core.jobs,\ org.eclipse.equinox.registry,\ org.eclipse.equinox.preferences,\ org.eclipse.core.contenttype,\ org.eclipse.equinox.app
In this and previous snipped you’ve also seen how to specify bundles in more lines with
\ (backslash) to improve legibility for your human colleagues.
osgi.bundles accepts various formats of input
<URL | simple bundle location>[@ [<start-level>] [":start"]]
If you omit start level, bundle will be run in default start level. If you omit start, bundle will not be started until you do it yourself with
start <bundleId> console command.
This often causes a lot of troubles when you’re asking yourself why your application doesn’t run in the same manner like launched within PDE using Run Configuration.
Here are some examples of bundle specification value:
||Bundle from plugins/ subfolder will installed only when default start level is reached.|
||Bundle from plugins/ will be started in default start level.|
||Bundle from plugins/ will be started in start level 3.|
||Bundle \path\to\com.acme.someapp.jar will be started in default start level (note this time we used .jar).|
osgi.noShutdown specifies whether Framework should exit after Eclipse application terminates. Because we don’t develop Eclipse Platform application at this moment (we haven’t any
org.eclipse.equinox.app.IApplication child bind to
org.eclipse.core.runtime.applications extension point), Framework will otherwise shutdown immediately.
eclipse.ignoreApp hints launcher to don’t complain about missing application that is otherwise normally launched after bootstrapping. If you omit this you will get error
!ENTRY org.eclipse.osgi 4 0 2012-09-02 16:07:57.949 !MESSAGE Application error !STACK 1 java.lang.IllegalStateException: Unable to acquire application service. Ensure that the org.eclipse.core.runtime bundle is resolved and started (see config.ini). at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:74) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353) ...