If you have not read Part1 and Part2, please first read them.
In this part, we will introduce Glassfish OSGi Web Container and start our travel from creating a wab using maven and deploying it into glassfish v4. In the next parts, I will look into Glassfish OSGi Web Container in depth and introduce which features Glassfish OSGi Web Container has providered us with and which features we are implementing.
As is mentioned in Part1, Glassfish OSGi Web Container is implemented in fighterfish/module/osgi-web-container. Firstly, let us see the responsibility of Glassfish OSGi Web Container or simply saying, it does what?
[My Understanding]
"Glassfish OSGi Web Container is used for implementing OSGi R4 version 4.2 Enterprise Specification - 128 Web Applications Specification, and the Web Applications Specification is mainly used for defining and supporting a new OSGi bundle form called Web Application Bundle(WAB) which can run in both an OSGi bundle context and a Java EE context"
Simply saying, according to GF-OSGi-Features , When a web application is packaged and deployed as an OSGi bundle, it is called a Web Application Bundle(WAB).
Next, I will start to explore Glassfish OSGi Web Container from creating a wab sample.
In the sample, I will create a bundle activator used for demostrating that while deploying the wab into Glassfish OSGi context, the activator will be invoked, at the same time, I will also create a servlet using Servlet 3.0 to make the wab can run in JavaEE context while deploying the wab into Glassfish JavaEE context. In addition, for my favorite, I will use Maven + Eclipse to develop such a wab.
1. Creating a wab called "helloworldwab"
1) generating a simple maven project using the following directive
mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.fujitsu.cn.samples.osgi.helloworldwab -DartifactId=helloworldwab
2) adding dependencies into pom.xml
Because the sample will import org.osgi.framework.BundleActivator and javax.servlet.* and javax.servlet.http.*, we must add these dependencies into pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
3) generating eclipse related project file to import the maven project into eclipse
executing "mvn eclipse:eclipse"
4) importing the maven project into eclipse
[File]->[Import]->"Existing Projects into Workspace"
5) making App class (you can change into more friend name) generated by maven to implement BundleActivator interface
6) Creating a Servlet called "HelloWorldServlet"
Adding the following code into this Servlet.
7) Preparing to package the wab
① modify pom to change "<packaging>jar</packaging>" into "<packaging>war</packaging>"
We need war form rather than common jar.
② adding two plugins into pom's <build> as following:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>ejb</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>jar</supportedProjectType>
</supportedProjectTypes>
<instructions>
<!-- Specify elements to add to MANIFEST.MF -->
<Web-ContextPath>/wabclient</Web-ContextPath>
<!-- By default, nothing is exported -->
<Export-Package>!*</Export-Package>
<Bundle-Activator>com.fujitsu.cn.samples.osgi.helloworldwab.App</Bundle-Activator>
</instructions>
</configuration>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
<execution>
<id>bundle-install</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<!-- add bundle plugin generated manifest to the war -->
<manifestFile>
${project.build.outputDirectory}/META-INF/MANIFEST.MF
</manifestFile>
<!-- For some reason, adding Bundle-ClassPath in maven-bundle-plugin
confuses that plugin and it generates wrong Import-Package, etc. So, we generate
it here. -->
<manifestEntries>
<Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
</manifestEntries>
</archive>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
This is the most critical step for packaging a wab successfully. There are some notes as following:
- we use maven-bundle-plugin to package a OSGi bundle rather than common jar
we also need to add a series of "instructions" to package the wab rightly, for example,
<Web-ContextPath> tells us that the war is a wab, and <Bundle-Activator> tells us that the wab has an activator which will be invoked by OSGi runtime while starting the wab.
About detailed "instructions" , please seeing apache-felix-maven-bundle-plugin .
- we also use maven-war-plugin to package a war deployment structure because virtually a wab is also a war.
8) installing the wab
Backing to command shell, we start to install the wab by executing the following command,
mvn clean install
After executing the above command, you will see an artifact called "helloworldwab-1.0-SNAPSHOT.war" in target directory. If you unzip the war, you will find that in MANIFEST.MF, the following contents will be generated,
Manifest-Version: 1.0
Bundle-ClassPath: WEB-INF/classes/
Built-By: Administrator
Tool: Bnd-1.50.0
Bundle-Name: helloworldwab
Created-By: Apache Maven Bundle Plugin
Web-ContextPath: /wabclient
Build-Jdk: 1.7.0_09
Bundle-Version: 1.0.0.SNAPSHOT
Bnd-LastModified: 1363100030484
Bundle-ManifestVersion: 2
Bundle-Activator: com.fujitsu.cn.samples.osgi.helloworldwab.App
Import-Package: javax.servlet,javax.servlet.annotation,javax.servlet.h
ttp,org.osgi.framework;version="[1.5,2)"
Bundle-SymbolicName: com.fujitsu.cn.samples.osgi.helloworldwab
Archiver-Version: Plexus Archiver
Congratulations! you have installed a right wab. And next, we will deploy the wab into Glassfish v4.
2. Deploying the wab into Glassfish v4
1) Preparing a Glassfish v4 distro
You have two ways to obtain a glassfish v4 distro, because currently, glassfish v4 is still in development, you can only obtain by
① http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/
② building a v4 SNAPSHOT according to https://wikis.oracle.com/display/GlassFish/FullBuildInstructions
2) starting glassfish domain
Opening a command shell and executing the following command to start glassfish domain
asadmin start-domain domain1
3) using deploy command to deploy the wab into Glassfish domain
asadmin deploy --type=osgi helloworldwab-1.0-SNAPSHOT.war
Noting: you must add "--type=osgi" , otherwise, you are deploying a common war rather than wab.
After deploying successfully, you should see the following in server.log
"helloworldwab has been in OSGi context!"
3. Accessing the wab from your favorate broswer
eg. openning firefox, and accessing "http://localhost:8080/wabclient/HelloWorldServlet", you will see " Hello, This is a Web Application Bundle!"
We provide parent pom.xml that you can easily extend or look at to build OSGi enabled Java EE bundles. The parent pom is available at [1]. You can see its use in our sample applications available at [2].
Sahoo
[1] http://search.maven.org/#artifactdetails|org.glassfish.fighterfish|sample.parent-pom|1.0.2|pom
[2] https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/sample
Posted by: Sahoo | 2013/03/13 at 00:07
Thanks Sahoo's comments!
Right, fighterfish sample is a good place to learn how to use Glassfish OSGi-JavaEE rightly.
Posted by: Tang Yong | 2013/03/13 at 21:29