Wednesday Apr 28, 2010

TOTD #131: Dynamic OSGi services in GlassFish - Using ServiceTracker

OSGi is the dynamic module system for Java. Each module, or bundle as called in OSGi terminology, is packaged as a JAR file and the inbound and outbound dependencies are explicitly defined using the META-INF/MANIFEST.MF in the JAR file. A complex software system may be broken into multiple modules where each module may be exposing a set of services. These services are then consumed by some other "client" OSGi bundles. The beauty of dynamic nature of OSGi is that each bundle can be easily updated without restarting the framework and any reference to the service in the "client" bundles is also updated accordingly. However the client needs to ensure that they are watching out for changes in the lifecycle of "service" bundle.

GlassFish's modular architecture is based upon OSGi. The different capabilities such as Web container, EJB container, and RESTful Web services are provided as OSGi modules. The OSGi framework is available to developers as well so that they can construct their application as OSGi modules and leverage all the goodness.

This Tip Of The Day (TOTD) explains an OSGi design pattern that allows the client to track the dynamic discovery of an OSGi service. This means that client keeps a reference to the service which is automatically refreshed if the bundle providing the service is refreshed. And of course, it uses GlassFish to deploy the bundles :-)

For those, who prefer to see the results directly, download and unzip this zip file:

  1. Give the following command in the root directory:
    mvn clean install
    
  2. Copy the generated bundles to "domains/domain1/autodeploy/bundles" directory as:
    cp helloworld-api/target/helloworld-api-1.0-SNAPSHOT.jar \\
    helloworld-impl/target/helloworld-impl-1.0-SNAPSHOT.jar \\
    helloworld-client/target/helloworld-client-1.0-SNAPSHOT.jar \\
    ~/tools/glassfish/v3/final/glassfishv3/glassfish/domains/domain1/autodeploy/bundles
    

    The following log messages will be displayed in the console:
    [#|2010-04-28T17:03:55.090-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
    services.impl|_ThreadID=23;_ThreadName=Thread-23;|Getting a new service|#]
    
    [#|2010-04-28T17:03:55.091-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
    services.impl|_ThreadID=23;_ThreadName=Thread-23;|Hello Duke|#]
    
    [#|2010-04-28T17:03:57.091-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
    services.impl|_ThreadID=23;_ThreadName=Thread-23;|Getting a new service|#]
    
    [#|2010-04-28T17:03:57.092-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
    services.impl|_ThreadID=23;_ThreadName=Thread-23;|Hello Duke|#]
    
    

    The log messages from the client bundle invoking the service bundle are highlighted in bold.
  3. Update the service implementation
    1. Edit service implementation in "hello-impl/src/main/java/org/samples/osgi/helloworld/impl/HelloImpl.java" and change the "return" statement from:
      return "Hello " + name;
      
      to
      return "Howdy " + name;
      
    2. Create the service implementation bundle again by giving the command:
      mvn clean install
      

      in the "helloworld-impl" directory.
    3. Copy the updated bundle from "helloworld-impl/target/helloworld-impl-1.0-SNAPSHOT.jar" to "glassfishv3/glassfish/domains/domain1/autodeploy/bundles" directory. The following sequence of log messages will be seen:
      [#|2010-04-28T17:04:47.110-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
      services.impl|_ThreadID=23;_ThreadName=Thread-23;|Getting a new service|#]
      
      [#|2010-04-28T17:04:47.110-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
      services.impl|_ThreadID=23;_ThreadName=Thread-23;|Hello Duke|#]
      
      [#|2010-04-28T17:04:48.151-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
      services.impl|_ThreadID=22;_ThreadName={felix.fileinstall.poll=5000, 
      felix.fileinstall.bundles.new.start=true, service.pid=org.apache.felix.fileinstall.b0b03c1b-5a58-457d-bfde-116be31299f0,
      felix.fileinstall.dir=/Users/arungupta/tools/glassfish/v3/final/glassfishv3/glassfish/domains/domain1
      /autodeploy/bundles/, felix.fileinstall.filename=org.apache.felix.fileinstall-autodeploy-bundles.cfg, 
      service.factorypid=org.apache.felix.fileinstall, felix.fileinstall.debug=1};|Updated 
      /Users/arungupta/tools/glassfish/v3/final/glassfishv3/glassfish/domains/domain1/autodeploy/bundles/
      helloworld-impl-1.0-SNAPSHOT.jar|#]
      
      [#|2010-04-28T17:04:49.110-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
      services.impl|_ThreadID=23;_ThreadName=Thread-23;|Getting a new service|#]
      
      [#|2010-04-28T17:04:49.111-0700|INFO|glassfishv3.0|javax.enterprise.system.std.com.sun.enterprise.v3.
      services.impl|_ThreadID=23;_ThreadName=Thread-23;|Howdy Duke|#]
      

      As evident from the log messages, "Hello Duke" message is printed first, the service implementation bundle gets refreshed, and then the message from the updated service implementation, i.e. "Howdy Duke" is printed. Notice, only the service implementation got refreshed.

Now some explanation!

The application is split into 3 bundles - API, Impl, and Client. Splitting into 3 bundles allows cleaner separation and other implementations of the service  to show up relying purely upon the API bundle.

The "API" bundle (helloworld-api) has one class with the following interface:

package org.samples.osgi.helloworld.api;

public interface Hello {
    public String sayHello(String name);
}

This bundle has the following manifest entry:

<Export-Package>${pom.groupId}.api</Export-Package>

to ensure that the package with the service interface is exported and available for imports by service implementers. The "Impl" bundle (helloworld-impl) has the trivial implementation of this interface as:
package org.samples.osgi.helloworld.impl

import org.samples.osgi.helloworld.api.Hello;

public class HelloImpl implements Hello {
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

And the bundle's activator registers the service as:

package org.samples.osgi.helloworld.impl;

import java.util.Properties;
import org.samples.osgi.helloworld.api.Hello;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class App implements BundleActivator {

    public void start(BundleContext bc) throws Exception {
        bc.registerService(Hello.class.getName(), new HelloImpl(), new Properties());
    }

    public void stop(BundleContext bc) throws Exception {
        bc.ungetService(bc.getServiceReference(Hello.class.getName()));
    }
}

This bundle defines the dependency on the package exported earlier as:

<dependency>
 <groupId>${pom.groupId}</groupId>
 <artifactId>helloworld-api</artifactId>
 <version>1.0-SNAPSHOT</version>
 </dependency>

and also imports the appropriate packages as:

<Import-Package>${pom.groupId}.api, org.osgi.framework</Import-Package>

The "client" bundle's (helloworld-client) activator uses "org.osgi.util.tracker.ServiceTracker" for the dynamic discovery of service. The code looks like:

package org.samples.osgi.helloworld.client;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.samples.osgi.helloworld.api.Hello;

public class App implements BundleActivator {
    BundleContext ctx;
    ServiceTracker tracker;

    public void start(BundleContext context) {
        System.out.println("Starting client bundle");

        this.ctx = context;        

        // Create a service tracker to monitor Hello services.
        tracker = new ServiceTracker(context, Hello.class.getName(), null);
        tracker.open();

        new PingService(tracker).start();
    }

    public void stop(BundleContext context) {
        System.out.println("Stopping client bundle");
        tracker.close();
    }

    private class PingService extends Thread {
        ServiceTracker tracker;

        PingService(ServiceTracker tracker) {
            this.tracker = tracker;
        }

        public void run() {
            try {
                while (true) {
                    Thread.sleep(2000);
                    System.out.println("Getting a new service");
                    Hello hello = (Hello) tracker.getService();
                    if (hello == null)
                        System.out.println("No service found!"); 
                    else      
                        System.out.println(hello.sayHello("Duke"));
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

The ServiceTracker API allows customized service tracking and find services that meet search criteria defined by filters. Basically it listens to different service events and gets/ungets the service accordingly. In this case, a "ServiceTracker" is created to track the service by specifying the class name. The "tracker.open()" starts the service tracking. A new thread is started which pings the service every 2 seconds and prints the received response. Notice, a new service is retrieved from the service tracker as the service bundle might have been refreshed.

Please read through OSGi javadocs for more details on these APIs.

A future blog will show how a Java EE 6 MVC-based application can be split into multiple OSGi bundles using this design pattern.

How are you using dynamic discovery of services in OSGi ?

Technorati: totd osgi modules glassfish v3 felix dynamic discovery

Thursday Jan 21, 2010

TOTD #119: Telnet to GlassFish v3 with NetBeans 6.8 - "Could not open connection to the host"

As explained in TOTD #118, one of the ways to manage OSGi bundles in GlassFish is by giving the command "telnet localhost 6666".

This straight forward command works fine if you installed either the Sun GlassFish Enterprise Server or the GlassFish community bits. The "domain.xml" in both of them is pre-configured for the telnet port to 6666 using the "jvm-options" as shown below:

<jvm-options>-Dosgi.shell.telnet.port=6666</jvm-options>

However if you installed GlassFish as part of NetBeans 6.8, then you might see an error message as shown below:

C:\\Users\\Arun>telnet localhost 6666
Connecting To localhost...Could not open connection to the host, on
port 6666: Connect failed

This error is more prominent in Windows Vista / 7 because of the Windows User Account Control (UAC). Or anywhere where GlassFish is installed in a directory that require root/administrator/sudo access to read/write. This Tip Of The Day will explain how to workaround this issue.

The default NetBeans installation directory is "C:\\Program Files\\NetBeans 6.8" and GlassFish goes in "C:\\Program Files\\sges-v3". At first start of NetBeans (typically as a non-Administrator), it tries to register the pre-configured domain in GlassFish installed in "C:\\Program Files". But the non-Adminstrator user do not have read/write access to "C:\\Program Files" and any sub-directories. So NetBeans create a new "personal" domain and assign a random port available at that moment for telnet. It shows all the ports assigned during the domain creation as shown below:

The image shows the port number "22007" for OSGI_SHELL.

How do you find that port later ? - Go to "Services" tab, expand "Servers", right-click on "Personal GlassFish v3 Domain", select "Properties" from the popup menu to see the following window:

The "Domains folder" shows the directory location of newly created domain and "Domain Name" has the domain name. The exact assigned port can be found by looking at "Domains folder"\\"Domain Name"\\config\\domain.xml. On my Windows7, it showed the following line:

<jvm-options>-Dosgi.shell.telnet.port=22007</jvm-options>


So I tried "telnet localhost 22007" and voila, it worked!

Some other possible solutions that will work:

  1. Delete ".netbeans" directory and restart NetBeans by right-clicking on selecting "Run as administrator". This will provide the required rights for NetBeans to read/write "C:\\Program Files\\sges-v3\\glassfish\\domains\\domain1" directory. And so instead of creating a new "personal" domain, it'll register the existing domain in "\\Program Files\\sges-v3\\glassfish". Then "telnet localhost 6666" will work as expected.
  2. During NetBeans installation, specify GlassFish installation directory in a user directory such as:



    This will ensure that NetBeans will have required privileges to read/write the "domains\\domain1" directory.
  3. Delete the "Personal GlassFish v3 Domain" and register a new instance that is already installed in a user directory.
  4. Disable UAC.

A complete archive of all the TOTDs is available here.

Technorati: totd netbeans glassfish v3 felix osgi telnet

Wednesday Jan 20, 2010

TOTD #118: Managing OSGi bundles in GlassFish v3 - asadmin, filesystem, telnet console, web browser, REST, osgish

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.

  1. 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] ------------------------------------------------------------------------
    
  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 <packaging> to "bundle" from the default value of "jar".
    2. Add <dependency> on "org.osgi.core".
    3. 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>
      

  4. 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:

  1. The "asadmin" command (explained here)
  2. Filesystem operations using the pre-installed Apache Felix File Install bundle (explained here)
  3. A Telnet shell using pre-installed Apache Felix Remote Shell (explained here and TOTD #103)
  4. A Web browser using the Apache Felix Web Console (needs to be installed separately and more details below)
  5. 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

  1. 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.
  2. 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.
    
  3. 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

  1. 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.
  2. 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

  1. 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:
    ============================
    
    ->
    
  2. 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.
  3. 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.

  1. Copy GlassFish OSGi HTTP Service bundle from here (latest) and save it in the "modules/autostart" directory.

  2. Copy Apache Felix Web Console bundle from here (latest) and save it in the "modules/autostart" directory.

  3. 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|#]
    
  4. 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.

  5. 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:

     

  6. 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

  1. If not done already, copy GlassFish OSGi HTTP Service bundle from here (latest) and save it in the "modules/autostart" directory.
  2. Download the REST console bundle (latest) in "modules/autostart" directory.
  3. 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
    
  4. 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 ?

UPDATE: Osgish is a command-line shell for OSGi and implemented in Perl. See the complete installation instructions and it can be used to manage OSGi runtime in GlassFish as well.

A complete archive of all the TOTDs is available here.

Technorati: totd glassfish v3 osgi apache felix bundles maven

Monday Sep 14, 2009

TOTD #103: GlassFish v3 with different OSGi runtimes – Felix, Equinox, and Knoplerfish

GlassFish v3 uses standard OSGi APIs to achieve modularity. It bundles Apache Felix 2.0 as the OSGi runtime and can run on any other OSGi R4.1 compliant runtimes as well. This blog will use previously described instructions and show how to run GlassFish v3 on Eclipse Equinox and Knoplerfish. The complete details about different OSGi runtimes is described here, this TOTD provide detailed steps and overrides the instructions defined here (and here and here).

This blog is using a CI build from last week but you should try the instructions on a promoted build.

GlassFish with Felix - Felix 2.0.0 is bundled with GlassFish v3 and requires no additional configurations.

  1. Start GlassFish as:
    ~/tools/glassfish/v3/2269/glassfishv3/glassfish >./bin/asadmin start-domain --verbose
    

    and see the following messages in the log:
    Sep 11, 2009 4:41:16 PM com.sun.enterprise.glassfish.bootstrap.ASMain main
    INFO: Launching GlassFish on Felix platform
    
    Welcome to Felix
    ================
    
    . . .
    
    Sep 11, 2009 4:41:30 PM com.sun.enterprise.v3.server.AppServerStartup run
    INFO: GlassFish v3  startup time : Felix(9669ms) startup services(4453ms) total(14122ms)
    
    
  2. Optionally, connect to Felix runtime using Apache Felix Remote Shell (described here) as:

    ~/tools/glassfish/v3/2269/glassfishv3 >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:
    ============================
    
    ->
    


    and type "help" to see the list of commands available as:

    -> help
    bundlelevel
    cd
    find
    headers
    help
    inspect
    install
    log
    ps
    refresh
    resolve
    shutdown
    start
    startlevel
    stop
    uninstall
    update
    version
    
    Use 'help ' for more information.
    
  3. See the list of OSGi modules installed as:
    -> ps
    START LEVEL 1
       ID   State         Level  Name
    [   0] [Active     ] [    0] System Bundle (2.0.0)
    [   1] [Active     ] [    1] HK2 OSGi Main Bundle (0.3.91)
    [   2] [Installed  ] [    1] EclipseLink Core (2.0.0.v20090821-r4934)
    [   3] [Resolved   ] [    1] Hibernate validator library and Validation API (JSR 303) repackaged as OSGi and HK2 bundle (3.0.0.JBoss-400Beta3)
    [   4] [Installed  ] [    1] Connector (gluecode) for GlassFish Java EE Connector Architecture Runtime (3.0.0.SNAPSHOT)
    [   5] [Active     ] [    1] GlassFish Flashlight Framework (3.0.0.SNAPSHOT)
    
    . . .
    
    [ 201] [Resolved   ] [    1] glassfish-corba-asm (3.0.0.b024)
    [ 202] [Resolved   ] [    1] MIME streaming extension (1.4)
    [ 203] [Installed  ] [    1] Admin Console Connectors Plugin (3.0.0.SNAPSHOT)
    [ 204] [Installed  ] [    1] Apache Felix Shell TUI (1.4.0)
    [ 205] [Resolved   ] [    1] org.glassfish.core.glassfish-extra-jre-packages
    
  4. Use "headers" command to display the bundle header properties for any bundle. "help <command>" shows more information about each command displayed in the output of "help". Finally type "exit" to quit the shell.

GlassFish on Equinox

  1. Download Equinox latest release from http://www.eclipse.org/equinox/ (3.5 as of this writing).
  2. Unzip the contents and copy the Equinox jar file to "osgi/equinox" directory of GlassFish as shown below:
    ~/tools/glassfish/v3/2269/glassfishv3/glassfish >unzip ~/Downloads/equinox-SDK-3.5.zip -d ~/tools/equinox-3.5
    ~/tools/glassfish/v3/2269/glassfishv3/glassfish >cp ~/tools/equinox-3.5/plugins/org.eclipse.osgi_3.5.0.v20090520.jar ./osgi/equinox
    
    
  3. Start GlassFish as:
    ~/tools/glassfish/v3/2269/glassfishv3 >GlassFish_Platform=Equinox ./bin/asadmin start-domain --verbose
    

    and see the following messages in the log:
    Sep 11, 2009 5:11:13 PM com.sun.enterprise.glassfish.bootstrap.ASMain main
    INFO: Launching GlassFish on Equinox platform
    Listening on port 6667 ...
    
    . . .
    
    Sep 11, 2009 5:11:19 PM com.sun.enterprise.v3.server.AppServerStartup run
    INFO: GlassFish v3  startup time : Equinox(3649ms) startup services(1843ms) total(5492ms)
    


    Note, Equinox platform started on port 6667 for remote management.
  4. Optionally, connect to Equinox runtime as:

    ~/tools/glassfish/v3/2269/glassfishv3/glassfish >telnet localhost 6667
    Trying ::1...
    Connected to localhost.
    Escape character is '\^]'.
    
    osgi>
    
    

    Make sure to use the port number specified during the startup. Type "help" to see the list of commands available as:
    osgi> help
    ---Controlling the OSGi framework---
            launch - start the OSGi Framework
            shutdown - shutdown the OSGi Framework
            close - shutdown and exit
            exit - exit immediately (System.exit)
            init - uninstall all bundles
            setprop = - set the OSGi property
    ---Controlling Bundles---
    
    . . . 
    
    ---Controlling the Console---
            more - More prompt for console output
            disconnect - Disconnects from telnet session
    
  5. See the list of OSGi modules installed as:
    osgi> ss
    
    Framework is launched.
    
    id      State       Bundle
    0       ACTIVE      org.eclipse.osgi_3.5.0.v20090520
                        Fragments=62, 128, 205
    1       ACTIVE      com.sun.enterprise.osgi-main_0.3.91
    2       RESOLVED    org.eclipse.persistence.core_2.0.0.v20090821-r4934
                        Fragments=136
    
    . . . 
    
    203     RESOLVED    org.glassfish.admingui.console-jca-plugin_3.0.0.SNAPSHOT
    204     RESOLVED    org.apache.felix.shell.tui_1.4.0
    205     RESOLVED    org.glassfish.core.glassfish-extra-jre-packages_0.0.0
                        Master=0
    

    Typing "help" shows a comprehensive list of commands. Finally type "disconnect" to terminate the shell. Do not type "exit" as it terminates the Equinox shell and killing the GlassFish process as well.

GlassFish with Knoplerfish - As mentioned here, GlassFish v3 requires at least R4.1 APIs. All Knopflerfish releases prior to 3.0.0 are R4 compliant and so will not work with the GlassFish v3 latest builds. Knopflerfish 3.0.0 beta1 is the first build that is R4.2 compliant but it does not start on Mac OS X 10.5.8 as described in issue #2858798. So until then, you you can follow the instructions documented at  GlassFish v3 on OSGi KnopflerFish and Using KnopflerFish Desktop in GlassFish v3 to get them running on GlassFish v3 TP2 or Prelude.

Some additional details missing form the entries above

  1. Download Knoplerfish 2.3.3 and install.
  2. In "knopflerfish_osgi_2.3.3/knopflerfish.org/osgi", copy "props.xargs" to "gf.xargs" and add the lines mentioned here. Make sure to copy the Knopflerfish related files to the modules directory and change the location accordingly.
  3. Create "gfpackages.txt" by copying "felix/conf/config.properties" from the GlassFish directory. List each package specified in the "gf-packages" property on a single line. There should be no other character such as ";" or "," or "/" on a line, only the package name.
  4. Start GlassFish as:
    ~/tools/glassfish/v3/2269/glassfishv3/glassfish >KNOPFLERFISH_HOME=/Users/arungupta/tools/knopflerfish_osgi_2.3.3/knopflerfish.org/osgi GlassFish_Platform=Knopflerfish ./bin/asadmin start-domain --verbose
    
    
    and see the following messages in the log:
    Knopflerfish OSGi framework, version 4.1.10
    Copyright 2003-2009 Knopflerfish. All Rights Reserved.
    
    See http://www.knopflerfish.org for more information.
    Loading xargs url file:/Users/arungupta/tools/knopflerfish_osgi_2.3.3/knopflerfish.org/osgi/gf.xargs
    Removed existing fwdir /Users/arungupta/tools/knopflerfish_osgi_2.3.3/knopflerfish.org/osgi/fwdir
    Installed: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/tiger-types-osgi-0.2.1.jar (id#1)
    Installed: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/auto-depends-0.2.1.jar (id#2)
    Installed: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/config-0.2.1.jar (id#3)
    
    . . .
    
    Started: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/cm_all-2.0.1.jar (id#7)
    Started: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/console_all-2.0.1.jar (id#8)
    Started: file:/Users/arungupta/tools/glassfish/v3/glassfishv3-tp2/glassfish/modules/desktop_all-2.3.11.jar (id#11)
    


    and finally see the Knopflerfish console as:



The instructions will be updated after a more stable release of Knopflerfish is available.

A complete archive of all the tips is available here.

Technorati: totd glassfish v3 osgi apache felix eclipse equinox knopflerfish

Thursday Jun 19, 2008

TOTD #34: Using Felix Shell with GlassFish

TOTD #33 explains how to create a GlassFish v3 distribution that uses Apache Felix (default) as the  OSGi R4 Service Platform runtime. This blog explains how to use Felix Shell TUI with that bundle to issue commands to the OSGi framework and obtain information from it.

To enable Felix Shell with GlassFish v3, add the lines ...

 ${com.sun.aas.installRootURI}/felix/bundle/org.apache.felix.shell.jar \\
 ${com.sun.aas.installRootURI}/felix/bundle/org.apache.felix.shell.tui.jar

to "felix.auto.start.1" property in "felix/conf/config.properties" file of the expanded bundle. The updated property looks like:

felix.auto.start.1= \\
 ${com.sun.aas.installRootURI}/modules/tiger-types-osgi-0.3.2.jar \\
 ${com.sun.aas.installRootURI}/modules/auto-depends-0.3.2.jar \\
 ${com.sun.aas.installRootURI}/modules/config-0.3.2.jar \\
 ${com.sun.aas.installRootURI}/modules/hk2-core-0.3.2.jar \\
 ${com.sun.aas.installRootURI}/modules/osgi-adapter-0.3.2.jar \\
 ${com.sun.aas.installRootURI}/felix/bundle/org.apache.felix.shell.jar \\
 ${com.sun.aas.installRootURI}/felix/bundle/org.apache.felix.shell.tui.jar

with the changes highlighted in bold.

The shell works only if GlassFish is started using "java -jar modules/glassfish-10.0-SNAPSHOT.jar" command.

The shell is available when the following prompt is shown:

INFO: Glassfish v3 started in 1624 ms
Jun 16, 2008 7:10:37 PM  
INFO: ->
Jun 16, 2008 7:10:37 PM com.sun.enterprise.glassfish.bootstrap.ASMainFelix launchOSGiFW
INFO: Framework successfully started

You can type "help" in the shell to see the complete list of commands that are available:

help
Jun 16, 2008 7:11:12 PM  
INFO: bundlelevel <level> <id> ... | <id> - set or get bundle start level.
Jun 16, 2008 7:11:12 PM  
INFO: cd [<base-URL>]                     - change or display base URL.
Jun 16, 2008 7:11:12 PM  
INFO: headers [<id> ...]                  - display bundle header properties.
Jun 16, 2008 7:11:12 PM  
INFO: help                                - display impl commands.
Jun 16, 2008 7:11:12 PM  
INFO: install <URL> [<URL> ...]           - install bundle(s).
Jun 16, 2008 7:11:12 PM  
INFO: packages [<id> ...]                 - list exported packages.
Jun 16, 2008 7:11:12 PM  
INFO: ps [-l | -s | -u]                   - list installed bundles.
Jun 16, 2008 7:11:12 PM  
INFO: refresh [<id> ...]                  - refresh packages.
Jun 16, 2008 7:11:12 PM  
INFO: resolve [<id> ...]                  - attempt to resolve the specified bundles.
Jun 16, 2008 7:11:12 PM  
INFO: services [-u] [-a] [<id> ...]       - list registered or used services.
Jun 16, 2008 7:11:12 PM  
INFO: shutdown                            - shutdown framework.
Jun 16, 2008 7:11:12 PM  
INFO: start <id> [<id> <URL> ...]         - start bundle(s).
Jun 16, 2008 7:11:12 PM  
INFO: startlevel [<level>]                - get or set framework start level.
Jun 16, 2008 7:11:12 PM  
INFO: stop <id> [<id> ...]                - stop bundle(s).
Jun 16, 2008 7:11:12 PM  
INFO: uninstall <id> [<id> ...]           - uninstall bundle(s).
Jun 16, 2008 7:11:12 PM  
INFO: update <id> [<URL>]                 - update bundle.
Jun 16, 2008 7:11:12 PM  
INFO: version                             - display version of framework.
Jun 16, 2008 7:11:12 PM  
INFO: -> 

This shows the list of available commands along with a brief description. For example "ps" shows the list of installed bundles as shown below:

ps
Jun 16, 2008 7:13:57 PM  
INFO: START LEVEL 1
Jun 16, 2008 7:13:57 PM  
INFO:    ID   State         Level  Name
Jun 16, 2008 7:13:57 PM  
INFO: [   0] [Active     ] [    0] System Bundle (1.0.4)
Jun 16, 2008 7:13:57 PM  
INFO: [   1] [Active     ] [    1] org.jvnet.tiger-types repackaged as module (0.3.2)
. . .
INFO: [ 137] [Installed  ] [    1] WebTier Security Integration (10.0.0.SNAPSHOT)
Jun 16, 2008 7:13:57 PM 
INFO: [ 138] [Installed  ] [    1] Web module command line interface (10.0.0.SNAPSHOT)
Jun 16, 2008 7:13:57 PM 
INFO: [ 139] [Installed  ] [    1] Admin GUI Web Container Plugin (10.0.0.SNAPSHOT)
Jun 16, 2008 7:13:57 PM 
INFO: ->

More details about the commands and options are available @ Felix Usage Docs.

The commands are described in "felix/conf/config.properties" (around line 38).

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive is available here.

Technorati: totd glassfish v3 felix osgi

Monday Jun 16, 2008

TOTD #33: Building GlassFish v3 Workspace

Reviving after a 2-week hiatus ...

This TOTD (Tip Of The Day) provides complete instructions on how to checkout/build GlassFish v3 workspace.
  1. Check out the workspace as ...

    ~/workspaces/glassfish >svn checkout https://svn.dev.java.net/svn/glassfish-svn/trunk/v3
    Error validating server certificate for 'https://svn.dev.java.net:443':
     - The certificate is not issued by a trusted authority. Use the
       fingerprint to validate the certificate manually!
    Certificate information:
     - Hostname: \*.dev.java.net
     - Valid: from Thu, 09 Aug 2007 06:44:32 GMT until Sat, 09 Aug 2008 06:44:32 GMT
     - Issuer: Equifax Secure Inc., US
     - Fingerprint: e9:12:f6:a0:36:fe:7d:b0:07:dd:8b:d6:c3:b6:29:ff:ba:02:03:46
    (R)eject, accept (t)emporarily or accept (p)ermanently? t
    Authentication realm: <https://svn.dev.java.net:443> CollabNet Subversion Repository
    Password for 'arungupta':  <YOUR PASSWORD HERE>
    A    v3/deployment
    A    v3/deployment/javaee-core
    A    v3/deployment/javaee-core/src
    A    v3/deployment/javaee-core/src/main
    . . .
    A    v3/packager/packages/glassfishv3-ejb/build.properties
    A    v3/packager/packages/glassfishv3-ejb/build.xml
    A    v3/packager/packages/glassfishv3-ejb/glassfishv3-ejb.spec.tmpl
    A    v3/packager/packages/README
     U   v3
    Checked out revision 21054.

  2. The directory structure looks like:

    ~/workspaces/glassfish/v3 >ls -la
    total 24
    drwxr-xr-x  25 arungupta  arungupta    850 Jun 16 15:03 .
    drwxr-xr-x   3 arungupta  arungupta    102 Jun 16 14:58 ..
    drwxr-xr-x  10 arungupta  arungupta    340 Jun 16 15:03 .svn
    drwxr-xr-x  17 arungupta  arungupta    578 Jun 16 15:00 admin
    drwxr-xr-x  10 arungupta  arungupta    340 Jun 16 15:01 admingui
    drwxr-xr-x   6 arungupta  arungupta    204 Jun 16 15:01 build
    drwxr-xr-x  15 arungupta  arungupta    510 Jun 16 15:00 common
    drwxr-xr-x   9 arungupta  arungupta    306 Jun 16 15:03 connectors
    drwxr-xr-x   7 arungupta  arungupta    238 Jun 16 14:59 core
    drwxr-xr-x  10 arungupta  arungupta    340 Jun 16 14:58 deployment
    drwxr-xr-x  10 arungupta  arungupta    340 Jun 16 15:01 distributions
    drwxr-xr-x   9 arungupta  arungupta    306 Jun 16 15:01 ejb
    drwxr-xr-x   8 arungupta  arungupta    272 Jun 16 15:02 extras
    drwxr-xr-x   6 arungupta  arungupta    204 Jun 16 15:00 installer
    drwxr-xr-x  27 arungupta  arungupta    918 Jun 16 15:01 javaee-api
    drwxr-xr-x   5 arungupta  arungupta    170 Jun 16 15:02 osgi-platforms
    drwxr-xr-x  13 arungupta  arungupta    442 Jun 16 15:03 packager
    drwxr-xr-x   6 arungupta  arungupta    204 Jun 16 14:58 persistence
    -rw-r--r--   1 arungupta  arungupta  11866 Jun 16 15:03 pom.xml
    drwxr-xr-x   6 arungupta  arungupta    204 Jun 16 15:02 registration
    drwxr-xr-x   7 arungupta  arungupta    238 Jun 16 15:02 security
    drwxr-xr-x   8 arungupta  arungupta    272 Jun 16 15:01 tests
    drwxr-xr-x   8 arungupta  arungupta    272 Jun 16 14:58 transaction
    drwxr-xr-x  15 arungupta  arungupta    510 Jun 16 15:02 web
    drwxr-xr-x   5 arungupta  arungupta    170 Jun 16 14:58 webservices
  3. Set the Maven options as ...

    export MAVEN_OPTS=-Xmx512m

    And build the distribution as ...

    ~/workspaces/glassfish/v3 >mvn -U install
    [INFO] Scanning for projects...
    [INFO] Reactor build order:
    [INFO]   GlassFish Build Utilities
    [INFO]   GlassFish v3 Maven2 plugin
    [INFO]   Maven extension for building GlassFish
    [INFO]   GlassFish Parent Project
    . . .
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 5 minutes 56 seconds
    [INFO] Finished at: Mon Jun 16 15:33:46 PDT 2008
    [INFO] Final Memory: 57M/121M
    [INFO] ------------------------------------------------------------------------

    You need to use "mvn -U clean install" for a previously built workspace.
  4. Unzip the created distribution as:

    ~/testbed/glassfish/v3/snapshot >unzip ~/workspaces/glassfish/v3/distributions/glassfish/target/glassfish-10.0-SNAPSHOT.zip
    Archive:  /Users/arungupta/workspaces/glassfish/v3/distributions/glassfish/target/glassfish-10.0-SNAPSHOT.zip
       creating: glassfish/
       creating: glassfish/docs/
    . . .
      inflating: glassfish/lib/templates/keyfile 
      inflating: glassfish/lib/templates/logging.properties 
      inflating: glassfish/lib/templates/login.conf 
      inflating: glassfish/lib/templates/profile.properties 
      inflating: glassfish/lib/templates/server.policy

    The unzipped distribution directory looks like:

    ~/testbed/glassfish/v3/snapshot/glassfish >ls -la
    total 592
    drwxr-xr-x  14 arungupta  arungupta     476 Apr 23 16:37 .
    drwxr-xr-x   3 arungupta  arungupta     102 Jun 16 15:40 ..
    -rw-r--r--   1 arungupta  arungupta  250464 Jun 16 15:24 3RD-PARTY-LICENSE.txt
    -rw-r--r--   1 arungupta  arungupta    4603 Jun 16 15:24 COPYRIGHT
    -rw-r--r--   1 arungupta  arungupta   36116 Jun 16 15:24 LICENSE.txt
    -rw-r--r--   1 arungupta  arungupta     271 Jun 16 15:24 README
    drwxr-xr-x   8 arungupta  arungupta     272 Jun 16 15:33 bin
    drwxr-xr-x   6 arungupta  arungupta     204 Jun 16 15:33 config
    drwxr-xr-x   7 arungupta  arungupta     238 Jun 16 15:33 docs
    drwxr-xr-x   3 arungupta  arungupta     102 Jun 16 15:33 domains
    drwxr-xr-x   5 arungupta  arungupta     170 Jun 16 15:33 felix
    drwxr-xr-x   9 arungupta  arungupta     306 Jun 16 15:32 javadb
    drwxr-xr-x  11 arungupta  arungupta     374 Apr 23 16:37 lib
    drwxr-xr-x  74 arungupta  arungupta    2516 Jun 16 15:33 modules

    Start GlassFish as ...

    ~/testbed/glassfish/v3/snapshot/glassfish >bin/asadmin start-domain -v
    Jun 16, 2008 3:44:54 PM com.sun.enterprise.admin.launcher.GFLauncherLogger info
    INFO: JVM invocation command line:
    /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java
    -cp
    /Users/arungupta/testbed/glassfish/v3/snapshot/glassfish/modules/glassfish-10.0-SNAPSHOT.jar
    -XX:+UnlockDiagnosticVMOptions
    -XX:NewRatio=2
    . . .
    INFO: Started bundle org.glassfish.common.container-common [85]
    Jun 16, 2008 3:44:56 PM com.sun.enterprise.v3.admin.adapter.AdminConsoleAdapter setContextRoot
    INFO: Admin Console Adapter: context root: /admin
    Jun 16, 2008 3:44:56 PM com.sun.enterprise.v3.server.AppServerStartup run
    INFO: Glassfish v3 started in 1594 ms
    Jun 16, 2008 3:44:56 PM com.sun.enterprise.glassfish.bootstrap.ASMainFelix launchOSGiFW
    INFO: Framework successfully started

And you'll see the default page as shown below:



Hurrah!

This starts GlassFish v3 using Apache Felix as the OSGi platform. Alternatively, you can start GlassFish using the command "java -jar modules/glassfish-10.0-SNAPSHOT.jar". The complete instructions are available on GlassFish Wiki.

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive is available here.

Technorati: totd glassfish v3 felix osgi
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