GlassFish v3 and OSGi integration is now known for almost two years. Several blogs have been published on this topic and googling on "glassfish osgi" shows 817,000 results. This blog has published four entries on the topic so far.
This Tip Of The Day (TOTD) will show the different ways you can manage OSGi bundles in GlassFish v3.
The first part is to create a trivial OSGi bundle as explained in TOTD #36.
- Create a simple Maven project using the command as shown below:
~/samples/v3/osgi >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] ------------------------------------------------------------------------ [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] [archetype:create] [WARNING] This goal is deprecated. Please use mvn archetype:generate instead [INFO] Defaulting package to group ID: org.glassfish.samples.osgi.helloworld [INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: checking for updates from central [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating OldArchetype: 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: package, Value: org.glassfish.samples.osgi.helloworld [INFO] Parameter: artifactId, Value: helloworld [INFO] Parameter: basedir, Value: /Users/arungupta/samples/v3/osgi [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] OldArchetype created in dir: /Users/arungupta/samples/v3/osgi/helloworld [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 11 seconds [INFO] Finished at: Wed Jan 20 14:12:41 PST 2010 [INFO] Final Memory: 12M/80M [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 <packaging> to "bundle" from the default value of "jar".
- Add <dependency> on "org.osgi.core".
- Add the <plugin> maven-bundle-plugin and provide <instructions> to generate the appropriate MANIFEST.MF.
<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/osgi/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/osgi/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/osgi/helloworld/target/test-classes [INFO] [surefire:test] [INFO] Surefire report directory: /Users/arungupta/samples/v3/osgi/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.06 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [bundle:bundle] [INFO] [install:install] [INFO] Installing /Users/arungupta/samples/v3/osgi/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: 8 seconds [INFO] Finished at: Wed Jan 20 14:18:31 PST 2010 [INFO] Final Memory: 20M/80M [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.357 Bundle-Name: helloworld Created-By: Apache Maven Bundle Plugin Bundle-Version: 1.0.0.SNAPSHOT Build-Jdk: 1.6.0_17 Bnd-LastModified: 1264025910352 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
Lets install this newly created OSGi bundle in GlassFish v3. First, fire up GlassFish as:
~/tools/glassfish/v3/74b/glassfishv3/glassfish >./bin/asadmin start-domain -v Jan 20, 2010 2:30:39 PM com.sun.enterprise.admin.launcher.GFLauncherLogger info INFO: JVM invocation command line: /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java -cp /Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/glassfish.jar -XX:+UnlockDiagnosticVMOptions -XX:MaxPermSize=192m -XX:NewRatio=2 -XX:+LogVMOutput . . . Jan 20, 2010 2:30:40 PM com.sun.enterprise.admin.launcher.GFLauncherLogger info INFO: Successfully launched in 52 msec. Jan 20, 2010 2:30:40 PM com.sun.enterprise.glassfish.bootstrap.ASMain main INFO: Launching GlassFish on Felix platform Welcome to Felix ================ [#|2010-01-20T14:30:49.437-0800|INFO|glassfishv3.0|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=11;_ThreadName=FelixStartLevel;|Perform lazy SSL initialization for the listener 'http-listener-2'|#] [#|2010-01-20T14:30:49.527-0800|INFO|glassfishv3.0|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=12;_ThreadName=Thread-11;|Starting Grizzly Framework 1.9.18-k - Wed Jan 20 14:30:49 PST 2010|#] . . . [#|2010-01-20T14:30:58.668-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/, felix.fileinstall.debug=1};|Started bundle: file:/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/org.apache.felix.scr.jar|#] [#|2010-01-20T14:30:58.786-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/, felix.fileinstall.debug=1};|Started bundle: file:/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/osgi-web-container.jar|#] [#|2010-01-20T14:31:00.436-0800|INFO|glassfishv3.0|null|_ThreadID=23;_ThreadName=ping;|Total number of available updates : 0|#]
There are several ways to manage the OSGi bundles in GlassFish v3:
- The "asadmin" command (explained here)
- Filesystem operations using the pre-installed Apache Felix File Install bundle (explained here)
- A Telnet shell using pre-installed Apache Felix Remote Shell (explained here and TOTD #103)
- A Web browser using the Apache Felix Web Console (needs to be installed separately and more details below)
- A RESTful client by installing the REST console (need to be installed separately and more details below)
Lets explore each option in detail now.
Option 1: Manage the OSGi bundle using the "asadmin" command
- Deploy the generated OSGi bundle using asadmin command:
~/samples/v3/osgi/helloworld/target >~/tools/glassfish/v3/74b/glassfishv3/glassfish/bin/asadmin deploy --type osgi helloworld-1.0-SNAPSHOT.jar Application deployed successfully with name helloworld-1.0-SNAPSHOT. Command deploy executed successfully.
The server log shows the following output:
[#|2010-01-20T16:15:10.553-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=36;_ThreadName=http-thread-pool-4848-(2); |Hey!|#]
Notice "Hey!" message in the server log as the bundle gets started.
- Verify the installed bundle as:
~/samples/v3/osgi/helloworld/target >~/tools/glassfish/v3/74b/glassfishv3/glassfish/bin/asadmin list-applications helloworld-1.0-SNAPSHOT Command list-applications executed successfully.
Or if there are multiple applications deployed then only the OSGi bundles can be queried as:
~/samples/v3/osgi/helloworld/target >~/tools/glassfish/v3/74b/glassfishv3/glassfish/bin/asadmin list-applications --type osgi helloworld-1.0-SNAPSHOT Command list-applications executed successfully.
-
The bundle can be undeployed as:
~/samples/v3/osgi/helloworld/target >~/tools/glassfish/v3/74b/glassfishv3/glassfish/bin/asadmin undeploy helloworld-1.0-SNAPSHOT Command undeploy executed successfully.
And then the following message is shown on the console:
[#|2010-01-20T16:22:19.554-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=37;_ThreadName=http-thread-pool-4848-(1); |Bye!|#]
Notice "Bye!" message in second line of the log output indicating the bundle is stopped.
Option 2: Manage the OSGi bundle using file system operations
- Copy the generated jar (target/helloworld-1.0-SNAPSHOT.jar) in "modules/autostart" directory as:
~/tools/glassfish/v3/74b/glassfishv3/glassfish >cp ~/samples/v3/osgi/helloworld/target/helloworld-1.0-SNAPSHOT.jar modules/autostart/
and that shows the log output as:
[#|2010-01-20T16:29:04.625-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Installed /Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/ helloworld-1.0-SNAPSHOT.jar|#] [#|2010-01-20T16:29:04.635-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Hey!|#] [#|2010-01-20T16:29:04.636-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Started bundle: file:/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart /helloworld-1.0-SNAPSHOT.jar|#]
Notice "Hey!" message in the second line of log output as the bundle gets started.
- The bundle can be undeployed by removing the JAR file from "modules/autostart" directory as:
~/tools/glassfish/v3/74b/glassfishv3/glassfish >rm modules/autostart/helloworld-1.0-SNAPSHOT.jar
that shows the following output:
~/tools/glassfish/v3/74b/glassfishv3/glassfish >[#|2010-01-20T16:32:04.677-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Uninstalling bundle 224 (helloworld)|#] [#|2010-01-20T16:32:04.679-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Bye!|#] [#|2010-01-20T16:32:04.682-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=21;_ThreadName={felix.fileinstall.poll=5000, felix.fileinstall.bundles.new.start=true, felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish /modules/autostart/, felix.fileinstall.debug=1};|Uninstalled /Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart /helloworld-1.0-SNAPSHOT.jar|#]
Notice "Bye!" message in second line of the log output indicating the bundle is stopped.
Option 3: Manage the OSGi bundle using a remote Telnet Shell
- Connecting to the Felix Remote Shell as:
~/tools/glassfish/v3/74b/glassfishv3/glassfish >telnet localhost 6666 Trying ::1... telnet: connect to address ::1: Connection refused Trying fe80::1... telnet: connect to address fe80::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Felix Remote Shell Console: ============================ ->
- Install the bundle as:
-> install file:///Users/arungupta/samples/v3/osgi/helloworld/target/helloworld-1.0-SNAPSHOT.jar Bundle ID: 225
The command output shows "225" as the bundle id. This id is used to start / stop / uninstall the bundle.
- Check the bundle status as:
-> find hello START LEVEL 1 ID State Level Name [ 225] [Installed ] [ 1] helloworld (1.0.0.SNAPSHOT)
and then start, stop, and uninstall the bundle as:
-> start 225 -> stop 225 -> uninstall 225 -> find hello No matching bundles found
which shows following output in the logs:
[#|2010-01-20T16:43:45.399-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=38;_ThreadName=telnetconsole.shell remote=/127.0.0.1:4894;|Hey!|#] [#|2010-01-20T16:43:58.516-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=38;_ThreadName=telnetconsole.shell remote=/127.0.0.1:4894;|Bye!|#]
Notice "Hey!" and "Bye!" messages in the log output as the bundle is started and stopped.
Option 4 – Manage the OSGi bundle using a Web browser
Lets see how the OSGi bundles in GlassFish can be managed using Apache Felix Web Console. This is originally explained in Sahoo’s blog.
-
Copy GlassFish OSGi HTTP Service bundle from here (latest) and save it in the "modules/autostart" directory.
-
Copy Apache Felix Web Console bundle from here (latest) and save it in the "modules/autostart" directory.
-
Ignore the "NoClassDefFoundError" in the server log. The key is to look for the following message in server log:
Started bundle: file:/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/org.apache.felix.webconsole-2.0.4.jar|#]
-
Open the URL "http://localhost:8080/osgi/system/console/bundles" in a browser and use "admin" as the username and "admin" as the password as shown below:
I had to enter the credentials couple of times for the login to work but finally the following window showed up:
It shows a complete summary of all the OSGi bundles available/installed/active etc in GlassFish v3. A new OSGi bundle can be installed by clicking on "Choose File" button. Several administration commands such as Start/Stop, Update, Uninstall, Refresh Import Packages can be issued for each bundle by clicking on associated buttons.
-
Install the OSGi bundle by clicking on "Choose File" and selecting "helloworld-1.0.-SNAPSHOT.jar" and then click on "Install or Update" button. The following message is shown in the server log:
[#|2010-01-20T17:04:46.654-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com. sun.enterprise.v3.services.impl|_ThreadID=39;_ThreadName=Background Install /var/folders/+E/+E6YtSvGGEKNwOA77I-9Fk+++TI/-Tmp-/install1657418488877506078.tmp; |Hey!|#]
The bundle gets installed and started as identified by "Hey!" message.
The recently installed "HelloWorld" bundle looks like:
Clicking on "helloworld" shows the complete status about the bundle as shown below:
-
The bundle can be stopped by clicking on the Stopped, Refreshed Package Imports, Updated, and Uninstalled by clicking on the respective buttons in the "Actions" column. Clicking on the Stop button shows the following message:
[#|2010-01-20T17:10:56.359-0800|INFO|glassfishv3.0|javax.enterprise.system.std.com .sun.enterprise.v3.services.impl|_ThreadID=25;_ThreadName=http-thread-pool-8080-(2); |Bye!|#]
Notice "Bye!" message indicating the bundle has stopped.
Option 5: Manage the OSGi bundle using a REST console
- If not done already, copy GlassFish OSGi HTTP Service bundle from here (latest) and save it in the "modules/autostart" directory.
- Download the REST console bundle (latest) in "modules/autostart" directory.
- The complete list of bundles is available in Text or XML format by accessing the URL "http://localhost:8080/osgi/restconsole/bundles/.txt" or "http://localhost:8080/osgi/restconsole/bundles" respectively. Here is how the text output looks like:
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 16198 0 16198 0 0 1173k 0 --:--:-- --:--:-- --:--:-- 1173kbundles bundle id 0 symbolic-name org.apache.felix.framework . . . description Generated using Pax-Construct vendor version 1.0.0.SNAPSHOT location file:/Users/arungupta/tools/glassfish/v3/74b/glassfishv3/glassfish/modules/autostart/ com.knokode.osgi.restconsole.main-1.0-PREVIEW01.jar state ACTIVE
- The OSGi bundle should be installed by issuing the following command:
curl -X PUT file:///Users/arungupta/samples/v3/osgi/helloworld/target/helloworld-1.0-SNAPSHOT.jar http://localhost:8080/osgi/restconsole/bundles
but it’s giving a "Segmentation fault". Am following with @fdiotalevi.
Anyway, the complete usage information of the REST console is described here.
So how do you manage OSGi bundles in GlassFish v3 – asadmin, file system operations, telnet console, web browser, or REST ?
A complete archive of all the TOTDs is available here.
Technorati: totd glassfish v3 osgi apache felix bundles maven
Related posts:- TOTD #125: Creating an OSGi bundles using NetBeans and deploying in GlassFish
- TOTD #131: Dynamic OSGi services in GlassFish – Using ServiceTracker
- TOTD #127: Embedding GlassFish in an existing OSGi runtime – Eclipse Equinox
- TOTD #36: Deploy OSGi bundles in GlassFish using maven-bundle-plugin
- TOTD #103: GlassFish v3 with different OSGi runtimes – Felix, Equinox, and Knoplerfish
I like your blog Let’s excange some info. I write quite a specialist blog
Comment by Iala — March 8, 2010 @ 8:33 am