views:

157

answers:

1

I'd like my Jython servlet to implement the HttpServlet.contextInitialized method but I'm not sure how to express this in the web.xml. What I currently have is:

from javax.servlet import ServletContextListener;
from javax.servlet.http import HttpServlet

class JythonServlet1 ( HttpServlet, ServletContextListener ):

        def contextInitialized( self, event ):
            print "contextInitialized"

            context = event.getServletContext()

        def contextDestroyed( self, event ):
            print "contextDestroyed"

            context = event.getServletContext()

        def doGet( self, request, response ):
            print "doGet"

        def doPost( self, request, response ):
            print "doPost"

And my web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" version="2.5">

  <display-name>JythonTest</display-name>

    <servlet>
        <servlet-name>PyServlet</servlet-name>
        <servlet-class>org.python.util.PyServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>PyServlet</servlet-name>
        <url-pattern>*.py</url-pattern>
    </servlet-mapping>

    <servlet>
        <description></description>
        <display-name>JythonServlet1</display-name>
        <servlet-name>JythonServlet1</servlet-name>
        <servlet-class>JythonServlet1</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

</web-app>

As you can see, in the last <servlet> entry I'd like to initialize the servlet with the context (where I can start a scheduler) but it doesn't seem to work the same as with a Java servlet.

+1  A: 

I don't do Jython, but there's no means of contextInitialized or contextDestroyed methods in the HttpServlet API. You're probably looking for ServletContextListener interface which is normally to be implemented as the following Java-based example:

package com.example;

import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event) {
        // ...
    }
    public void contextDestroyed(ServletContextEvent event) {
        // ...
    }
}

...which is to be definied as <listener> in web.xml as follows:

<listener>
    <listener-class>com.example.MyServletContextListener</listener-class>
</listener>

This must give you an idea how to pickup it using Jython.

You can optionally also let your servlet both extend HttpServlet and implement ServletContextListener like follows:

public class MyServlet extends HttpServlet implements ServletContextListener {
    // ...
}

so that you can end up with the code you've posted (don't forget to import the particular interface and define your class as both servlet and listener in web.xml). But this is not always considered a good practice.

That said, you should be placing classes in a package to avoid portability problems. It may work in some environments, but not in other. Sun also discourages using packageless classes in non-prototyping environments. They can normally namely not be imported by other classes which are itself in a package.

BalusC
Yeah, sorry my bad. The context methods are indeed implemented by ServletContextListener interface. I have the Java version working so I know to do it. However, I'd like to get it working in Jython. I've updated my sample code with the interface included. PS: I understand packages, I'm trying to avoid verbose samples here.
Luke
Other thing, if you'd like to hook on servlet's init and destroy rather than webapp's startup and shutdown, then you should rather implement the `HttpServlet` API provided `init()` and `destroy()` methods.
BalusC
As I understand correctly the `init` method is only called the first time the servlet is triggered. I'd like my servlet to be initialized when the server is started.
Luke
You already did that by setting `<load-on-startup>` with a value higher than `0` :)
BalusC
No, PyServlet is the interpreter. It executes the Python scripts and is not my servlet. The problem is that the server doesn't understand what to do with JythonServlet1 (e.g. hand it to the interpreter). It thinks JythonServlet1 is a Java servlet, but its a Python script.
Luke
I initially meant the `JythonServlet`, it's also loaded on startup. But OK, I *think* I understand you. Go ahead with `ServletContextListener`.
BalusC
Thanks for your help so far. If only I could figure out how to make the JythonServlet1 to be executed on server start up time...
Luke