Solved

Help me understand static!

Posted on 2002-07-25
16
204 Views
Last Modified: 2013-11-24
I've the following code which I am using to implement a pool of database connection pools ( our development environment needs each of our developers to have their own db pool - it's a long story.... )

Anyway, what I thought would happen is that as the applications make calls to DatabasePoolFactory.getInstance(...) I would create one and only one hashtable and put and get poolmanager objects from it. Here's the code:

package BslDatabasePool;

import java.util.*;
import SPAR.BslException.*;

public class BslDatabasePoolFactory
{

    static private Hashtable dbList = null;

/**
 * Retrieves an instance of the named PoolManager. This should be used when you
 * want to connect to a pool which you know ( or hope! )to be available, and you don't want to
 * go to the trouble of having to define the db context. If the Pool is actually
 * NOT running, then an UnknownPoolException is thrown.
 */
    static public synchronized PoolManager getInstance(String PoolName) throws Exception
    {
       return getInstance(PoolName,(SparDatabaseContext)null);
    }
   
/**
 * Retrieves an instance of the named PoolManager, creating a new one with
 * the supplied name and database context if one does not already exist. If
 * a pool manager exists with the specified name, YOU WILL BE RETURNED A
 * REFERENCE TO IT REGARDLESS OF WHETHER OR NOT ITS CONTEXT MATCHES THAT
 * WHICH YOU PASSED IN. This means that there is a possibility that you
 * may end up connecting to a database that you don't want to. Making sure
 * that this doesn't happen is dependent upon sensible naming standards.
 */
    static public synchronized PoolManager getInstance(String PoolName,
                                                       SparDatabaseContext SdbC)
                                                       throws Exception,
                                                              UnknownPool
    {

        if (dbList == null)
        {
            System.out.println("Creating New Database Factory");
            dbList = new Hashtable();
        }

        PoolManager tmp = (PoolManager)dbList.get(PoolName);

        if (tmp == null)
        {
            System.out.println("PoolManager Not Found - Creating New One called " + PoolName);
            if (SdbC == null)
            {
                throw(new UnknownPool(PoolName));
            }
            tmp = new PoolManager(SdbC);
            tmp.setName(PoolName);
            dbList.put(PoolName,tmp);
        }
         else {System.out.println("Pool Already Available");};

        return tmp;

    }

}

My understanding of static ( which I'm sure is wrong! ) is such that, as the first call on the static getInstance method is received, a dbList hashtable will be created and the message "Creating New Database Factory" will be produced. After that, any subsequent calls to getInstance will go to the hashtable and retrieve the specified poolmanager object. This appears to happen as long as only one tomcat servlet is running. When a second servlet calls getInstance, I would expect it to see that the static hashtable dbList is already in existence and just put any new pool manager instances in to the same hashtable. What _actually_ happens is that I see another "Creating New Database Factory" message, which I guess means that a new hash table is being created and populated.

My understanding was that a static class would exist once in the JVM. This doesn't appear to be happening. Where is my understanding letting me down?

Dave
0
Comment
Question by:howesd
  • 4
  • 4
  • 3
  • +3
16 Comments
 
LVL 35

Accepted Solution

by:
girionis earned 200 total points
ID: 7177902
 AFAIK it is likely to be a class loader issue. Where do you have BslDatabasePoolFactory class? Try to put it in your current working web application and see what happens.

  In general try to move it up and down the class loader hierarchy.

  Hope it helps.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 7177920
It seems to me your understanding of 'static' in this situation is quite correct. It seems a little mysterious to me too. But I could suggest the following, some of which might bring about a change:

1. If you're going to use some kind of pool manager, you could arrange for it to be preloaded by the context.

2. If you're going to do that, you may as well create dbList as soon as the class is loaded:

static private Hashtable dbList = new Hashtable();

3. Since this reference will never change, why not:

private static final Hashtable dbList = new Hashtable();

4. On an unrelated note, I would rename UnknownPool to UnknownPoolException.
0
 
LVL 4

Expert Comment

by:kylar
ID: 7178064
I agree in that it seems like your assumptions are correct and that there should only be a single Hashtable. Is it possible that multiple VM's are running somehow inside the servlet container? (I don't do much servlet work so forgive my ignorance :)

