How to configure Permanent Servlets in Tomcat 6? - java

Permanent servlets are loaded when the server is started, and live until the server is
shutdown.
I have requirement to start some server side java programs and These programs then provide functionality that is totally unique and independent of the web server. I wish to do it on Tomcat startup. Solution I see is Permanent Servlet, Which will invokes these Java programs.
So How to configure Permanent Servlets in Tomcat 6 ?
More Details about Permanent Servlets from http://java.sun.com/developer/onlineTraining/Servlets/Fundamentals/servlets.html
Temporary versus Permanent Servlets
Servlets can be started and stopped for each client request, or they can be started as the web server is started and kept alive until the server is shut down. Temporary servlets are loaded on demand and offer a good way to conserve resources in the server for less-used functions.
Permanent servlets are loaded when the server is started, and live until the server is shutdown. Servlets are installed as permanent extensions to a server when their start-up costs are very high (such as establishing a connection with a DBMS), when they offer permanent server-side functionality (such as an RMI service), or when they must respond as fast as possible to client requests.
There is no special code necessary to make a servlet temporary or permanent; this is a function of the server configuration.
Because servlets can be loaded when a web server starts, they can use this auto-loading mechanism to provide easier loading of server-side Java programs. These programs can then provide functionality that is totally unique and independent of the web server. For example, a servlet could provide R-based services (rlogin, rsh, ...) through TCP/IP ports while using the servlet request/response protocol to present and process HTML pages used to manage the servlet.

You can do what you need with a ServletContextListener. Register one in your web.xml, e.g.:
<listener>
<listener-class>com.example.MyServletContextListener</listener-class>
</listener>
Then create that class to do what you want:
public class MyServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
// initialize and startup whatever you need here
}
public void contextDestroyed(ServletContextEvent sce) {
// shutdown and destroy those things here
}
}

I think what they are referring to when they say "permanent servlets" are just the servlets you define in the web.xml, a la,
<servlet>
<description>I'm permanent</description>
<display-name>Servlet</display-name>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
This servlet will be started up when the server starts and will be kept around until it shuts down, probably (See below).
An example temporary servlet would be a .jsp file. It wont load the file up until it is requested and it will probably dispose of it after servicing the request.
Looking at the Servlet Specification about servlet lifecycles,
When the servlet engine is started, needed servlet classes must be located by the
servlet container. The servlet container loads the servlet class using normal Java class
loading facilities. ...
After loading the Servlet class, the container instantiates it for use.
Then for eol,
The servlet container is not required to keep a servlet loaded for any particular
period of time. A servlet instance may be kept active in a servlet container for a
period of milliseconds, for the lifetime of the servlet container (which could be a
number of days, months, or years), or any amount of time in between.
When the servlet container determines that a servlet should be removed from
service, it calls the destroy method of the Servlet interface to allow the servlet to
release any resources it is using and save any persistent state. For example, the
container may do this when it wants to conserve memory resources, or when it is
being shut down.
Before the servlet container calls the destroy method, it must allow any threads that
are currently running in the service method of the servlet to complete execution, or
exceed a server-defined time limit.
Once the destroy method is called on a servlet instance, the container may not route
other requests to that instance of the servlet. If the container needs to enable the
servlet again, it must do so with a new instance of the servlet’s class.
After the destroy method completes, the servlet container must release the servlet
instance so that it is eligible for garbage collection.
So I think bottom line, the servlet specification makes no guarantee as to how long a servlet will be kept, it is implementation specific, but I think its a pretty safe bet that if you load it on start up it will remain loaded for the whole time the server is running.
For your specific use case though, follow WhiteFang34, as using a servlet for something other than servicing requests is abusing the API IMO.
[Edit] Everywhere I look to see how a servlets' lifecycle is managed seems to say that it will remain loaded for the entirety of the webapps lifetime.
Servlets
What is the difference between JSF, Servlet and JSP?
java servlet instantiation and session variables
But nowhere can I find a reference that says that, so I just don't know for certain.

Related

when container call deployment descriptor (web.xml)

