I'm looking for the best solution to a 'problem' that I know many people have come up against in the J2EE world...
Here's a quick example of the problem:
You have a class (not an EJB), say, "MaintClass" that creates (and holds a reference to) a Thread that repeated does some work (for example scans a db for a certain entry). MaintClass also has some methods on it to allow other objects to interigate it and find out info about what it's up to and/or what results or info it might have available. You want all classes (servlets/jsps & EJBs) within your J2EE environment to be able to access a particular instance of this class (it is NOT a singleton) and call methods on it.
The question is, what is the best way to get this class instantiated one or more times as the App Server fires up, and where/how do you keep the references to the instances so that they don't get garbage collected, and so that they can be 'found' by all all other classes? Also, if you have a 'cluster' of app servers running, you don't want to have the instances propigate accross the cluster, because there are threads held by the instances.
Thanks for any suggestions!
Create the objects and 'attach' them to your JNDI tree. Name each instance whatever you want....You can grab an instance whenever you want.
Does this really work? -- The object has to be 'serializable' - right? What happens with the Thread?
JNDI is definitely the best way to locate the objects. JNDI can store objects of class java.rmi.Remote. You could make each one of the objects an RMI object.
If you don't need them to run outside the server then you could use a factory pattern. Have a singleton object that creates the objects you're talking about and also performs resource management on them. It's like an EJB home but without the RMI.
So if I make my class 'Serializable' so that it can go into the JNDI tree of the app server, then I need to make the member that holds the Thread 'transient'.
When this is bound to the tree, and later lookup()'d , is the reference to the thread still good? (obviously I'm talking about when the app server has stayed running... if the app server restarted, then the thread obviously dead for sure)
Well, I can't say that I have lots of J2EE experience, but here's how I'd solve this using "classical" Java programming techniques:
o Use a MaintClassFactory, which is the only one that will be entered in RMI registry. There must be only one instance of MaintClassFactory.
o MaintClassFactory provides factory methods to create new instances of MaintClass. There should be absolutely no other way to instantiate MaintClass.
o MaintClassFactory holds a pool of all instances of MaintClass ever created. This might be a Collection of some sort.
o When creating a new instance of MaintClass, the factory method automatically enters this instance to its pool.
o Provide some accessors to this pool: Collection getAll(),
MaintClass getByKey(Key id), ...
o Please not that it might be necessary to inform MaintClassFactory if an instance of MaintClass has fallen out of use - so that it can reuse this instance or purge it from its local pool, freeing the resources.
Might this work for you?