 |
TOTD #36: Deploy OSGi bundles in GlassFish using maven-bundle-plugin
Posted by arungupta on June 26, 2008 at 06:15 AM | Comments (6)
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.
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> |
-
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 |
Now let's install this newly created bundle using Felix shell in
GlassFish v3. Check out and build GlassFish v3 workspace as explained
in TOTD
#33. Unzip
"~/workspaces/glassfish/v3/distributions/web/target/web.zip" and enable
Felix
TUI as explained in TOTD
#34.
- 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: -> |
So following this blog you can deploy any of your OSGi bundles in
GlassFish v3.
Technorati: glassfish
v3 osgi maven mavenbundleplugin
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Hi Arun,
Thanks for sharing this. However I do have one question. Does glasfish does have some sort of pickup folder, which will load a bundle into felix once in this folder?
Thanks.
Regards Vincent
Posted by: vincentkok on November 04, 2008 at 09:03 AM
-
Vincent, OSGi bundles can be dropped in "modules" directory and will automatically get loaded.
Posted by: arungupta on November 04, 2008 at 01:34 PM
-
is it possible to start glassfish in one process and
start a separate process to manage osgi bundles.
I would like to start/stop the osgi felix cli without having to start/stop glassfish itself.
thank you
Posted by: christian_cadieux on November 21, 2008 at 10:15 AM
-
Please post your question to users@glassfish.dev.java.net and somebody may know.
Posted by: arungupta on December 05, 2008 at 05:46 PM
-
There is something missing between step 5 and step 6. I believe that step 6, 7, 8, 9, 10 are all Felix shell command. How do I start Felix shell after I start Glassfish?
In Felix standalone environment, I can start Felix shell by "java -jar bin/felix.jar". If I do the same for Felix under Glassfish. I will be prompted with profile name:
I am using glassfishv3-prelude instead of building myself.
Posted by: threecuptea on January 21, 2009 at 11:37 AM
-
Felix shell is started as part of v3 startup. v3 Prelude shows a message like:
INFO: GlassFish v3 Prelude startup time : Felix(1732ms) startup services(1091ms) total(2823ms)
It clearly shows how much time is taken to startup Felix. TOTD# 34 (http://blogs.sun.com/arungupta/entry/totd_34_using_felix_shell) shows how to start Felix shell. Are you looking for something else ?
Posted by: arungupta on January 21, 2009 at 01:28 PM
|