Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2008

Tip: Looking for answers? Try searching our database.

Singletons and Serialization Question

Thread view: 
christopher@dailycrossword.com - 26 Mar 2008 19:58 GMT
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!
Mark Space - 26 Mar 2008 20:22 GMT
> 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.
christopher@dailycrossword.com - 26 Mar 2008 20:43 GMT
> christop...@dailycrossword.com wrote:
> > My goal is to remove the 'collector' singletons to an app server and
[quoted text clipped - 9 lines]
> 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.

> > 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.

Perfect thanks!  I read right over this, but it solves the problem
neatly.
Andrea Francia - 26 Mar 2008 20:58 GMT
> 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.

Signature

Andrea Francia
http://www.andreafrancia.it/

Mark Space - 26 Mar 2008 21:23 GMT
>> 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
[quoted text clipped - 3 lines]
>
> 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.
christopher@dailycrossword.com - 26 Mar 2008 22:36 GMT
> christop...@dailycrossword.com wrote:
> >> This sounds like a bad bad idea.  I'm no expert on this, but connections
[quoted text clipped - 8 lines]
> 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!
Mark Space - 26 Mar 2008 23:18 GMT
> 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. ;-)
Andrea Francia - 26 Mar 2008 23:53 GMT
> 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.

Signature

Andrea Francia
http://www.andreafrancia.it/

Roedy Green - 26 Mar 2008 20:44 GMT
On Wed, 26 Mar 2008 19:22:32 GMT, Mark Space
<markspace@sbc.global.net> wrote, quoted or indirectly quoted someone
who said :

>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.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.