We know that whenever a request for a servlet comes, servlet container will first check web.xml file for url and corresponding servlet classes. This is fine, But the confusion comes after that. Suppose I am using load-on-startup property. SO, the servlet should be ready before first call comes in. In that case container need servlet Config object to make servlet in work. But again load-on-start up and init-parameter for servlet is defined in web.xml file. So when exactly container uses web.xml?( when load-on-startup property is used then container can not obviously wait for first call, again container has to read web.xml file to know whether that property is used with any servlet.)
It will be better if some one can clear my confusion. Please provide some dependable link also if possible.
Loading and Instantiation:
The servlet container is responsible for loading and instantiating servlets. The loading and instantiation can occur when the container is started, or delayed until the container determines the servlet is needed to service a request.
When the servlet engine is started, needed servlet classes must be located by the servlet container. The servlet container loads the servlet class using normal Java class loading facilities. The loading may be from a local file system, a remote file system, or other network services. And as the servlets are declared in the web.xml, this file is loaded and read by the container during container startup.
Initialization:
After the servlet object is instantiated, the container must initialize the servlet before
it can handle requests from clients.The container initializes the servlet instance by calling the init method of the Servlet interface with a unique (per servlet declaration) object implementing the ServletConfig interface.
Ref: JSR-000315 JavaTM Servlet 3.0
web.xml is read as soon as you deploy your application on a web server. For the sake of understanding, you can assume container is nothing but your web server. Although web server has more than just a web container.
Web server reads the web.xml, and loads the context config, load on startup servelts,etc. web.xml is the file through which you tell your container/server about your application. Your web application sits inside the web server, and server intercepts all the incoming requests, decides to which application the request should be forwarded depending on the context.

How do I run an action on server startup using Struts2?

