TOTD #36: Deploy OSGi bundles in GlassFish using maven-bundle-plugin
GlassFish v3 is a modular (OSGi compliant), embeddable (runs in-VM) and extensible (supports non-Java apps) Application Server.
The extensible part is demonstrated by deployment of Rails and Grails applications. An example of embeddability is an in-VM Servlet. This blog demonstrates how a simple OSGi bundle can be easily created using Maven Bundle Plugin and deployed on v3 trunk.
- Generate a simple Maven project using the command as shown
below:
~/samples/v3 >mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=org.glassfish.samples.osgi.helloworld -DartifactId=helloworld
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] Ignoring available plugin update: 2.0-alpha-3 as it requires Maven version 2.0.7
[INFO] Ignoring available plugin update: 2.0-alpha-2 as it requires Maven version 2.0.7
[INFO] Ignoring available plugin update: 2.0-alpha-1 as it requires Maven version 2.0.7
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:create] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] **************************************************************
[INFO] Starting Jakarta Velocity v1.4
[INFO] RuntimeInstance initializing.
[INFO] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties
[INFO] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl)
[INFO] Resource Loader Instantiated: org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader
[INFO] ClasspathResourceLoader : initialization starting.
[INFO] ClasspathResourceLoader : initialization complete.
[INFO] ResourceCache : initialized. (class org.apache.velocity.runtime.resource.ResourceCacheImpl)
[INFO] Default ResourceManager initialization complete.
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Include
[INFO] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
[INFO] Created: 20 parsers.
[INFO] Velocimacro : initialization starting.
[INFO] Velocimacro : adding VMs from VM library template : VM_global_library.vm
[ERROR] ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
[INFO] Velocimacro : error using VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'VM_global_library.vm'
[INFO] Velocimacro : VM library template macro registration complete.
[INFO] Velocimacro : allowInline = true : VMs can be defined inline in templates
[INFO] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
[INFO] Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed.
[INFO] Velocimacro : initialization complete.
[INFO] Velocity successfully started.
[INFO] [archetype:create]
[INFO] Defaulting package to group ID: org.glassfish.samples.osgi.helloworld
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating Archetype: maven-archetype-quickstart:RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.glassfish.samples.osgi.helloworld
[INFO] Parameter: packageName, Value: org.glassfish.samples.osgi.helloworld
[INFO] Parameter: basedir, Value: /Users/arungupta/samples/v3
[INFO] Parameter: package, Value: org.glassfish.samples.osgi.helloworld
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: helloworld
[INFO] ********************* End of debug info from resources from generated POM ***********************
[INFO] Archetype created in dir: /Users/arungupta/samples/v3/helloworld
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Jun 25 10:07:27 PDT 2008
[INFO] Final Memory: 5M/10M
[INFO] ------------------------------------------------------------------------ - Change the generated App class in
"src/main/java/org/glassfish/samples/osgi/helloworld" folder so that it
looks like:
package org.glassfish.samples.osgi.helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
* Hello world!
*
*/
public class App implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Hey!");
}
public void stop(BundleContext context) throws Exception {
System.out.println("Bye!");
}
}
This is a trivial Activator class but sitll shows the key methods. The changes are highlighted in bold. - Update "pom.xml" with the following changes:
- Change the <packaging> to "bundle" from the default value of "jar".
- Add the <dependency> on "org.osgi.core".
- Add the <plugin> maven-bundle-plugin and provide <instructions> to generate the appropriate MANIFEST.MF.
-
Generate the OSGi bundle as shown below:
~/samples/v3/helloworld >mvn install
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building helloworld
[INFO] task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to /Users/arungupta/samples/v3/helloworld/target/classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to /Users/arungupta/samples/v3/helloworld/target/test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: /Users/arungupta/samples/v3/helloworld/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.glassfish.samples.osgi.helloworld.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.022 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] [bundle:bundle]
[INFO] [install:install]
[INFO] Installing /Users/arungupta/samples/v3/helloworld/target/helloworld-1.0-SNAPSHOT.jar to /Users/arungupta/.m2/repository/org/glassfish/samples/osgi/helloworld/helloworld/1.0-SNAPSHOT/helloworld-1.0-SNAPSHOT.jar
[INFO] [bundle:install]
[INFO] Parsing file:/Users/arungupta/.m2/repository/repository.xml
[INFO] Installing org/glassfish/samples/osgi/helloworld/helloworld/1.0-SNAPSHOT/helloworld-1.0-SNAPSHOT.jar
[INFO] Writing OBR metadata
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Wed Jun 25 10:20:27 PDT 2008
[INFO] Final Memory: 22M/54M
[INFO] ------------------------------------------------------------------------
The generated "target/helloworld-1.0-SNAPSHOT.jar" has the following contents:
META-INF/MANIFEST.MF
META-INF/
META-INF/maven/
META-INF/maven/org.glassfish.samples.osgi.helloworld/
META-INF/maven/org.glassfish.samples.osgi.helloworld/helloworld/
META-INF/maven/org.glassfish.samples.osgi.helloworld/helloworld/pom.properties
META-INF/maven/org.glassfish.samples.osgi.helloworld/helloworld/pom.xml
org/
org/glassfish/
org/glassfish/samples/
org/glassfish/samples/osgi/
org/glassfish/samples/osgi/helloworld/
org/glassfish/samples/osgi/helloworld/App.class
And the generated "MANIFEST.MF" looks like:
Manifest-Version: 1.0
Export-Package: org.glassfish.samples.osgi.helloworld;uses:="org.osgi.
framework"
Built-By: arungupta
Tool: Bnd-0.0.255
Bundle-Name: helloworld
Created-By: Apache Maven Bundle Plugin
Bundle-Version: 1.0.0.SNAPSHOT
Build-Jdk: 1.6.0_05
Bnd-LastModified: 1214414426851
Bundle-ManifestVersion: 2
Bundle-Activator: org.glassfish.samples.osgi.helloworld.App
Import-Package: org.glassfish.samples.osgi.helloworld,org.osgi.framewo
rk;version="1.3"
Bundle-SymbolicName: helloworld
The updated "pom.xml" with changes highlighted in bold are shown below:
| <project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.glassfish.samples.osgi.helloworld</groupId> <artifactId>helloworld</artifactId> <packaging>bundle</packaging> <version>1.0-SNAPSHOT</version> <name>helloworld</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Export-Package>${pom.groupId}</Export-Package> <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> <Bundle-Activator>${pom.groupId}.App</Bundle-Activator> </instructions> </configuration> </plugin> </plugins> </build> </project> |
- Start GlassFish v3 as:
~/testbed/glassfish/v3/snapshot/glassfish >java -jar modules/glassfish-10.0-SNAPSHOT.jar
Jun 25, 2008 4:09:19 PM com.sun.enterprise.glassfish.bootstrap.ASMain main
INFO: Launching GlassFish on Apache Felix OSGi platform
Jun 25, 2008 4:09:19 PM com.sun.enterprise.glassfish.bootstrap.ASMainOSGi getSharedRepos
INFO: /Users/arungupta/testbed/glassfish/v3/snapshot/glassfish/domains/domain1/lib does not exist
Welcome to Felix.
=================
Jun 25, 2008 4:09:20 PM HK2Main start
INFO: contextRootDir = /Users/arungupta/testbed/glassfish/v3/snapshot/glassfish/modules
Jun 25, 2008 4:09:20 PM OSGiFactoryImpl initialize
INFO: Singleton already initialized as com.sun.enterprise.module.impl.HK2Factory@3d44d0c6
Jun 25, 2008 4:09:20 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.common.glassfish-mbeanserver [19]
Jun 25, 2008 4:09:20 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.core.kernel [51]
Jun 25, 2008 4:09:21 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.common.glassfish-naming [8]
Jun 25, 2008 4:09:21 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.admin.config-api [43]
Jun 25, 2008 4:09:21 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.common.internal-api [33]
Jun 25, 2008 4:09:21 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.deployment.deployment-common [10]
Jun 25, 2008 4:09:21 PM
INFO: JMXMP connector server URL = service:jmx:jmxmp://localhost:8888
Jun 25, 2008 4:09:21 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
INFO: Listening on port 8080
Jun 25, 2008 4:09:21 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
INFO: Listening on port 8181
Jun 25, 2008 4:09:21 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
INFO: Listening on port 4848
Jun 25, 2008 4:09:21 PM OSGiModuleImpl loadClass
INFO: Started bundle org.glassfish.common.container-common [21]
Jun 25, 2008 4:09:22 PM com.sun.enterprise.v3.admin.adapter.AdminConsoleAdapter setContextRoot
INFO: Admin Console Adapter: context root: /admin
Jun 25, 2008 4:09:22 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: Glassfish v3 started in 1789 ms
Jun 25, 2008 4:09:22 PM
INFO: ->
Jun 25, 2008 4:09:22 PM com.sun.enterprise.glassfish.bootstrap.ASMainFelix launchOSGiFW
INFO: Framework successfully started - Install the Hello World bundle as:
install file:///Users/arungupta/samples/v3/helloworld/target/helloworld-1.0-SNAPSHOT.jar
Jun 25, 2008 4:10:19 PM
INFO: Bundle ID: 75
Jun 25, 2008 4:10:19 PM
INFO: ->
The command output shows "75" as the process id. This id is used to start/stop/uninstall the bundle later. - Check the bundle status
ps
Jun 25, 2008 4:10:27 PM
INFO: START LEVEL 1
Jun 25, 2008 4:10:27 PM
INFO: ID State Level Name
Jun 25, 2008 4:10:27 PM
INFO: [ 0] [Active ] [ 0] System Bundle (1.0.4)
Jun 25, 2008 4:10:27 PM
INFO: [ 1] [Active ] [ 1] org.jvnet.tiger-types repackaged as module (0.3.2)
Jun 25, 2008 4:10:27 PM
. . .
INFO: [ 71] [Installed ] [ 1] Web module command line interface (10.0.0.SNAPSHOT)
Jun 25, 2008 4:10:27 PM
INFO: [ 72] [Installed ] [ 1] Admin GUI Web Container Plugin (10.0.0.SNAPSHOT)
Jun 25, 2008 4:10:27 PM
INFO: [ 75] [Installed ] [ 1] helloworld (1.0.0.SNAPSHOT)
Jun 25, 2008 4:10:27 PM
INFO: ->
The last log output shows the newly added process. - Start the bundle as:
start 75
Jun 25, 2008 4:10:32 PM
INFO: Hey!
Jun 25, 2008 4:10:32 PM
INFO: ->
This fragment shows "Hey!" output printed from the start method of Activator. - Stop the bundle as:
stop 75
Jun 25, 2008 4:10:35 PM
INFO: Bye!
Jun 25, 2008 4:10:35 PM
INFO: ->
This fragment shows "Bye!" output printed from the stop method of Activator. - And finally uninstall the bundle as:
uninstall 75
Jun 25, 2008 4:10:42 PM
INFO: ->
- arungupta's blog
- Login or register to post comments
- 295 reads
- Flag as offensive
- Email this Blog entry
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