Listening Curiously...
-K
0
 

Expert Comment

by:cehjohnson
ID: 7178126
On the other hand, if you want to construct a BslDatabasePool explicitly at a certain point, you could make this class a singleton as an extra safeguard, if Tomcat will allow it. This means that you would have only *one* possible BslDatabasePool to get only *one* possible PoolManager from.
I say if Tomcat will allow it as Tom might not allow private constructors.
0
 
LVL 92

Expert Comment

by:objects
ID: 7178745
An instance of each static variable exists for every *class loader*. Tomcat uses a seperate class loader for each servlet which is resulting in what you are experiencing.
0
 
LVL 1

Author Comment

by:howesd
ID: 7179499
cehjohnson - After I posted the message I realised that making it a singleton class would be a good idea ( that was what I was actually trying to achieve but I'd made a hash of it! )

objects - given what you're saying about the separate class loader for each servlet, am I wasting my time in trying to produce a poolfactory which will serve up poolmanagers across a complete tomcat installation?

Dave
0
 
LVL 35

Expert Comment

by:girionis
ID: 7179553
 Take a look here for a detailed analysis:

http://www.javageeks.com/Papers/JavaStatics/index.html
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 86

Expert Comment

by:CEHJ
ID: 7179699
>>you could make this class a singleton as an extra safeguard, if Tomcat will allow it

Even that won't work as the paper girionis mentions explains, so my suggestion won't cure the problem. The problem can be treated by applying the principles the paper's author describes beginning 'Consequences'.
0
 
LVL 1

Author Comment

by:howesd
ID: 7179735
Unfortunately, I can't read the paper - I think the firewall I'm behind might be getting in the way. I'll try to read it when I can get access from another machine.

Thanks
0
 
LVL 1

Author Comment

by:howesd
ID: 7183140
I still can't get hold of the paper .... but, if I understand objects comment about each servlet having its own classloader correctly, does this mean that I need to instantiate the DatabasePoolFactory in one servlet ( probably one that loads on startup ) and then push it into the servlet context using getServletContext().setAttribute(...) and then get any other JSP's or servlets which want to use the pool to use getServletContext().getAttribute(...) ( or what ever it's called - I don't have my documentation with me at the moment )?

Dave
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 7183229
Probably easier if we somehow get you the paper! I wonder if you can't it because of the mime type of the url? You could try this if that's the case - the pdf file is converted into html:

http://access.adobe.com/perl/convertPDF.pl?url=http://www.javageeks.com/Papers/JavaStatics/JavaStatics.pdf

If that doesn't work, let me know and I'll mail you the file.

In the meantime you can save yourself some time by implementing the singleton anyway, as we were discussing, although as you'll see when you read the document, this will not be sufficient in itself to cure the problem.
0
 
LVL 1

Author Comment

by:howesd
ID: 7183232
CEHJ - That's very kind of you. I'll read it and let you know what I make of it

Dave
0
 
LVL 35

Expert Comment

by:girionis
ID: 7183265
 Or you can send me an e-mail to p_konstantinidis@hotmail.com and I will mail the file to you. I rarely ever use his address anymore.  It's mainly full of junk mail so I do not mind getting some more. I have just deleted all my mails cause my mail box was full, so there is space for your e-mail (if you decide to send me one).

  Hope it helps.

0
 
LVL 92

Expert Comment

by:objects
ID: 7184183
> am I wasting my time in trying to produce a poolfactory
> which will serve up poolmanagers across a complete
> tomcat installation?

No, what you need to do is ensure your singleton pool factory is loaded by the system class loader. You can do this by ensuring the classes are found in the ext directory or the classpath.

0
 
LVL 35

Expert Comment

by:girionis
ID: 8952206
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:

- points to girionis

Please leave any comments here within the
next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

girionis
Cleanup Volunteer
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
nestparen challenge 4 56
json example 39 115
Image decoding from Camera 3 47
Java Server Faces parameter pass? 6 24
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now