views:

1239

answers:

10

I am currently working on some older java code that was developed without App Servers in mind. It is basically a bunch of "black box code" with an input interface, and an output interface. Everything in the "black box" classes are static Data Structures that contain state, which are put through algorithms at timed intervals (every 10 seconds). The black box is started from a main method.

To keep this easy for myself, I am thinking of making the "black box" a Singleton. Basically, anyone who wants to access the logic inside of the black box will get the same instance. This will allow me to use Message Driven beans as input to the black box, and a JMS Publisher of some sort as the output of the black box.

How bad of an idea is this? Any tips?

One of the main concerns I have though, is there may be Threads in the "black box" code that I am unaware of.

Is there such thing as "application scoped objects" in EJB?

Note: I am using Glassfish

+2  A: 

Far from being a bad idea, it actually sounds to me like potentially quite a good idea.

Just from a program design point of view: if your black box is conceptually an "object" with properties and methods that work on them, then make it into an object, even if there'll only ever be one of them instantiated.

Neil Coffey
+3  A: 

I would say that creating a singleton is actually the only viable idea. Assuming that code inside this "black box" is known to use static fields, it is absolutely unsafe to create two instances of this facade. Results are unpredictable otherwise.

Antonio
+2  A: 

It should work, but there are some issues you may have to deal with.

Threading, as you have mentioned. An MDB is run in the EJB container where you cannot create your own threads, so you have a potential problem there. If you have access to the actual code (which it sounds like you do), you may want to do some refactoring to either eliminate the threads or use an "approved" threading method. The CommonJ TimerManager will probably work in your stated case since it is performing some task on an interval. There are implementations available for most app servers (WAS and Weblogic have it included).

Classloading - This is dependent on you configuration. If the singleton is created and manipulated from MDB's within the same EAR, you will be fine. Separate EAR's will mean different classloaders and multiple instance of you Singleton. Can't comment on whether this would be a problem in your case or not without more information.

Robin
+11  A: 

If you use a simple singelton, you will be facing problems once you enter a clustered environment.

In such scenario, you have multiple classloaders on multiple JVMs, and your sinlgeton pattern will break as you will have several instances of that class.

The only acceptable use for a singleton in an app server (potentially in a clustered environment) is when you the singleton is totally state-less, and is only used as a convenience to access global data/functions.

I suggest checking your application server vendor's solution for this issue. Most, if not all vendors, supply some solution for requirements of your sort.

Specifically for Glassfish, which you say you are using, check out Singleton EJB support for Glassfish. It might be as simple as adding a single annotation.

Yuval A
This is the most important consideration. Because your app runs on an app server, there will be the automatic assumption that you can throw another server at it. If you aren't there to say "Don't do that", they are going to be cursing your name for generations.
Bill K
Any suggestions for the "other EJB Container"?
Grasper
Updated my answer a bit, it is very dependent on which app server you are actually using.
Yuval A
A: 

Fix the code to get rid of the statics as soon as possible. Singletons are not a step in the right direction - they just add extra misdirection.

Tom Hawtin - tackline
+2  A: 

I'm missing a point? You mentioned that the 'black box code' contains state. MDBs may be limited to 1 instance per destination but without proper configuration you will end up with a few MDBs. All of them working with your single instance of 'black box code'. For me it seems this is not a good idea, because one bean will override the 'black box code' state a other bean has created a few ticks before.

It doesn't matter if there is more than one MDB instance, they will be accessing the same "Black Box" instance, if the singleton model is strictly enforced.
Grasper
A: 

Don't use Singletons where state may change.

Exposing the global instance of your black-box class doesn't seem like the way to go. Often times, singletons will seem like they will make things easier on you, and in a way they can, but it often comes back to bite you and you end up having to restructure a large chunk of your code.

A: 

In the webserver world, an object can be scoped to the request, the session, or the application. Perhaps what you need is a application-scope object.

Search the docs for "application scope object" or "application lifetime object".

paulmurray
A: 

It seems to me that the artifact that better fits to your requirement is a JBoss MBean. (If you are thinking on JBoss as AS candidate).

Standard MBean Example

MBeans can also be deployed as Singletons, in case of JBoss clustering.

Clustering with JBoss

I hope that this is useful for you.

Rafa.

Rafa Sanchez
A: 

Why not create a rest interface for the blank box thingy and let clients make http calls ?

Jacques René Mesrine