where can i encaptulate the global parameter?

Discussions

EJB design: where can i encaptulate the global parameter?

  1. where can i encaptulate the global parameter? (9 messages)

    hello
    consider my scenario,when i develop project in web tier,i can write a singleton to encaptualte the global parameter,such as jndi look up......,and write a servlet (config it as "load on startup")to instantiate the singleton as soon as the web container is started up,then other classes in the web tier can get the global parameter by using the static get method of the singleton,i think maybe it is so-called "service locator pattern",it works well.

    but now,i want to extend such mechanism to ejb tier,that is i also write a singleton to encaptulate the global patameter within the ejb tier,this singleton can be started up automatically by something(in web tier,i can use serlvet to take the responsibility,but i can't find such a thing in the ejb tier) as soon as the ejb container is started up,it is only my guess,i don't know if it is realizable,and the following question confuse me:
    1 if the ejb container support singleton object,that is if the session bean can visit the singleton in ejb container just as java bean visit the singleton in servlet container?

    2 if my suggestion is available,who can take the role to start up the singleton in ejb container just as the servlet in web container takes?
    thanks for any instruction!


  2. where can i encaptulate the global parameter?[ Go to top ]

    Option 1: You can take advantage of proprietary features of your app server like startup classes (if available).

    Option 2: The more portable option would be to add a method to your SB that initializes the singleton and call it from your "load on startup" servlet (taking into account that EJB containers take longer to start up than servlet engines). This would require you to shutdown and startup your servlet engine and EJB containers together. Not a big problem, as, that's what happens with most app servers anyway.
  3. where can i encaptulate the global parameter?[ Go to top ]

    thank you
    according instruction(option 2),do you mean that there is not the same "load on startup" mechanism in the ejb container just as that in the web container?
  4. where can i encaptulate the global parameter?[ Go to top ]

    Correct me if I'm wrong here, but you said that you created a singleton class. I do not understand why it would be a problem for you to find a place where this class will be instantiated.

    If you write the following singleton class:

       public class MySingleton {
       
          private static MySingleton me;
          private Properties globalParams;
          
          static {
             me = new MySingleTon();
          }
          
          private MySingleton(){
             globalParams = System.getProperties();
             
          }
          
          public static MySingleton getInstance(){
             return me;
          }
          
          public String getParameterValue(String key){
             return globalParams.getProperty(key);
          }
          
          ...
          
       }
       
    the class instance itself will be created as soon as the VM loads the class.

    Your main concern here will be: since your web-app and ejb will be loaded by two different class loaders (unless you use an ear), there will two instances created for in your server. One for the web-app and one for the ejb. This actually is not a problem if your singleton class will contain global parameters.

    As you can see from the above example, this class will load any system properties that you passed when you run your server. Example

       %JAVA_HOME%\bin\java -Dparam1=ParameterOne -Dparam2=ParameterTwo weblogic.Server

    So you can call:

       MySingleton.getInstance().getParameterValue("param1");
       
    Regards,

    Marco
    mingco at ccsc dot com
          
  5. This is eager instantiation. When you load your data in your singleton from a trivial resource (a file, a resource bundle, properties), this is ok.

    On the other hand, if you have a singleton that accesses other applications or datasources and the like to load its data, the answer to "when to instantiate the singleton?" becomes "when we safely know all supporting parts have themselves been initialized" instead of "class load time".

    So we leave the instantiation to the point where it is required (lazy instantiation):
       private static MySingleton me = null;
       public static synchronized MySingleton getInstance() {
          if (me == null) {
              me = new MySingleton();
          }

          return me;
       }

    This version has problems and needs some tweaking: threads now have to wait for each other if they try to get the reference to the instance. This can't be good. What we normally do is separate the creation code
      public static synchronized void instantiateSingleton() {
         if (me == null)
            me = new MySingleton();
      }
    and getInstance():
      public static MySingleton getInstance() {
         return me;
      }

    Note there's no need for synchronization on getInstance now, just like your eager singleton. And the instatiation is done when needed. The down-side is someone has to do it before anybody calls getInstance()
  6. I also would have done this your way (lazy instantiation) but since I know this class would load information that's already there then eager instantiation was my choice.
  7. Oh by the way, where do you call your instantiateSingleton() method? Do you have to call this method first before calling getInstance() as in:

       public void methodA(){
          MySingleton.instantiateSingleton();
          MySingleton ms = MySingleton.getInstance();
       }

    If you do this this way then I don't see your point why you need to have the instantiateSingleton() method. All methods that need to get MySingleton need to call instantiateSingleton() to make sure that there's an instance right? Unless, maybe, if you're going to call the getInstance() method several times in a method, in this case, it might be useful.
  8. Marco wrote:
    "Oh by the way, where do you call your instantiateSingleton() method?"

    You have to do it during "startup" (hence the stated problem: how to do it in an EJB container?).

    If you don't, everybody using getInstance() should run instantiateSingleton() prior to that call just to be sure there *is* an instance (as is in your code), which surely beats the purpose of moving the instantiation code into a synchronized instantiateSingleton() method and leaving getInstance() un-synchronized.

    So, in summary, you have to call instantiateSingleton() only once, but, prior to any getInstance() calls from anybody. This is best done during startup.
  9. I hope you realize that by allowing the singleton class to be instantiated from a startup class, it has to be in the server's classpath and not (just) in your EJB jar and war files. Not that there's anything wrong with this.
  10. Very nice point Marco: that last observation (apart from obvious portability issues) is a very good point in favor of going with option 2.