A few months ago, I was still blissfully unaware of the fact that a RAP application, and in fact any Eclipse application, running on a local Jetty Server will not automagically run on a server. I am still not sure exactly why this is the case, but when this realisation comes one day prior to an important demo, I guess the reasons do not really matter that much.
Anyway, the lessons learned was that when one wants to run Eclipse applications on a server, you will need a JAVA based application server, and my choice fell on Virgo, as it seemed the most OSGI compliant application server around. As it has taken me about four weeks to get everything up and running the way I wanted, I felt that the online tutorials might need a bit of updating, and so I hope my experiences may be of help to other developers, because Virgo really does boost the possibilities of your OSGI applications...once you're through the tough spots!
Getting Virgo to run on a server is really a very simple task! In my case we have a Debian Linux distribution running in the cloud. Virgo was up and running after three operations:
- Set up JAVA
- Copy a Virgo distribution to the distro
- Create a startup script.
In our case, we needed a JAVA 7 JDK from Oracle, because we wanted to run a Cassandra client which at the time was not available for JAVA 6, the OpenJDK. version at the time. Getting JAVA7 to run on Debian was simply a matter of:
- Unzipping the
JDKin a folder on Debian (we used /opt)
- Setting the JAVA_HOME to the root of the folder in the
- updating the system with the
Getting the Virgo distribution on the server basically follows the same procedure as above, with the only difference that the environment variable
SERVER_HOME needs to be added to the
profile file. Selecting the right distribution of Virgo however, required some more thought!
Selecting the Right Virgo Distribution
Virgo comes in a number of flavours:
- Nano is a minimal application server, which is suited for a single application
- Kernel provides a fully powered, but bare-bones application server, which can be extended with
- Jetty-Serveror tomcat-server in order to serve web contents.
Initially we opted for a nano distribution that was extended for RAP, following this post from Eclipse RAP lead Ralf Steinberg, At the time of writing, the 3.7.0 version of Virgo was available on the Virgo build server.which included the nano-rap distribution. We installed this version on the server, and managed to get our RAP application working, but it soon became clear that this approach will only work for very small RAP applications.
As Virgo Nano does not include the user region capabilities of the kernel, you can only build your application by dropping the necessary OSGI bundles in the pickup directory one by one. These bundles need to be dropped in the directory in such a manner that the dependencies are respected, so if
bundle A has a dependency with
bundle B, then
bundle B must be dropped in the directory first. This approach is perfect for testing, but becomes problematic for even moderately large applications, let alone if multiple applications must be served. We were going to deploy four applications, some of which shared functionality, such as database connectivity, so this approach quickly became cumbersome. It has been mentioned quite often, but the support Virgo offers through its management console is really great. Also the logs in the servicability folder are a great help!
The logical choice for us, then was to opt for the jetty-server distribution. This distribution has much better means of managing multiple applications, and the jetty server is provided by default. Setting up a RAP application on this distribution is covered fairly well by these posts from Florian Waibel:
To my knowledge (and as far as I tested), the information is still largely valid, with the only comment that the Virgo tooling currently is not being actively developed, and is trailing behind the Eclipse Luna and Mars releases.The tooling allows you to integrate Virgo in your Eclipse IDE, but this was not a main concern at the time. I was not really happy with the jetty server, as the distribution seems very much like 'work in progress'. Many bundles in the ext user region are double, which makes debugging with the admin console quite complicated.
What baffled me most, however, is that in both posts by Florian, the RAP applications cannot be dropped in the application server without any additional coding! Either you have to include a SpringDM bean in your bundle, or you have to make your bundle a web bundle by including a
Web-Context directive in your
MANIFEST.MF file, and a WEB-INF folder under the root of the bundle. In the nano-rap distribution, this was not needed, so I decided to to see if I could create a 'best of both worlds' version of Virgo myself. This has cost me a few days, and I haven't managed to achieve my goals, but it has helped me understand the Virgo server a lot better!
A Custom Virgo Application Server
As a result, I made a custom Virgo application server, by:
Adding the Jetty files and RAP files from the nano-rap distribution to the ext folder
As far as I can tell, this set up creates on of the leanest distributions, which supports all the features of the kernel, and is 'RAP ready'. As a result, I added the Virgo kernel distribution to my Linux server, unpacked it to the
/opt folder, set the
SERVER_HOME variable in the profile file as described above, and started it. By checking the
<my.server.ip.address>:8080/admin/console address in a browser, I could see that everything worked fine. Now I needed to configure this set up.
Configuring the Virgo Kernel
When the Virgo Kernel distribution is up and running, the admin console is served by the
org.eclipse.equinox.http bundle, which is located in the
plugins folder. This bundle needs to be replaced by Jetty - or else you will run into network problems, as both use the
config.ini to select the port they run on. Most tutorials will invite you to drop the jetty bundles in the
ext folder, but we opted to add a new
user region called rap in which we wanted to put both the jetty and rap bundles. This is quite a straightforward task, once you know what to do. We opted for this, because ext is already used to add the
gemini blueprint functionality, and we didn't want to mix functionality in one folder, for reasons of maintenance.
First we need to select the
org.eclipse.virgo.repository properties file from the configuration folder, and add the following lines (boldface):
These lines tell the Virgo application server that a new repository will be added to the user region called
rap , which is physically located in the
Next, we need to create the folder and fill it with the required bundles:
As you can see, the bundles are extended with two Virgo plans, which determine, amongst others:
- the sequence in which the bundles in the folder are started
- which bundles are made available for bundles in other folders of the user region.
Every folder, which is added to the the
org.eclipse.virgo.repository properties file is basically a self-contained module, of which the scope is determined by the folder it resides in. The plans make these bundles available for broader use.
Both plans were literally copied (and modified) from Florian's post, and are included here for the sake of completeness. The Jetty plan is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<plan name="org.eclipse.jetty" version="8.1.3" scoped="false" atomic="true"
<artifact type="bundle" name="javax.servlet" version="[3, 4)" />
<artifact type="bundle" name="org.eclipse.jetty.util" version="[8.1.3, 9)" />
<artifact type="bundle" name="org.eclipse.jetty.io" version="[8.1.3, 9)" />
<artifact type="bundle" name="org.eclipse.jetty.http" version="[8.1.3, 9)" />
<artifact type="bundle" name="org.eclipse.jetty.servlet" version="[8.1.3, 9)" />
<artifact type="bundle" name="org.eclipse.equinox.http.servlet" version="[1.1.300, 2)" />
<artifact type="bundle" name="org.eclipse.equinox.http.jetty" version="[3.0.0, 4)" />
And the RAP-2.3.0 plan looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<plan name="org.eclipse.rap" version="2.3.0" scoped="false" atomic="true"
<artifact type="bundle" name="org.eclipse.rap.rwt" version="[2.3.0, 4.0.0)" />
<artifact type="bundle" name="org.eclipse.rap.rwt.osgi" version="[2.3.0, 4.0.0)" />
<artifact type="bundle" name="org.eclipse.rap.jface" version="[2.3.0, 4.0.0)" />
<artifact type="bundle" name="org.eclipse.rap.jface.databinding" version="[2.3.0, 4.0.0)" />
For details on Virgo plans, please refer to the relevant documentation. For the discussion here, it is relevant to point out that both plans include a directive:
which means that the bundles in the plan are made available for other bundles in the
All we have to do now is activate the plans. This is done in the
org.eclipse.virgo.kernel.userregion properties file in the configuration folder. The following lines (boldface) are added to the
initialArtifacts = repository:plan/org.eclipse.virgo.kernel.userregion.blueprint,\
Restart the application server, and the admin console should be active again, but now through the Jetty server!
In a similar fashion, we created user regions for the
JaaS security, a cassandra client , netty and a MySQL client. Virgo allows for great modularisation and maintainability this way.
Running the Applications
Last we included user regions for each of our applications. As was mentioned earlier, a number of these applications were running as RAP RCP. Initially we thought we could just add plans to the user region that would start these applications, but when we opened the browser and surfed to the web context url, Jetty told us that the web pages were not available.Further scrutiny told us that although all the bundles were started correctly and were running, our RCP applications somehow did not manage to make a connection with the
org.eclipse.rap.rwt.osgi bundle through the declarative services, so the
RAP isn't declared in Jetty's servlet container.
After numerous failed experiments, we 'web-ified' the RAP bundles, by extending the
Manifest.MF file with a web context:
and adding a
WEB-INF directory with a
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
When we built the bundles and dropped these in the pickup directory (not in a plan!), the applications worked fine.
My dealings with the Virgo application server have really made me enthusiastic about its possibilities, and I believe it is a matter of time before we really can activate our OSGI applications by simply dropping the bundles in Virgo! If you come from the OSGI world, like myself (and not from Spring, for instance), I believe that the kernel setup that is described above is the cleanest configuration you can make, when you want to deploy multiple applications on a Virgo application server. If we manage to omit the 'webification' of our RAP bundles, then Virgo will really be the perfect application server for OSGI applications!
In the second post I will be updating the above configuration.