Singletons and Serialization Question

C

christopher

I am operating within Tomcat 6. I use 'collector' singletons to build
complex trees of objects from database queries. These singletons rely
on a pool of connections to various data sources, which are made
available via a 'connection pooling' singleton like this:

Connection
con=DriverManager.getConnection(MyPoolingSingleton.getPool("dbwrite"));

where "dbwrite" is the name of a connection that was established
earlier having certain permissions, etc.

My goal is to remove the 'collector' singletons to an app server and
obtain copies of them on a web server via serialization. They still
need access to the database after they are created. In this case the
'connection pooling' singleton must be instantiated locally on each
web server, since connections cannot be pooled across multiple JVM's
in my little world.

My question is, how to ensure the MySingleton.getPool() method call
points to the local singleton and not the singleton from the
originating server. Is it sufficient to ensure MyPoolingSingleton is
not serializable? Do I need to use a mechanism like a transient
instance variable to get a reference to the local copy of
MyPoolingSingleton?

Thanx all!
 
M

Mark Space

My goal is to remove the 'collector' singletons to an app server and
obtain copies of them on a web server via serialization. They still
need access to the database after they are created. In this case the
'connection pooling' singleton must be instantiated locally on each
web server, since connections cannot be pooled across multiple JVM's
in my little world.

This sounds like a bad bad idea. I'm no expert on this, but connections
in general have lots of local resources that are completely
non-applicable to a new server. You'll probably have to serialize just
the connect string ("server:login:password" or whatever) and then
instantiate a new connection on the new server.
My question is, how to ensure the MySingleton.getPool() method call
points to the local singleton and not the singleton from the

There's a readResolve method that can substitute objects during
de-serialization. It's often used for singletons.
 
C

christopher

This sounds like a bad bad idea. I'm no expert on this, but connections
in general have lots of local resources that are completely
non-applicable to a new server. You'll probably have to serialize just
the connect string ("server:login:password" or whatever) and then
instantiate a new connection on the new server.

The whole idea is the connect string is hidden for security reasons.
There's a readResolve method that can substitute objects during
de-serialization. It's often used for singletons.

Perfect thanks! I read right over this, but it solves the problem
neatly.
 
R

Roedy Green

This sounds like a bad bad idea. I'm no expert on this, but connections
in general have lots of local resources that are completely
non-applicable to a new server. You'll probably have to serialize just
the connect string ("server:login:password" or whatever) and then
instantiate a new connection on the new server.

I agree. Make these transient and remake the connection or
reconstitute. It is actually quite different beast. The end points
are not even the same.
 
A

Andrea Francia

The whole idea is the connect string is hidden for security reasons.

Even if you manage to serialize the Connection you can prevent a
malicious user to read the serialized file and discover the connection
string. He or she can use an hex editor or ad hoc created java program.

To hide the connection string from occasional user you can simply
encipher it before saving it.
 
M

Mark Space

The whole idea is the connect string is hidden for security reasons.

I'd be interested in seeing how you actually do this. I can't think of
any way to do this myself. Like Andrea the next thing that comes to
mind is to encrypt the connect string.
 
C

christopher

I'd be interested in seeing how you actually do this. I can't think of
any way to do this myself. Like Andrea the next thing that comes to
mind is to encrypt the connect string.

First, the connect url, username, and password are in a file with
access restrictions -- they are never in the source, which means there
is only one place from which the passwords can be obtained (except
from memory and my workstation). This file is read at the time the
singleton is instantiated, which occurs when the Tomcat context is
started using ContextListener. Then the connections are created and
references to them are kept in the singleton. It is these references
that are used to obtain the connections like "dbwrite" in the above
example, *not* connect strings. There are connectors for different
databases and connectors that are read-only for eventual database load
balancing if it becomes necessary.

(Not that it matters to this question, but I think what some of you
are missing is the fact that these connections are created by a
factory earlier using the url, name and password, and that
DriverManager.getConnection() is returning a reference to a pooled
connection, not creating a new one, so it doesn't need the password.
An interesting side note is connections obtained in this manner are
shared by all the webapps in Tomcat 6, so the references to them have
to be individualized per webapp. I found this out when one webapp was
updating data in the wrong database during a test phase!)

The fact that the connection cannot be serialized is what prompted my
question -- sorry I was not clear! I intended to say that a pool of
connections would be maintained on each of the 'web' servers, which
obtain serialized 'collector' singletons form the 'app' server. These
'collector' singletons currently refer directly to a singleton
'connection pooler' which without modification of the code is
definitely not going to work. I was not certain how to use
'transient' to prevent the 'connection pooler' from being serialized,
and I was unclear what would happen if I just made it not
serializable. It looks like "readResolve" will accomplish what I
need, forcing the local copy of the 'collector' singleton to use the
local instance of the 'connection pooler'.

I hope I said this right. Its a big job, so I will make a trial run
using this technique before I update all my code. Thanx for all your
help!
 
M

Mark Space

I hope I said this right. Its a big job, so I will make a trial run
using this technique before I update all my code. Thanx for all your
help!

Well I don't think I understood all of that, but good luck. There were
to many things in your post that referred to some internal concept in
your own code. I would have loved to see a description how the actual
jdbc objects move about.

It does seem to me that you have some proxy objects ("collectors") that
make requests not to the DB, but to the app server, and it's the app
server that has the full connection string. However, I'm not sure
that's what is going on.

Anyway, have fun. ;-)
 
A

Andrea Francia

First, the connect url, username, and ...
Now I realized that I did not understood the problem.
You don't need to serialize the connection but your collector object.
I hope I said this right. Its a big job, so I will make a trial run
using this technique before I update all my code. Thanx for all your
help!
I wish you to resolve successfully your problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top