I am working on a legacy website which uses stateless session EJB's and runs on
WebLogic 6.1 using JDK 1.3 and Oracle 8.1.6, I am working on upgrading this
application to WebLogic 9.2, JDK 1.5 and Oracle 10.2.
I configured a datasource in WebLogic using the Oracle thin XA driver.
When attempting to run the application I got an error message stating that an
object which is not serializable is being passed as an EJB parameter. I found that
several EJB methods are passing open database connections as parameters so to fix this
issue we should change the code. However, I am reluctant to change the code since I
believe that the reason for passing the connection objects is that the developers
wished to preserve transactions and so any changes might result in many issues in
the application. I have the following questions:
- The code is doing something which is not allowed. So why was this okay in WebLogic
6.1 using the older Oracle oci driver?
- One way to get around this would be to convert the EJB's to POJOS. There are no
container based properties and the only EJB's are stateless session EJB's. The
high water mark for concurrant usage is 40. There is only a single server (no clustering)
What kind of issues would such a
- Would it be better to convert the EJB's to local interfaces? What kind of issues would
Any other suggestions would be very much appreciated.
First of all, passing Connections around in an EJB environment is a totally broken design. Without further knowledge of your technical reqs, the ejb container is perfectly capable of handling your transactions to ensure that different operations within a transaction also remain within that very transaction. But, enough said about that.
I am no WebLogic expert, but I would believe swithching to local interfaces would make the app behave like the earlier version of it, since you want to avoid parameter serialization. And by using local interfaces no serialization will occur, thus passing the Connection instance will not throw an exception.
Switching to pojos will probably introcude a magnitude of new issuses to deal with. So, to minimize your time and effort for this conversion, and if there is not anything else missing in this picture, no further changes than switching to local interfaces should be neccessary to fix your problem.
A lot of things have changed since WebLogic 6.1.
WLS 6.1 used to pass parameters by reference on local calls and by value on remote calls. So it didn't matter that your Connection object was not Serializable because WLS 6.1 didn't try to serialize it but just passed a reference to it.
At WLS 9 the distinction between "local" and "remote" isn't as clear cut as it used to be. At WLS 6.1 if the EJB and its client were in the same JVM, it was a local call and so call by reference semantics were used even for EJB remote interfaces. But now at 9.x it makes a difference if you are dealing with objects in different EARs or WARs. Even though the EJB is running in the same instance of WebLogic, it may still count as a remote call, in which case WLS will insist that the parameters must be passed by value and as such must be Serializable.
It is possible that you are using remote interfaces but accessing the EJB from within the same EAR file. In this case, WLS 6.1 would pass by reference by default. But for WLS 9.x the default behaviour is to pass by value. If you are accessing these EJBs via remote interfaces in the same application, you could try setting enable-call-by-reference to true in the EJB deployment descriptor. That may solve your problem. Alternatively, you could convert the EJBs to use local interfaces (which may or may not be a small job depending on the existing code).
If the call is from a different application then you are screwed. The parameters will always be passed by value and there is nothing you can do about it: you will have to re-architect the application. In this case you will not be able to use local interfaces because as far as WLS is concerned, it's a remote call. If you move to POJOs I would think that the biggest problem you will face will be transaction demarcation because you will lose the benefits of CMT.
By the way, this is all documented in the WebLogic documentation which is all available on-line.
I would not believe moving to local interfaces for EJBs would be a robust solution from long term point of view . It is very likely that the scalibility of the application increases as and when the application gets older . The question is that later down the line will the application be able to sustain the load without clustering and hence w/o remote interface EJB calls ? Going the harder way a better solution would be to make the connection serializable if that is what it has been designed as .
Yes the code is terrible since it specifies container managed transactions for all methods and then passes the connection around freely. I am not sure what the developers were thinking but that is beside the point now since I am stuck with this architecture. It is a production application and there are many other changes in the queue before a redesign can be attempted.
I am going to try using the call by reference since setting it explicitly will make the app behave just like it did before. I did see call by reference mentioned in the weblogic-ejb deployment descriptor but was unsure because I did not know about the behaviour changes between 9.2 and 6.1 and your comment did help clarify that. I also got the same feedback from WL support so I think that is the best option among all the bad options that I have. I hate to lock the application into a state where clustering and moving to an alternative J2EE server becomes impossible but given the state of the code it should probably be rewritten before clustering is attempted. I am just trying to put a band aid for now until a longer term solution becomes possible.