Wednesday Feb 18, 2009

Proxy pattern for exposing jsr77 api and internal api using common implementation

GlassFish v3 is designed to be modular not only in architecture but in distribution as well. The distributions range from compact version 'Nucleus' to full blown version 'Enterprise' through 'Web', and 'PE' distributions.

We need to support jsr77 in Enterprise version so we'll need jsr77 interfaces to be available only in Enterprise version and not the lower versions like 'Web' and 'PE'. However we need to use jsr77 like monitoring data types for exposing monitoring data in 'Web' and 'PE' distributions. This poses a challenge of maintaining same data types but in two different packages. To avoid this maintenance hassle, we can use proxy pattern as described below.

Assume that we need to expose two interfaces with different package names but with same method signatures. Let us call them javax.management.j2ee.statistics.Statistic and org.glassfish.internal.api.Statistic. The corresponding implementations are javax.management.j2ee.statistics.JSR77StatisticImpl and org.glassfish.internal.api.IntStatisticImpl respectively. Recall that our idea of using proxy pattern is to avoid the maintenance hassle and for that we make JSR77StatisticImpl extend IntStatisticImpl and implement javax.management.j2ee.statistics.Statistic. This makes it reuse the common implementation.

Using dynamic proxy api, we can expose the required interface at runtime as shown below with working example.

  • Create glassfish internal Statistic interface under <stats_proxy_pattern>/internal-api
     
  • Create glassfish internal Statistic implementation IntStatisticImpl under <stats_proxy_pattern>/internal-api
     
  • Create jsr77 Statistic interface under <stats_proxy_pattern>/jsr77
     
  • Create jsr77 Statistic implementation JSR77StatisticImpl under <stats_proxy_pattern>/jsr77
     
  • Create StatsProxy under <stats_proxy_pattern>/monitor
     
  • First let us test the internal Statistic data type using the following code under <stats_proxy_pattern>.
    import org.glassfish.internal.api.\*;
    import com.sun.enterprise.monitor.\*;
    
    /\*\*
     \* Verify the stat types at runtime
     \* @author Sreenivas Munnangi
     \*/
    
    public class TestStatInterface {
        public static void main (String args[]) {
            System.out.println("TestStatInterface");
            try {
                //interanl Statistic
                Statistic stat = (Statistic) StatsProxy.newInstance(new IntStatisticImpl());
                System.out.println("TestStatInterface: before calling method getName on proxy ...");
                System.out.println("TestStatInterface: stat.getName() = " + stat.getName());
                System.out.println("TestStatInterface: after calling method getName on proxy ...");
                System.out.println("TestStatInterface: before calling method getStartTime on proxy ...");
                System.out.println("TestStatInterface: stat.getStartTime() = " + stat.getStartTime());
                System.out.println("TestStatInterface: after calling method getStartTime on proxy ...");
            } catch (Exception e) {
                System.out.println("Caught exception ...");
                e.printStackTrace();
            }
        }
    }
    
    When we build and run the above code, we see the following output. 
    I have used build.xml from the attached example, 
    link is provided at the end of this blog.
    
    run:
         [java] TestStatInterface
         [java] TestStatInterface: before calling method getName on proxy ...
         [java] statsproxy before method getName
         [java] result = called getName() ...
         [java] statsproxy after method getName
    
         [java] TestStatInterface: stat.getName() = called getName() ...
         [java] TestStatInterface: after calling method getName on proxy ...
         [java] TestStatInterface: before calling method getStartTime on proxy ...
         [java] statsproxy before method getStartTime
         [java] result = 1234985924526
         [java] statsproxy after method getStartTime
         [java] TestStatInterface: stat.getStartTime() = 1234985924526
         [java] TestStatInterface: after calling method getStartTime on proxy ...
    
    BUILD SUCCESSFUL
    
  • Now test for jsr77 Statistic type. Notice the change in imports.
    import javax.management.j2ee.statistics.\*;
    import com.sun.enterprise.monitor.\*;
    
    /\*\*
     \* Verify the stat types at runtime
     \* @author Sreenivas Munnangi
     \*/
    
    public class TestStatInterface {
        public static void main (String args[]) {
            System.out.println("TestStatInterface");
            try {
                //jsr77 Statistic
                Statistic stat = (Statistic) StatsProxy.newInstance(new JSR77StatisticImpl());
                System.out.println("TestStatInterface: before calling method getName on proxy ...");
                System.out.println("TestStatInterface: stat.getName() = " + stat.getName());
                System.out.println("TestStatInterface: after calling method getName on proxy ...");
                System.out.println("TestStatInterface: before calling method getStartTime on proxy ...");
                System.out.println("TestStatInterface: stat.getStartTime() = " + stat.getStartTime());
                System.out.println("TestStatInterface: after calling method getStartTime on proxy ...");
            } catch (Exception e) {
                System.out.println("Caught exception ...");
                e.printStackTrace();
            }
        }
    }
    
    Following is the output which will be similar to what 
    we have seen earlier since they both use common implementation.
    
    run:
         [java] TestStatInterface
         [java] TestStatInterface: before calling method getName on proxy ...
         [java] statsproxy before method getName
         [java] result = called getName() ...
         [java] statsproxy after method getName
         [java] TestStatInterface: stat.getName() = called getName() ...
         [java] TestStatInterface: after calling method getName on proxy ...
         [java] TestStatInterface: before calling method getStartTime on proxy ...
         [java] statsproxy before method getStartTime
         [java] result = 1234986155422
         [java] statsproxy after method getStartTime
         [java] TestStatInterface: stat.getStartTime() = 1234986155422
         [java] TestStatInterface: after calling method getStartTime on proxy ...
    
    BUILD SUCCESSFUL
    
Download the complete example.

Wednesday Dec 05, 2007

Runtime Management of Sailfin Applications

The JSR77 spec. provides server vendors with a standard model for managing the Java EE Platform.

GlassFish V2/Sun Java System Application Server 9.x provides the default JSR77 implementation. Based on this, after deploying an application it is possible to start/stop the application using its runtime management mBean. However if the application is deployed in disabled state then no mBean is created for its runtime management.

A version of application server is being developed for Sailfin based on the GlassFish V2 source. Sailfin applications are deployed using extended archive version of 'SAR' and the implementation requires that even if the application is disabled, its runtime management mBean need to be available to perform start/stop operations. Accordingly the code has been added to provide this feature. Now it is possible to manage Sailfin application like a standard Java EE application, more importantly, start/stop the applications even if they are disabled. The start/stop operations can be performed using any standard jmx console, for ex. jconsole which comes with jdk 6.0 or any JMX compatible Console. One can use the connection parameters from the Application Server log. The jmx connector URL is printed in the server.log when the Application Server is started.

About

msreddy

Search

Categories
Archives
« July 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
31
  
       
Today