I have to execute a struts2 action on server startup rather than on the first request.
Loading data on startup of an application is a common task, you will find several examples on the web. As said in other answers, you should implement a ServletContextListener (that is not Struts2 specific)... you can read a great example here.
The important thing here is understanding the Action concept:
In Struts2 MVC (Model View Controller) Framework, an Action is the Controller (and part of the Model).
Actions are invoked by Requests coming from the Clients (and one Action is created on every request, so they're thread-safe).
This means that you need a Client, that usually means a guy in front of a pc, clicking on a browser... then, a client call is not the right trigger to perform automated, server-side operation on shared objects.
Of course you could implement some form of lazy-initialitazion (eg. with the help of a custom Interceptor) so that the first user would set-up something in the Application scope, and the other users would retrieve the object already populated, but this is not the best way to do it (you should handle the concurrency on the initialitaion, and you would have one user, the first, waiting for operations that the server could have done in the night on startup...).
Write a ServletContextListener, this will be available only one per web application and will get instatiated when the application is deployed.
Here is the post
If you want to some code to run when your web application, aka Servlet Context, starts for the first time, then you should leverage the hooks provided by the technology. The Servlet API provides lifecycle hooks for you to use to fire code at various lifecycle stages of a web application. Since all Struts 2 applications are Servlet API web applications, then you can leverage this yourself.
The ServletContextListener interface provides an init hook method. You simply implement this interface and register your implementation in the web.xml.
Note, if what you need to do is more Struts 2 specific, then you could consider utilizing something from within the Struts 2 API itself.
Load on start-up in servlet and jsp is present as below
You can ask the page to be loaded when the server starts. This is done via the web.xml file
<servlet>
<servlet-name>login</servlet-name>
<jsp-file>/login.jsp</jsp-file>
<load-on-startup>1</load-on-startup>
</servlet>
Normally jsp file is compiles on first hit.
Now the code says precompile a jsp file without waiting for the first hit.
For struts2 you can change programatically in web.xml
<listener>
<listener-class>your listener class</listener-class>
</listener>
refer this link it might be helpful to you
Loadonstart up.

Servlet Filters - Context Initialization

When using a "global" filter, one which is located in the root lib directory of an apache tomcat webserver and applies to all web application contexts:
I was wondering if the web application contexts are initialized synchronously - one at a time, or can there be a case where the Filter.init() function is called by two different contexts in the same time.
I'm asking this since I want to initialize a database connection configuration object based on a specific FilterConfig.initParameter the first time init() is called by any of the application contexts, and I'm wondering if I should put the above in a synchronized block or not...
I think it's the internals of Tomcat, it could change any time so I'd do it in a synchronized block. It's not a big deal or performance issue because it runs only once per application context initialization.
From Java Servlet Specification 6.2.1 Filter Lifecycle:
Only one instance per <filter> declaration in the deployment
descriptor is instantiated per JVM of the container.
You could reach the same result with a custom Valve:
The Valve Component
Valve javadoc

initialize ServletContext using a method on a Resin server

Is there a way to initialize the ServletContext for a webapp on a Resin server using a method? I need something like that runs once, when the server starts up.
You need to use a ServletContextListener.
http://www.java-tips.org/java-ee-tips/java-servlet/how-to-work-with-servletcontextlistener.html
This J2EE tip demonstrates use of
ServletContextListener. This event
class handles notifications about
changes to the servlet context of the
Web application that they are part of.
This can be explained as if someone is
present on the server and dynamically
informing us about the events that are
occuring on the server. There acquire
need of Listners. Therefore,
ServletContextListner is helpful in
informing about context Initilazation
and destruction.
Use the <load-on-startup/> in the <servlet> tag.

How do servlets work?

I write couples of servlet program, however I dont think I fully understand how servlet run. So here is couples question that I have:
All the code I wrote about Servlet only run on Netbeans with apache tomcat run behind. When I run my html file that make request to the servlet, it usually give error saying that it could not find the servlet, I then have to redeploy the servlet then everything would run fine. Seem like my servlet timeout after a while or something.
Does the servlet run all the time? Servlet has init() and destroy(), so I guess it wont run all the time. So then when does it start and when does it end? Does it start when there is a request from the client, and end when it is time out? And how does I fixed my problem that I have to constantly redeploy the servlet. Thank you very much.
Under normal circumstances, a servlet is only destroyed at shutdown (ie when the application container, such as Tomcat, is shut down). Otherwise it remains in memory for the duration of the application. I couldn't say what's going on with your Netbeans setup, but try deploying your WAR file to a standalone Tomcat installation and see if the problem doesn't go away.
Another time that the application container will call destroy on a servlet is if it is running out of memory, but this is far less common.
Regarding your question about requests, a servlet is designed to handle many requests. It is said that the servlet is application-scoped, whereas the request has its own scope.
You're apparently in middle of developing with servlets. You need to ensure that the webapp is fully published whenever you have made changes to web.xml or any of the Servlet classes. Otherwise you may risk that the resource cannot be found.
In easy terms, a "resource not found" error is basically exactly the same as a "404 page not found". The servlet container can't seem to find a resource which matches the URL or url-pattern. That's all.
As to the Servlet lifecycle, it will be created only once during webapp startup (publish, create of context), the init() method will be called and the instance will be kept in the server's memory in a sort of a Map<Url-Pattern, Servlet>. If you have overriden the init() method in your Servlet, then it will be called. The servlet container will do the same for all of the servlets declared in web.xml (or as per Java EE 6, annotated with #WebServlet).
Everytime a request whose URL matches the url-pattern of the Servlet, the (inherited) service() method will be invoked. The normal HttpServlet implementation will then determine the method to be executed based on HttpServletRequest#getMethod(). If you did override any of those methods (doGet(), doPost(), etc) in your Servlet, then it will be invoked accordingly.
Finally, when the webapp is about to shutdown (unpublish, destroy of context), then the destroy() will be invoked for any of the Servlet instances kept in server's memory. If you have overriden the destroy() method in your Servlet, then it will be called.
A servlet "runs" only when it's invoked. The server will wait for a connection to come from the client, read the headers, find the proper servlet based on the mappings in web.xml, and then call the service() method of that servlet. The servlet object, will remain in-memory until the container decides to dispose it (which it may do at any time that it's not servicing requests). If the server decides to dispose of a particular servlet instance, it will create a new one the next time a request comes in for the servlet.
Which means you should not be getting an error that says the server can't find your servlet. Assuming that the application has been deployed, and there is a correct servlet mapping, the container will be able to process the request. If you edit your request and paste the exact error message, someone may be able to tell you why this isn't happening.
you need to research the servlet lifecycle - that's what the init() and destroy methods are there for
normally init() is called once, when the serlvet is first called (unless you did something like set it to autorun in tomcat)
and destroy() is called when the container shuts down
dopost() or doGet() (if it's an HTTP servlet) are called for each request

Categories

Resources