Discussions

J2EE patterns: J2EE Singleton

  1. J2EE Singleton (37 messages)

    Classical Singleton Pattern allows to have only one instance of class per JVM. In J2EE environment usually there are more then one JVM, so if we have to have one instance of class among many JVMs, classical approach doesn’t work.
    Solution is to use RMI and JNDI: you create outside RMI Object and register it in J2EE application server's JNDI tree. Then, inside Servlet or EJB container you have to look up previously registered RMI object (actually you’ll find RMI Stub) and call some method any it.

    Steps to implement J2EE Singleton Pattern for different application servers are described here.

    1. Create Remote service interface and Remote service implementation class.

    Create Remote service interface that extends java.rmi.Remote and implementation class that extends javax.rmi.PortableRemoteObject.

    public interface RemoteService extends java.rmi.Remote {
       …
    }


    public class RemoteServiceImpl extends javax.rmi.PortableRemoteObject implements RemoteService {
       …
    }


    Make sure that all method declared in RemoteService throws java.rmi.RemoteException.

    2. Create RMI Server that will host RemoteService.

    Find one of possible implementations of RMI Server below:

    public class RMIServer {

    // Properties to obtain application server’s initial context. Possible values describes below after Java source.

    public static final INITIAL_CONTEXT_FACTORY = “factory class”//;
    public static final PROVIDER_URL = “JNDI URL”//;

    public static void main(String[] args) {
            if (System.getSecurityManager() == null) {
                System.setSecurityManager(new RMISecurityManager());
            }
           try {
                // creates object
                RemoteService remoteService = new RemoteServiceImpl();
                Properties props = new Properties();
                
               // gets initial context
                props.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
                props.put(Context.PROVIDER_URL, PROVIDER_URL);

                // gets initial context
                InitialContext context = new InitialContext(props);
                
                 // bind remote service to naming context
                context.rebind("RemoteServiceJNDI", someRemoteService);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    Possible values of INITIAL_CONTEXT_FACTORY and PROVIDER_URL properties for Weblogic 7.0, Sun One 7.0 and JRun 4.0 application servers:
    Weblogic 7.0: “weblogic.jndi.WLInitialContextFactory”, “t3://host:7001”
    Sun One 7.0: “com.sun.jndi.cosnaming.CNCtxFactory”, “iiop://host:3700”
    JRun 4.0: “jrun.naming.JRunContextFactory”, “host:2909”

    Port numbers indicated here are just possible default values.

    3. Compile Remote service classes and generate Stub and Skeleton.

    Using rmic create Skeleton and CORBA IIOP compatible Stub:

    rmic RemoteServiceImpl
    rmic -iiop RemoteService

    4. Create the client application and deploy it to J2EE application server.

    Package RemoteService and _RemoteService_Stub generated by rmic into your J2EE component (war or ejb-jar). In client code InitailContext should be obtain in the same way as in RMI Server:

          Properies props = new Properties();

           // should be the same as in RMI server class.
           props.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
           props.put(Context.PROVIDER_URL, PROVIDER_URL)
           InitialContext context = new InitialContext(props);
           Object obj = context.lookup(“RemoteServiceJNDI”);
           RemoteService service = (RemoteService)PortableRemoteObject.narrow(obj,RemoteService.class);

     
    Note, that Weblogic generates it’s own stub just after binding. So there is no need to package stub compiled by rmic if you are using Weblogic.

    Also note, initial context being obtained as

    Context ctx = new InitialContext();

    can not be used for lookup of remote object registered from outside.

    5. Start up System
    Start up the Application Server to make server’s JNDI context available.
    Start up the RMI Server. RMI Server will register RemoteService in application server’s JNDI tree and stay available for remote calls.
    Now any part of application could legally lookup and makes a remote call to RemoteServiceImpl.

    Threaded Messages (37)

  2. J2EE Singleton[ Go to top ]

    it sounds good ! but it does not work! if the server that the instance was created in is down,the program could lookup the instance in the JNDI tree.
    in one word, it does not support failover.
  3. J2EE Singleton[ Go to top ]

    it sounds good ! but it does not work! if the server that the instance was created in is down,the program [b]could not[/b] lookup the instance in the JNDI tree.
    in one word, it does not support failover.
  4. J2EE Singleton[ Go to top ]

    You are right. But I don't see another solution. If you need failover - make you RMI Server code smart enougth to support it :)
  5. J2EE Singleton[ Go to top ]

    BTW, the better solution is to use another application server instance (as RMI Server) but with only One JVM instance inside :)
  6. J2EE Singleton[ Go to top ]

    Hi Guys,

    I did experience the same problem when i was using some singletons patterns in my weblogic clustered environment. I used MDB to publish the changes across the cluster to all machines.

    ie. The MDB's will be deployed in all the members of the cluster subscribed for the Topic listening for messages. Each Servers will refresh their singleton reference accordingly.

    Even in the non clustered app server environment we can make the solution easy by using JMS. A specific member class of all JVM will subscribe for the changes in the topic and refresh their data in memory. This is more scalable approach dont you think so??

    Suresh
  7. J2EE Singleton[ Go to top ]

    Yes, your approach works fine if we are tolking about Single Data Instance (you suggest to replicate data using JMS). But if we need Single Resource Instance that can't be replicated (socket, for example, or file handler) your approach will not work.
  8. Hi,

     I'm working with Bea WLS7. I need a (Singleton)-Pool for Backend-Credentials (many many users and only a few backend-credentials). Our application runs in a cluster with 4-16 nodes.
     My first approach to the problem was the RMI solution until I found out that WLS' failover for RMI instances only works for stateless ones by broadcasting the instance to all nodes' jndi-trees once. In other words, no synchronizing and no failover for the pool's state.
     Now I've made a StatefullSessionBean from my former RMI-Implementation. At startup of the server (after deployment) I create one instance of this bean. I take the handle from it an bind it to the jndi. WLS then propagates this handle to all nodes. Any "credentials-consumer" on every node can now access this handle and so the same bean instance. WLS can take care of the clustering and failover of SFSBs, so most of my problems are solved...
     Except for one thing: Concurrent calls to SFBSs are not allowed in J2EE. The default behaviour of a bean that is called more than once at the same time is to throw a RemoteException. Fortunatly WLS has a setting (don't know exactly about other containers) that allows concurrent calls on SFBSs. WLS even synchronizes the calls.


    Regards,
     Timo
  9. So, why do you need a singleton?[ Go to top ]

    I'm working with Bea WLS7. I need a (Singleton)-Pool for Backend-Credentials (many many users and only a few backend-credentials). Our application runs in a cluster with 4-16 nodes.


    I don't see why you need a singleton here.

    Usage of statefull EJBs is very very questionable in your case, as in almost every other case.
  10. So, why do you need a singleton?[ Go to top ]

    i've thought some time, if i should ignore it, but...
    thanx for your short feedback... as far as i can see from your previous posts in this thread i couldn't help getting the feeling that you must have a quite trivial solution for our problems, that you, for some reason only you know, don't want to tell us here ;)

    > Usage of statefull EJBs is very very questionable in your case, as in almost every other case.
    the fact, that there is exactly one SFSB in the whole cluster, makes it unlikely that there will be a negative impact on our application's runtime behaviour. btw categorical statements like these are the ones i like the most. found it in a book?
  11. the fact, that there is exactly one SFSB in the whole cluster, makes it unlikely that there will be a negative impact on our application's runtime behaviour. btw categorical statements like these are the ones i like the most. found it in a book?


    I didn't mean to offend you. If it looked like I did then I'm sorry.

    I just don't understand why someone needs a singleton for user credentials. What's so special about your system's credentials?

    Re: statfull beans - I donm't need a book. I've done some J2EE (4 years), I used statefull beans only once (unnecessarily, btw). So, it's hard for me to come up with a problem, which requires statefull beans.
  12. no problem :))

    ok, i got several legacy-backends that have to be integrated into the application. all these backends use authentication by username and password and each of them got a set (~100..500) of technical users they accept. technical users in this context means, that there's no permanent relationship between a real user (we expect about 2000 concurrent sessions with up to 100 transactions per second). so what has to be done is to assign a technical user to a real user when he needs to contact one or more backends and afterwards take it back after usage, so it can be handed out to another user. a couple of the backends are not able to handle concurrent requests from one authenticated user. that means, if one thread on one cluster node authenticates with one user and at the same time another thread (maybe on another node) uses the same credentials, the whole situation will end up in a desaster (worst case: the backend goes down because of an internal error, very nasty but true). besides this it's one of the customer's requirement that for one backend transaction there must be a 1:1 relation between a real and a technical user, so it is possible to track from presentation-layer into the backends what has been done in one transaction.
    btw the credentials that are pooled come from different resources like ldap, dbs and even properties-files and it is likely that technical users must be addable at runtime.

    the usual solution in a "native" java enviroment (in one jvm) would have been to use a pooling mechanism based on a singleton. an equivalent solution in our application would be a cluster-wide singleton with high availability (failover).

    i hope, i managed to explain, what's our problem, i'm no native english speaker ;)

    well, finally some "non-singleton" solutions we thought of:

    1) collect credentials from the resources, partion them and share them equally between the nodes. this would be a very easy way to implement, but has some drawbacks. one node crashes and (if there were four) one quarter of our credentials are temporily unavailable, while the cluster has to manage the same load. the number of credentials that one node ones may not be sufficient at all times. adding credentials at runtime becomes nearly impossible.

    2) use a database as "singleton"-instance in the application. this is a valid solution in j2ee. the database can make synchronization for me and act like a pool, if i want it to. the problem here is, that we must keep the data consistent with the credential-resources. that would take some extra time to implement the functions for this. knowing the infrastructure of the customer, this also could become a real performance problem.

    ok, that's it. if you can think of a better solution i'd be very thankful. i'm not really happy with our solution, as i really don't like messing with the j2ee spec. but, it works fine for now... :))
  13. I promise[ Go to top ]

    ok, i got several legacy-backends that have to be integrated into the application. all these backends use authentication by username and password and each of them got a set (~100..500) of technical users they accept. technical users in this context means, that there's no permanent relationship between a real user (we expect about 2000 concurrent sessions with up to 100 transactions per second).


    Now I see you problem. I think that what you call "credential" is not usually called "credential" in this context. That was confusing me.

    If I understand you correctly, then your "technical user" is an analog of the connection (e.g. in JDBC). You have a finite number of "technical users", each with its own unique parameters (uname, password,...), and these guys are not thread-safe. I hate to say, singletons :)

    I'll think of how to implement this stuff. Entity EJB could be one sub-optimal solution, it's guaranteed to be one istance.
  14. I promise[ Go to top ]

    I'll think of how to implement this stuff. Entity EJB could be one sub-optimal solution, it's guaranteed to be one istance.


    I'm sorry, but you always mix up Data Singletone and Resource (or runtime code) singletone in your posts.
    Surely, Entity EJB is guaranteed to be one instance of some Data. But how will you manage such entity as connection? Where will you store it? In any case you will need some code what will be single instanciated and your Entity EJB will be only wrapper for this single instance.
    So, as you can see, we have the same problem as in the very beginning.
    I want to repeat my statement ones more time:
    There are different types of Entities you want to have single instanciated - Serializable and Not Serializable. In J2EE sand-box you can manage only Serializable Entities as singletones.
  15. Hi,

    I am wondering since so many people think singelton are bad design. How would you design sharing expensive to create resource. Like say JMSSender which shares a JMS Connection yet creates a session for each invoker efficent rather than creating multiple connections and other expensive to create objects. Another shared resource logger better to have a singleton than pass it from class to class? Another program properties so each class can read its properties better than passing the properties object around?I have a registery which is a groups of these shared resources efficently. I would like to here peoples alternatives people to have to singletons for sharing these resources.
  16. Do you really need it?[ Go to top ]

    Singleton is always a good candidate to be a bottleneck so you should think twice before you commit to this pattern. In most cases you can and should use Entity beans for 'singleton data' and stateless session beans for shared resources like socket connection.
    When I was doing my first EJB project I wanted to implement three EJBs as singletons. Later I found well-working non-singleton solutions for all of them.
  17. Do you really need it?[ Go to top ]

    Hello,
    >In most cases you can and should use Entity beans for 'singleton data'
    How did you do this?
    Br
    VR
  18. Do you really need it?[ Go to top ]

    and stateless session beans for shared resources like socket connection.

    It's impossible in clustered environment.
  19. Use Entity Beans for Singletons[ Go to top ]

    It should be possible to mimic the behavior of a singleton by using an EntityBean. I think of a singleton as an entity with only *one* valid primary key and design accordingly.
  20. agree[ Go to top ]

    Agreed. If I needed singletons (and I don't), then I'd first think of Entity beans.
  21. J2EE Singleton and Failover in Bea WLS[ Go to top ]

    Hi Timo Weber,

    I am trying to implement a similar solution.
    Where in jndi do I store the ejb handle? So that it is accessible from other ejbs.
    As far as i know an ejb can access only 'java:comp/env/' in jndi.
    Also an ejb is not allowed to make changes to its environment.

    Thanks in advance,

    Ajay Amrite.
  22. Hi Timo Weber,

    >
    > I am trying to implement a similar solution.
    > Where in jndi do I store the ejb handle? So that it is accessible from other ejbs.
    > As far as i know an ejb can access only 'java:comp/env/' in jndi.
    > Also an ejb is not allowed to make changes to its environment.
    >
    > Thanks in advance,
    >
    > Ajay Amrite.

    Hi Ajay,

    I think you are right in terms of JNDI usage by EJBS, but I am also
    sure that to bind the instance handle you could use somethig that is guaranteed
    to preceed your application usage.

    An example of such a beast in WebLogic is Startup/Shutdown classes.

    What I am not sure is if startup/shutdown classes started after deployment of EJB Modules or bvefore. If after, you could use startup class that does exactly that (binds EJB to a JNDI namespace).

    You could then access the instance from youtr other beans, ...

    This is just a shot in the dark, but I would investigate this approach if
    I had to do what Tim has done.

    Later, Mikhail
  23. It looks that the solution Timo described is suitable to our situation as well. Dit it work, finally? Is there any final conclusion to this thread after your implementation, Timo?
  24. J2EE Singleton[ Go to top ]

    We can persist the Singleton Class into the database in bytes and use it as a global
  25. J2EE Singleton[ Go to top ]

    Hi, I did something like this before. My failover solution was to include a dummy method at the RMI Server class. Then I used a second simple singleton as the proxy for the remote one. In case of exception I try to use the dummy method(a very trivial one) and in the case the exception persists I assume the reference is invalid and should be recreatead and rebinded at the JNDI. Of course, the data get lost anyway but you can have some kind of universal singleton.
    I have it working in a uniqueID generator for EJB factory based on the Ed Roman's pattern(Sequence Blocks).

    Lester
  26. J2EE Singleton[ Go to top ]

    I think if you are in an environment where Singleton use is prohibitive -- which is practically just about all production J2EE scenarios -- you might consider exposing the singleton as a service.

    Your current design, I don't think this qualifies as a pattern in design more so in implementation -- no disrespect intended, would achieve that in effect anyway by providing a lookup thru JNDI.

    Exposing this singleton as a service in no way prohibits it's restriction to a single VM and/or a feasible distributed/local approach if the reqs change.

    All constructive criticism .. your approach is quite valuable. I am suggesting an alternate modus operandi ...
  27. J2EE Singleton[ Go to top ]

    The best solution would be in the case you are using J2EE is JNDI. You can bind the static instance to a JNDI Name and refer to the same JNDI name across JVM's.

    Thanks,
    Ravi.
  28. Who needs Singletons?[ Go to top ]

    I think that if you need a Singleton, then something's wrong with your design.

    Can someone explain me when is Singleton required in J2EE application?
  29. Agreed![ Go to top ]

    Singletons inherently don't support scaling an clustering. So if you need to develop a clustered solution, don't use singletons as they are violating the very rule of a reliable/clusterable/failover architecture!
  30. Rod Johnson's J2EE book[ Go to top ]

    Rod Johnson discusses Singletons and J2EE in his book "J2EE Design
    and Development".

    It is definitely worth reading.
  31. Rod Johnson's J2EE book[ Go to top ]

    Rod Johnson discusses Singletons and J2EE in his book "J2EE Design
    and Development".
    It is definitely worth reading.
    It’s indeed worth reading, but you rather get 101 reason to do not use singleton in J2EE environment and 99 ways to avoid it that 1 solution for singleton in cluster. There are proprietary vendor solution - I believe WebSphere, jBoss offering fault tolerance solution for singleton services, WebSphere have SharedMap as solution for data .. you also can use (or abuse) JNDI for some cases. Generally I’d love to see JSR for it for now we doomed to custom implementations JMS, JNDI or Entity EJB based.
  32. True Singletons[ Go to top ]

    We usually use the singletons to hold configuration data. It's pretty easy to gurantee a single instnace in one application, such as when one EAR file is deployed. This is a packaging issue. Different app server will have different class loading hierarchy.

    Problem is when there are multiple applicaiton deployed either in one JVM or Multiple JVMs such as in a clustering enviroment, How do we keep multiple instances of the singleton synchronized?

    Our soluton is to use the multicast. when the singleton in one node changes state, it needs to send multicast message out to all the nodes. The nodes receives it and update the changed fields accordingly. JavaGroups is a good implementation of multicasting. Even better, the Jboss provided the TreeCache that allows you not evening knowing about multicasting.

    About the author's suggested solution: "Solution is to use RMI and JNDI", the performance will be a big problem.
  33. h[ Go to top ]

    h
  34. This is no answer if there is a genuine need for a singleton such as the one described above by Timo. But in reply to "what alternatives to singletons are there for sharing resources?":

    However, if all you want is pooling of some expensive resource, you can hold create or obtain a reference to the resource in the ejbCreate (for stateless SB especially) and keep the reference as an instance field of the ejb. Since the SB is pooled by the container according to the load, you get automatic pooling of the resource according to load. It is also nice and easy to code...
  35. I came across a situation once where in I had to design a scheduler (running on a App Server) that should read a bunch of DB tables and invoke an EJB. Leaving the details asidem, the design requirement (limitation??) was to have only one instance of the scheduler program running at any point of time. I think this pattern fitted the best in such a scenario. But not a true fan of this pattern anyway.
  36. JBoss Clustered Singleton[ Go to top ]

    JBoss 3.x offers support for a "Clustered Singleton"

    This article explains it all:

    http://www.onjava.com/pub/a/onjava/2003/08/20/jboss_clustering.html
  37. MDB usage[ Go to top ]

    I am highly skeptical of MDB solution to act as an singleton or maybe i did not understand the solution :-|
    The mdb solution sounds more like read mostly pattern where create/update/delete operations are propogated to all clusters to keep their copies fresh "after" the operation has taken place...
    This solution does not prevent where an operation should be allowed only once. For example, 2 threads enter in 2 entity instance at same time in 2 different machines in cluster to create a certain record. Requirements are one of them should fail as that record should be created only once. Since both threads entered the entity beans in different machines in the cluster at the same time, both will successfully create the same record which defeats the purpose...
  38. binding handle at server startup[ Go to top ]

    The solution which suggested creating a bean at startup and bind it to jndi, works only because the bean is created at startup :(. Unfortunately, this solution would not work if the "luxury" for creating the bean at startup time is not avilable..... Any suggestions for singletons which would work anytime ....