This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I am trying overcome a situation that I ran into today when deploying my application. I have a BaseControl class that is inherited by all the other servlets. With BaseControl(), the super() is called and then init(). It is during init() first that I load up all system resources, create a db connection, etc - this happens only 1 time during the entire session for a user. My BaseControl doesn't implement the doGet or doPut , I leave that to the class servlet inheriting.
In my environ I have a dev and prod directories on the host system. What I was trying to do was when the user types in http://blah.blah.com/, this loads up the Main servlet. But before doGet or doPut process, init() runs first. The problem is that since init() is running, I can't determine what URL is being called so I know whether to load the properties for dev.com or prod.com instance because apparently the request/response is not valid or null in the init() call.
If there only a way to get HTTP Request and Response into the intialization section so I can call getRequestURL() and know which properties file to use.
First of all, no. You cannot subvert the life cycle of a servlet. Thankfully.
To start off, why are you trying to do initialization in a servlet in the first place? The purpose of a servlet is to fields requests and serve responses. Its init() should be confined to any initialization needed by that servlet, and nothing else.
App initialization is the job of a context listener, not a servlet.
The next problem, is what you are doing in the initialization. Grabbing a db connection in advance? That's the worst thing you could possibly do. That is guaranteed -- not perhaps, not maybe, not if -- guaranteed to cause problems as soon as requests start coming into the servlet. Not only that, but db connections are scarce and precious resources that should be used very miserly. If you are not using an ORM tool that's managing the connections on your behalf (which you obviously are not), you should be using container-managed connection pooling. Grab a connection only when you need it (and not a nanosecond sooner), and release it as soon as you are done with it (and not a nanosecond later).
And finally, environmental values that need to change from installation to installation are easily handled with a properties file.
You can't. (That's because it's possible to configure a servlet to be initialized when the server starts up, at which time there wouldn't be any request in progress.)
If you want to do application-level initialization, I would suggest a ServletContextListener where you can implement the contextInitialized() method... but wait, that has the same problem, namely that there's no request taking place. Which raises the question: why do you need a request to be able to tell whether the system is dev or prod?
Joined: May 27, 2010
Actually, I think I can resolve the question on the properties/pathing by asking it this way. Since BaseControl is the class that loads up the properties files for the system, how can I have the properties file load for it without telling it exactly where the file is at (specified path?). Right now I have it hardcoded to point to a directory because it is convenient to find it. But is there something where if I put the properties file in the BaseControl class dir that it will look in its immediate class directory? Sample code to show how that is done? Then instead of me hardcoding the paths for the main system file, by default, the class loads this file up from its own directory that contains the properties for that particular domain and application paths. Does that sound right? or am I off?
Here is how I am currently getting the systems property file information.
What would be the changes to have this code load up a properties file from the class path directory where BaseControl is located?
To the point of the Database Connection calling. You are saying I should not create the connection up so early, but should only create it at the mere moment that I am going to make a call to the db, get the information, and close it out as soon as possible? What I will do is load up the resource information during system startup, but take out the code to create the connection.
I will keep these 2 lines
theDatabaseConnector = new DatabaseConnector(myDriver,myType,myServer,myPort,myDatabase,myUser,myPass);
Connection con = null;
(All the DB Connection constructor does is just stores the variables passed and calls class.forName(DB_Driver); )
and then I take this line where I was actually getting the connection upfront to only do it where the Commands are getting called, then close the connection.
con = theDatabaseConnector.getConnection();
Thanks for the sanity check here guys and your immediate help. I am appreciate to have such quick responses before I get too far down the road!