Accueil > Equinox ServletBridge > OSGi Equinox in a Servlet Container [step4]

OSGi Equinox in a Servlet Container [step4]


In [step3], I have explained why it’s important to define Target Platform with OSGi Equinox in a Servlet Container to compile your custom bundle (sample.http, sample.http2…) with the bundles JARs coming from bridge/WebContent/WEB-INF/eclipse/plugins folder (and not coming from the Eclipse IDE).

In [step2], we have seen 2 problems :

  • It’s impossible to host some resources (HTML, Javascript, Servlet…) in the bridge WEB Application (when /* URL pattern is used). I will explain how fix this problem by using BridgeFilter coming from patch 323707.
  • It’s impossible to use directly the OSGi bundle coming from the workspace. You must create a JAR and copy/paste to the /plugins folder. I will explain how fix this problem by using ${workspace_loc} wildcard (to declare bundles in config.ini) coming from patch 323707.

The current distribution of OSGi Equinox in a Servlet Container doesn’t manage this 2 features, so I have decided to improve it with patch 323707. In this article I will explain how use this patch to manage the 2 problems explained below.

Download

You can download servletbridge_step4.zip which contains following explained projects :

  • bridge which contains :
    • the JAR patched lib/org.eclipse.equinox.servletbridge_1.2.0.201008301518.jar and plugins/org.eclipse.equinox.http.servlet_1.1.0.201008310825.jar.
    • the web.xml wich declare BridgeFilter instead of BridgeServlet.
    • the resources WEB-INF/WebContent/index.htm, WEB-INF/WebContent/index.jsp.
    • JAR of sample.http and sample.http2 deleted.
    • bridge.target Target Platform modified (at hand by editing with NodPad) to remove the sample.http and sample.http2 and the version of the org.eclipse.equinox.http.servlet with 1.1.0.201008310825 version.
  • sample.http2 which define /bin2 as output folder (instead of /bin folder) explained in bundleClassPathEntries section.
  • the same projects than [step2].

BridgeFilter – Add resource in bridge webapp

To use OSGi Equinox in a Servlet Container, the BrideServlet must be declared as an servlet. It works well except it causes the problem that it’s impossible to host some resources (JSP, HTML, Servlet…) in the bridge WEB Application, if /* URL servlet-mapping pattern is used. To resolve this problem, patch 323707 provides the capability to declare the « BrideServlet » as a Filter with BridgeFilter .

In this section we will see the problem with BridgeServlet, how BridgeFilter resolve this problem and I will explain why Filter using resolve the problem.

The problem with BridgeServlet

Add index.htm

Create the WEB-INF/WebContent/index.html file with this content :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>OSGi Equinox in a Servlet Container - Home Page</title>
</head>
<body>
<div>OSGi Equinox in a Servlet Container - Home Page</div>
</body>
</html>

When you go at http://localhost:8080/bridge/index.htm, you will have a 404 error :

This error message show you that BridgeServlet send a 404 error because it tries to search a resources registered ONLY with OSGi services (like /helloworld).

The fix problem – BridgetFilter

To resolve the problem of hosting some resources in the bridge WEB Application, you must use patch 323707 :

  • Download the zip NewServletBridge_*.zip from the patch 323707.
  • Replace the servletbridge.jar with the JAR org.eclipse.equinox.servletbridge_1.2.0.201008301518.jar.
  • Replace org.eclipse.equinox.http.servlet_1.0.0.200704022148.jar with the JAR org.eclipse.equinox.http.servlet_1.1.0.201008310825.jar.

You workspace looks like this :

Now you can declare BrigeServlet with BridgeFilter (with Filter). To do that modify web.xml like this :

<?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">
	<filter id="bridge">
		<filter-name>equinoxbridgefilter</filter-name>
		<filter-class>org.eclipse.equinox.servletbridge.BridgeFilter</filter-class>
		<init-param>
			<param-name>commandline</param-name>
			<param-value>-console</param-value>			
		</init-param>		
		<init-param>
			<param-name>enableFrameworkControls</param-name>
			<param-value>true</param-value>			
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>equinoxbridgefilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!--
	  This is required if your application bundles expose JSPs. 
	-->	
	<filter-mapping>
		<filter-name>equinoxbridgefilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
		
</web-app>

You will notice that Servlet 2.4 is declared here :

<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">
...
</web-app>

Because Filter is available with <=Servlet 2.3. You could declare too Servlet 2.3 like this :

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
...
</web-app>

Retry

Restart your server and go at http://localhost:8080/bridge/index.htm, you will see the /index.htm content :

index.jsp

The bridge/WEB-INF/WebContent folder of the patch 323707 provides the index.jsp which display list of /sp_* commands frameworks. If you copy/paste it in your bridge/WEB-INF/WebContent and you go at http://localhost:8080/bridge/index.jsp, you will see the /sp_* whole commands with HTML links :

Why Filter using resolve the problem?

When BridgeServlet doesn’t find an OSGi services with the path required (ex : /index.jsp), the servlet send a 404 error, with this code

resp.sendError(HttpServletResponse.SC_NOT_FOUND, "BridgeServlet: " + req.getRequestURI());

When BridgeFilter doesn’t find an OSGi services with the path required (ex : /index.jsp), the filter gives the hand of the HTTP server by calling this code :

chain.doFilter(req, resp);

${workspace_loc} : Use bundles form the workspace

When you develop custom bundles (ex : sample.http, sample.http2….), you must create and deploy JARs as soon as you change your Java code of your bundle. In development mode, this action can be really annoying. The patch 323707 gives you the capability to use directly your bundles from your workspace (no need to create and deploy JARs).

This feature can works too with BridgeServlet. If you wish manage that, the only org.eclipse.equinox.servletbridge_1.2.0.201008301518.jar is required.

${workspace_loc}

patch 323707 gives you the capability to declare your bundles in the osgi.bundles property of the config.ini with :

reference\:file\:YOUR_PATH_FOLDER/YOUR_BUNDLE

where :

  • YOUR_PATH_FOLDER is the path folder of your bundles (ex : your workspace path location).
  • YOUR_BUNDLE is your bundle name (ex : sample.http).

In my case my workspace path location is D://_Projets/Personal/workspace-servletbridge-wordpress/step4, so I can write :

reference\:file\:/D\:/_Projets/Personal/workspace-servletbridge-wordpress/step4/sample.http

But path hard-declared is not very usefull when several developers works in the same project. So it’s possible (and it’s adviced) to use ${workspace_loc} wilcard like this :

${workspace_loc}/YOUR_BUNDLE

Here the osgi.bundles property of the config.ini used in this article :

osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@start, org.eclipse.equinox.http.servletbridge@start, org.eclipse.equinox.http.registry@start,${workspace_loc}/sample.http@start,${workspace_loc}/sample.http2@start,org.apache.felix.webconsole@start

The value of the ${workspace_loc} can be :

  • computed, if WEB Application is deployed inside the Eclipse Workspace.
  • or setted, if WEB Application is deployed outside the Eclipse Workspace.

WEB Application (deployed) INSIDE Workspace

When WEB Application is deployed inside the .metadata folder of the Workspace, ${workspace_loc} can be computed. This case comes from for instance with WTP Module (our case). For more information, please read WTP Deployment [step3].

To use sample.http and sample.http2 from the bundles workspace :

  • remove the bridge/WebContent/WEB-INF/eclipse/plugins/sample.http_1.0.0.jar and bridge/WebContent/WEB-INF/eclipse/plugins/sample.http2_1.0.0.jar
  • modify the bridge/WebContent/WEB-INF/eclipse/configuration/config.ini to use ${workspace_loc} like this :
    osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@start, org.eclipse.equinox.http.servletbridge@start, org.eclipse.equinox.http.registry@start,${workspace_loc}/sample.http@start,${workspace_loc}/sample.http2@start,org.apache.felix.webconsole@start
  • start your server and go at http://localhost:8080/bridge/sp_rdeploy

Check your config.ini replaced your old config.ini with your real Eclipse Workspace path. In my case I have :

osgi.bundles=org.eclipse.equinox.common@2\:start,org.eclipse.update.configurator@start,org.eclipse.equinox.http.servletbridge@start,org.eclipse.equinox.http.registry@start,reference\:file\:/D\:/_Projets/Personal/workspace-servletbridge-wordpress/step4/sample.http@start,reference\:file\:/D\:/_Projets/Personal/workspace-servletbridge-wordpress/step4/sample.http2@start,org.apache.felix.webconsole@start

Restart your server and type in the console View

ss

The OSGi console display the Short Status of the bundles installed :


...
15 ACTIVE sample.http_1.0.0
16 ACTIVE sample.http2_1.0.0

WEB Application (deployed) OUTSIDE Workspace

When WEB Application is deployed outside the .metadata folder of the Workspace, ${workspace_loc} must be setted. This case comes from for instance with WTP External Module. To set the workspace_loc value path, you can do it in the web.xml with init-param of the BridgeFilter (or BridgeServlet) like this :

<init-param>
  <param-name>workspace_loc</param-name>
  <param-value>D://_Projets/Personal/workspace-servletbridge-wordpress/step4</param-value>			
</init-param>

bundleClassPathEntries

At this step, sample.http2 compile Java classes to the /bin folder. To check that Open the Navigator View with Window/Show View/Other… and General/Navigator :

Sometimes you wish customize this output folder. To do that Go at Properties Project of the sample.http2 and click on Java Build Path node. Change « Default output folder » with sample.http2/bin2 :

Click OK and go to the Navigator View to check classes are stored in /bin2 folder :

Restart your server and type in the console View

ss

The OSGi console display the Short Status of the bundles installed :


...
15 ACTIVE sample.http_1.0.0
16 RESOLVED sample.http2_1.0.0

You will notice that sample.http is ACTIVE (it works) but sample.http2 is RESOLVED (problem).

If you try to force the start of the sample.http2 (in my case with start 16), you will see in the console :

osgi> start 16
org.osgi.framework.BundleException: The activator sample.http2.Activator for bundle sample.http2 is invalid
...
Caused by: java.lang.ClassNotFoundException: sample.http2.Activator
at java.net.URLClassLoader$1.run(Unknown Source)

The error show you that OSGi Equinox container cannot find classes of the sample.http2. To resolve that, you must configure BridgeFilter (or BridgeServlet) to set the classes output folder. In our case, we have :

  • /bin for the sample.http.
  • /bin2 for the sample.http2.

To configure that, you can do it in the web.xml with bundleClassPathEntries as init-param of the BridgeFilter (or BridgeServlet) like this :

<init-param>
  <param-name>bundleClassPathEntries</param-name>
  <param-value>bin,bin2</param-value>
</init-param>

Restart your server and type in the console View

ss

The OSGi console display the Short Status of the bundles installed :


...
15 ACTIVE sample.http_1.0.0
16 ACTIVE sample.http2_1.0.0

The sample.http and sample.http2 must be ACTIVE. Here the full web.xml used in this article :

<?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">
	<filter id="bridge">
		<filter-name>equinoxbridgefilter</filter-name>
		<filter-class>org.eclipse.equinox.servletbridge.BridgeFilter</filter-class>
		<init-param>
			<param-name>commandline</param-name>
			<param-value>-console</param-value>			
		</init-param>		
		<init-param>
			<param-name>enableFrameworkControls</param-name>
			<param-value>true</param-value>			
		</init-param>

		<!-- <init-param>
			<param-name>workspace_loc</param-name>
			<param-value>D://_Projets/Personal/workspace-servletbridge-wordpress/step4</param-value>			
		</init-param>
		 -->
		 
		 <init-param>
			<param-name>bundleClassPathEntries</param-name>
			<param-value>bin,bin2</param-value>
		</init-param>	
	</filter>
	<filter-mapping>
		<filter-name>equinoxbridgefilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!--
	  This is required if your application bundles expose JSPs. 
	-->	
	<filter-mapping>
		<filter-name>equinoxbridgefilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>
		
</web-app>

How it works?

To understand how it works, go at the Tomcat work folder where /eclipse folder is deployed (For more information, please read WTP Deployment [step3]). You will notice :

  • work/Catalina/localhost/bridge/eclipse/configuration/config.ini : ${workspace_loc} is replaced with your Workspace path location. In my case I have :
    osgi.bundles=...reference\:file\:/D\:/_Projets/Personal/workspace-servletbridge-wordpress/step4/sample.http@start,reference\:file\:/D\:/_Projets/Personal/workspace-servletbridge-wordpress/step4/sample.http2@start
  • work/Catalina/localhost/bridge/eclipse/dev.properties exists, which is a file generated when HTTP server start. It contains for each bundles declared with reference\:file the list of output folder to use :

    sample.http2=bin,bin2
    sample.http=bin,bin2

OSGi Equinox container (org.eclipse.core.runtime.adaptor.EclipseStarter()) is called with osgi.dev parameter by setting the path of the dev.properties file. For more informations about the Equinox OSGi container configuration, please read The Eclipse runtime options.

Conclusion

In this article we have seen that patch 323707 can be helpfull to :

  • host some resources (HTML, Javascript, Servlet…) in the bridge WEB Application.
  • use directly the OSGi bundle coming from the workspace with create and deploy a JAR in the /plugins folder.

In [step5], I will explain how we could use Equinox in Servlet Container to enjoy OSGi for an another features (different from HTTP services). We will transform bridge WEB Application to have (a simple) Electronic Document Management WEB application which manage Documentary Collection. Documentary Collection will be managed with an OSGi bundle that we will able to start/stop (with OSGi console) to register/unregister it to the Documentary Collections.

Catégories :Equinox ServletBridge
  1. Heng Sin
    décembre 22, 2010 à 3:50

    Hi, I come across your post when researhing on the possibilities of using the equinox http service registry inside an web application bundle ( wab ) on the eclipse geminiweb osgi web container. This looks great, will try to get this working inside WAB.

    • décembre 22, 2010 à 9:49

      Hi Heng,

      I’m happy that my post seems please you. Hope you will not have problem with WAB.

      Regards Angelo

  2. Heng Sin
    janvier 10, 2011 à 5:28

    Hi, I would like to update that using your patches, I have adapted the equinox servlet bridge to work inside a web application archive running on the gemini web container. The modified source is here: http://kenai.com/projects/hengsin/sources/development/show in three bundle – org.adempiere.eclipse.equinox.http.servlet, org.adempiere.eclipse.equinox.http.servletbridge and org.adempiere.eclipse.equinox.servletbridge. Example usage is in the org.adempiere.webstore and org.adempiere.webstore.servlet bundle.

    • janvier 11, 2011 à 8:10

      Hi Heng,

      Thank’s for your share. Perhaps it should be cool to provide your patch to Eclipse?

      Regards Angelo

  3. Anoop
    mars 14, 2011 à 2:47

    Do you have an example for how one can use Spring Dispatcher Servlet with the Bridge Filter ?

  4. Ahmed EL AMINE
    avril 7, 2011 à 8:46

    I’m really pleased with this post, it was for a great help to me. I couldn’t thank you enough for your great efforts and all that i learned here with you.

    Thank you.

    Best Rgrds,
    Ahmed EL AMINE

    • avril 7, 2011 à 8:48

      Hi Ahmed ,

      Thank a lot for your post. I’m happy that my articles can be help you.

      Regards Angelo

  5. Alex
    mars 15, 2013 à 7:20

    Hi *,

    just for convenience I want to edit my sources and see the changes immediately in the browser. This only works when Tomcat runs in DEBUG MODE in Eclipse.

    Happy coding

    Alex

  6. Eren
    mars 29, 2013 à 2:49

    Hi,

    i am getting ClassNotFound Exception for the Activator eventhough I can see created dev.properties includes my plugins /bin dir. I copied the bin directory directly to bundle root dir and it works without a problem what may be causing this so my runtime does not see the /bin as source folder.

    Regards
    Eren

  1. septembre 8, 2010 à 1:49
  2. septembre 8, 2010 à 2:30
  3. septembre 9, 2010 à 10:57

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :