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

Post a Comment:
  • HTML Syntax: NOT allowed
About

msreddy

Search

Categories
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