Singletons and Serialization Question

Discussion in 'Java' started by christopher@dailycrossword.com, Mar 26, 2008.

  1. Guest

    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!
     
    , Mar 26, 2008
    #1
    1. Advertising

  2. Mark Space Guest

    wrote:

    > 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.
     
    Mark Space, Mar 26, 2008
    #2
    1. Advertising

  3. Guest

    On Mar 26, 12:22 pm, Mark Space <> wrote:
    > wrote:
    > > 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.


    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.
     
    , Mar 26, 2008
    #3
  4. Roedy Green Guest

    On Wed, 26 Mar 2008 19:22:32 GMT, Mark Space
    <> 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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 26, 2008
    #4
  5. wrote:
    > 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.

    --
    Andrea Francia
    http://www.andreafrancia.it/
     
    Andrea Francia, Mar 26, 2008
    #5
  6. Mark Space Guest

    wrote:

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


    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.
     
    Mark Space, Mar 26, 2008
    #6
  7. Guest

    On Mar 26, 1:23 pm, Mark Space <> wrote:
    > wrote:
    > >> 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.

    >
    > 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!
     
    , Mar 26, 2008
    #7
  8. Mark Space Guest

    wrote:

    > 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. ;-)
     
    Mark Space, Mar 26, 2008
    #8
  9. wrote:
    > 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.

    --
    Andrea Francia
    http://www.andreafrancia.it/
     
    Andrea Francia, Mar 26, 2008
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    8
    Views:
    2,253
    deadsea
    Jan 2, 2005
  2. Replies:
    3
    Views:
    1,035
  3. Dimitri Ognibene
    Replies:
    4
    Views:
    785
    Dimitri Ognibene
    Sep 2, 2006
  4. Ramunas Urbonas
    Replies:
    1
    Views:
    403
    Dino Chiesa [Microsoft]
    Jul 27, 2004
  5. salai
    Replies:
    2
    Views:
    78
    salai
    Jun 5, 2009
Loading...

Share This Page