Wednesday Jun 25, 2008

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.
  1. 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] ------------------------------------------------------------------------
  2. 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.
  3. Update "pom.xml" with the following changes:
    1. Change the <packaging> to "bundle" from the default value of "jar".
    2. Add the <dependency> on "org.osgi.core".
    3. 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>
  4. 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.
  1. 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
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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
About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today