tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steven Elliott <ttoi...@mac.com>
Subject Re: Singleton pattern using Servlet init() and <load-on-startup> ?
Date Sat, 30 Mar 2002 12:25:04 GMT
On 29/03/02 22:04, "Wil Doane" <wdoane@hawaii.edu> wrote:

> Steven-
> 
> I've focused on enforcing Singleton on the DATA MODEL ONLY by using a
> minimal MVC structure... I couldn't care less how many instances of
> the controller accessing my data model exist, so long as they all
> access the same data structure, and so long as I synchronize the
> accessor methods in the DataModel class, I'm happy.
> 
> That is to say, I'm not sure that it's necessary to force there to be
> a single instance of a given servlet, so long as the data structures
> accessed by that servlet enforce Singleton.
> 
                < snip the example >

Aloha Wil.
Thanks for the reply but I don't implicitly agree that it is possible with
the code you provided to implement the Singleton pattern in a class
instantiated from a servlet invoked with <load-on-startup> in the Tomcat
container.

Why? Because I think the issue here is that more than 1 classloader is at
work. If you have a moment please check my code.

The code I used to test (sorry for the line wraps):

------------------------------< Your DataModel class code >-----------------
// Declaration of worker class DataModel
public class DataModel {
    
/** Ths singleton DataModel instance */
        private static DataModel theInstance;
        
 /** Internal data implementation */
        private static Long myData;
        
 /** Private constructor used to create a single instance of myData */
        private DataModel() {
            this.myData = new Long(System.currentTimeMillis());
        }
        
        public static Long getMyData() {
            return myData;
        }
        
 /**  Get the single instance of DataModel object. */
        public static DataModel getInstance() {
            System.out.println("DataModel is alive ="+(DataModel.theInstance
!= null));
            if (DataModel.theInstance == null) {
                DataModel.theInstance = new DataModel();
            }
            return DataModel.theInstance;
        }
}
------------------------------< Servlet code >-----------------
public class Singleton extends HttpServlet {

    DataModel dataModel;
    
    public void init()
        throws ServletException
    {
        System.out.println("Singleton initialized");
        this.dataModel = DataModel.getInstance();
        System.out.println("Got instance "+dataModel.getMyData());
    }
    
        
    public void destroy() {
    System.out.println("Singleton destroyed "+dataModel.getMyData());
    }

}

------------------------------< Results >-----------------
Starting service Tomcat-Standalone
Apache Tomcat/4.0.3
Singleton initialized
DataModel is alive = false
Got instance 1017488519801
Singleton initialized
DataModel is alive = false
Got instance 1017488523258
Singleton initialized
DataModel is alive = false
Got instance 1017488525010
Singleton initialized
DataModel is alive = false
Got instance 1017488526991

When I stop Tomcat I get the following:
Stopping service Tomcat-Standalone
Singleton destroyed 1017488519801
Singleton destroyed 1017488523258
Singleton destroyed 1017488526991
Singleton destroyed 1017488525010

So it would seem that either I am doing something entirely wrong or there
are four instances of DataModel each with a different DataStructure?  Is it
my implementation of your singleton pattern or is it that Tomcat is somehow
instantiating 4 different instances of the DataModel and DataStructure?
Because under normal circumstances I would say that your singleton pattern
looks fine.

But even if your code (and my implementation) proved to implement a
singleton I would still have at least two other problems:

    (1) a separate class outside of Tomcat does not meet my needs
    (2) the apparent conflict between the 2.3 Servlet spec and Tomcat's
         implementation.

(1)
My original purpose was to provide a means for my application to schedule
certain utility functions such as periodic email scheduling of database
reports, etc.  These classes (TimerTasks) would be scheduled at startup from
parameters with a Timer servlet.  I thought that it would be nice if these
utility classes could take advantage of the Application resouces (such as
the datasource pools).  But if I instance a class w/o Context such as your
DataModel, these resources cannot be made available.  Only if I use a
resource with Context within Tomcat can I get these benefits (or so it seems
to me since no one has been kind enough to reply to my other email regarding
how to pass access to JNDI Contexts from normal class files invoked from the
command line (eg. JCronTab)).  But not to digress too much and I hope you
see why I need to start this up from a Servelt and preferrably one which
starts on loadup.  You can also see why if 4 servlets of this type are
started what a waste of resources not to mention my client's irritation at
receiving 4 different versions of the same report.

(2)
The second problem is that in the 2.3 Servlet spec it strongly indicates
that only one instance of a Servlet will be invoked EXCEPT in the case where
that Servlet implements the SingleThreadModel.  In load conditions, the
Container can invoke more instances of classes implementing the
SingleThreadModel interface.

So, I would say that either my interpretation of the 2.3 Specs is incorrect
or Tomcat is instantiating (and keeping alive!!!) more than one instance of
a <load-on-startup> Servlet.  Possibly even more serious is that fact that
each servlet is getting initialized with different values.

In any case if you see problems of my implementation of your code or want me
to try something else please let me know and I'll get it done.  In the
meantime I'll wait and hope to hear something from Craig or another of the
TC developers shedding some light on this problem before filing a Bug
report.

Mahalo...

Steven

BTW I can only find in the logs (Application and Catalina logs) one
declaration of the Singleton.class being started!!! How weird.


--
To unsubscribe:   <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
For additional commands: <mailto:tomcat-user-help@jakarta.apache.org>
Troubles with the list: <mailto:tomcat-user-owner@jakarta.apache.org>


Mime
View raw message