You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Tony LaPaso <to...@absolutejava.com> on 2002/07/18 02:53:25 UTC

??? Tomcat Bug? -- Throws NullPointerException ???

Hello,

I was hoping somebody could run this on a non-Tomcat server. I've
used TC v4.0.4 and v4.1.7 and both result in NPEs being thrown
when I call getServletContext() from within the readObject()
method of an inner class. Below is a very simple servlet that
shows the problem.

As you can see, the init() method is able to call
getServletContext() with no problem. BUT, when init() tries to
de-serialize an object which is an inner class, the object's
readObject() method cannot call getServletContext().

I'm not looking for "work-arounds" -- I just want to know if this
is a Tomcat bug.






import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
   public void doGet(HttpServletRequest request,
                     HttpServletResponse response)
                     throws ServletException, IOException {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      out.write("<html><head><title>Hello</title></head><body>");
      out.println("Hello there....</body</html>");
   } // doGet()

   private class Inner implements Serializable {
      private Inner() {}

      private void readObject(ObjectInputStream ois)
                              throws Exception {
         System.out.println("In Inner.readObject()...");
         ois.defaultReadObject();
         System.out.println("defaultReadObject completed...");
         ServletContext sc = getServletContext();  // BOOM!!
         System.out.println("Got the servlet context!!!");
      } // readObject()
   } // Inner

   public void init() {
      try {
         System.out.println("The servlet context is: " +
getServletContext());
         ByteArrayOutputStream baos = new
ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos);
         oos.writeObject(new Inner());
         oos.close();

         // Now, deserialize it....
         ObjectInputStream ois = new ObjectInputStream(new
ByteArrayInputStream(baos.toByteArray()));
         Inner inner = (Inner)ois.readObject();
         System.out.println("Got the inner object...");
      } catch(IOException e) {
         System.err.println("Got an exception in init()..." + e);
         e.printStackTrace();
      } catch(ClassNotFoundException e) {
         System.err.println("Got an exception in init()..." + e);
         e.printStackTrace();
      }
   } // init()
} // HelloWorld



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


READ FIRST ??? Tomcat Bug? -- Throws NullPointerException ??? READ FIRST

Posted by Tony LaPaso <to...@absolutejava.com>.
Hi all,

You can disregard my message about Tomcat -- it's not a Tomcat
issue. It's a subtle serialization issue....

Thnaks


----- Original Message -----
From: "Tony LaPaso" <to...@absolutejava.com>
To: "Tomcat User" <to...@jakarta.apache.org>
Sent: Wednesday, July 17, 2002 7:53 PM
Subject: ??? Tomcat Bug? -- Throws NullPointerException ???


> Hello,
>
> I was hoping somebody could run this on a non-Tomcat server.
I've
> used TC v4.0.4 and v4.1.7 and both result in NPEs being thrown
> when I call getServletContext() from within the readObject()
> method of an inner class. Below is a very simple servlet that
> shows the problem.
>
> As you can see, the init() method is able to call
> getServletContext() with no problem. BUT, when init() tries to
> de-serialize an object which is an inner class, the object's
> readObject() method cannot call getServletContext().
>
> I'm not looking for "work-arounds" -- I just want to know if
this
> is a Tomcat bug.
>
>
>
>
>
>
> import java.io.*;
> import javax.servlet.*;
> import javax.servlet.http.*;
>
> public class HelloWorld extends HttpServlet {
>    public void doGet(HttpServletRequest request,
>                      HttpServletResponse response)
>                      throws ServletException, IOException {
>       response.setContentType("text/html");
>       PrintWriter out = response.getWriter();
>
out.write("<html><head><title>Hello</title></head><body>");
>       out.println("Hello there....</body</html>");
>    } // doGet()
>
>    private class Inner implements Serializable {
>       private Inner() {}
>
>       private void readObject(ObjectInputStream ois)
>                               throws Exception {
>          System.out.println("In Inner.readObject()...");
>          ois.defaultReadObject();
>          System.out.println("defaultReadObject completed...");
>          ServletContext sc = getServletContext();  // BOOM!!
>          System.out.println("Got the servlet context!!!");
>       } // readObject()
>    } // Inner
>
>    public void init() {
>       try {
>          System.out.println("The servlet context is: " +
> getServletContext());
>          ByteArrayOutputStream baos = new
> ByteArrayOutputStream();
>          ObjectOutputStream oos = new ObjectOutputStream(baos);
>          oos.writeObject(new Inner());
>          oos.close();
>
>          // Now, deserialize it....
>          ObjectInputStream ois = new ObjectInputStream(new
> ByteArrayInputStream(baos.toByteArray()));
>          Inner inner = (Inner)ois.readObject();
>          System.out.println("Got the inner object...");
>       } catch(IOException e) {
>          System.err.println("Got an exception in init()..." +
e);
>          e.printStackTrace();
>       } catch(ClassNotFoundException e) {
>          System.err.println("Got an exception in init()..." +
e);
>          e.printStackTrace();
>       }
>    } // init()
> } // HelloWorld
>
>
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Portabilty concern for getServletContext (was Re: ??? Tomcat Bug? -- Throws NullPointerException ???)

Posted by Will Hartung <wi...@msoft.com>.
From: "Tony LaPaso" <to...@absolutejava.com>
Sent: Wednesday, July 17, 2002 5:53 PM
Subject: ??? Tomcat Bug? -- Throws NullPointerException ???
> public class HelloWorld extends HttpServlet {
>    public void doGet(HttpServletRequest request,
>                      HttpServletResponse response)
>                      throws ServletException, IOException {
>       response.setContentType("text/html");
>       PrintWriter out = response.getWriter();
>       out.write("<html><head><title>Hello</title></head><body>");
>       out.println("Hello there....</body</html>");
>    } // doGet()
>
>    private class Inner implements Serializable {
>       private Inner() {}
>
>       private void readObject(ObjectInputStream ois)
>                               throws Exception {
>          System.out.println("In Inner.readObject()...");
>          ois.defaultReadObject();
>          System.out.println("defaultReadObject completed...");
>          ServletContext sc = getServletContext();  // BOOM!!
>          System.out.println("Got the servlet context!!!");
>       } // readObject()
>    } // Inner

I just wanted to point something out to folks out there using JSPs.

We are encountering this right now, and this sort of brings it to light.

In Tomcat 3.x (Not sure about TC 4), you have access to and can use
"getServletContext" within a JSP. No doubt this is because the actual JSP
servlet is descendant, or at least mimics the capabilities of
GenericServlet, which has "getServletContext" as a convenience method.

However, a key point to realize is that the Servlet INTERFACE (which is what
Servlets are required to implement), does NOT offer "getServletContext" as a
convenience method. So, using "getServletContext" from within a JSP is NOT
portable. This is a subtle thing.

Specifically, it is not portable to Weblogic.

Just a little FYI so you do not have to go back through all of the JSPs when
it comes time to port. It is quite a pain.


Something to be conscious of if you are trying to right portable code.

Regards,

Will Hartung
(willh@msoft.com)




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re[2]: ??? Tomcat Bug? -- Throws NullPointerException ???

Posted by Jacob Kjome <ho...@visi.com>.
Hello Tony,

Good to know.

Thanks.

Jake

Thursday, July 18, 2002, 12:38:51 AM, you wrote:

TL> Actually, you are wrong but your comments helped me find the
TL> general cause of the problem...it is not a bug in
TL> Tomcat...comments below....


TL> ----- Original Message -----
TL> From: "Jacob Kjome" <ho...@visi.com>



>> Just because you are creating an inner class within a servlet
TL> does not mean
>> that that inner class now gets access to the ServletConfig.

TL> Yes, I should have access to it -- inner classes have access to
TL> their parent's fields. In this case my inner class *should* have
TL> complete access to the ServletConfig object stored in
TL> GenericServlet.

TL> By the time my init() is called, the ServletConfig object has
TL> already beens set by GenericServlet.init(ServletConfig config).

TL> The problem is that the ServletConfig object in GenericServlet is
TL> transient. When I serialize the Inner object the following
TL> objects get serialized as well:

TL>   1. My Servlet
TL>   2. GenericServlet (contains the transient ServletConfig object)

TL> I have more investigation to do....



TL> --
TL> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
TL> For additional commands, e-mail: <ma...@jakarta.apache.org>



-- 
Best regards,
 Jacob                            mailto:hoju@visi.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ??? Tomcat Bug? -- Throws NullPointerException ???

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Thu, 18 Jul 2002, Tony LaPaso wrote:

> Date: Thu, 18 Jul 2002 00:38:51 -0500
> From: Tony LaPaso <to...@absolutejava.com>
> Reply-To: Tomcat Users List <to...@jakarta.apache.org>
> To: Tomcat Users List <to...@jakarta.apache.org>
> Subject: Re: ??? Tomcat Bug? -- Throws NullPointerException ???
>
> Actually, you are wrong but your comments helped me find the
> general cause of the problem...it is not a bug in
> Tomcat...comments below....
>
>
> ----- Original Message -----
> From: "Jacob Kjome" <ho...@visi.com>
>
>
>
> > Just because you are creating an inner class within a servlet
> does not mean
> > that that inner class now gets access to the ServletConfig.
>
> Yes, I should have access to it -- inner classes have access to
> their parent's fields. In this case my inner class *should* have
> complete access to the ServletConfig object stored in
> GenericServlet.
>
> By the time my init() is called, the ServletConfig object has
> already beens set by GenericServlet.init(ServletConfig config).
>
> The problem is that the ServletConfig object in GenericServlet is
> transient. When I serialize the Inner object the following
> objects get serialized as well:
>
>   1. My Servlet
>   2. GenericServlet (contains the transient ServletConfig object)
>
> I have more investigation to do....
>

Wouldn't it be just as easy to pass the ServletConfig object to the
contructor for your inner class?  Serializing and deserializing Servlet
classes is not going to be of much use.

Craig


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ??? Tomcat Bug? -- Throws NullPointerException ???

Posted by Tony LaPaso <to...@absolutejava.com>.
Actually, you are wrong but your comments helped me find the
general cause of the problem...it is not a bug in
Tomcat...comments below....


----- Original Message -----
From: "Jacob Kjome" <ho...@visi.com>



> Just because you are creating an inner class within a servlet
does not mean
> that that inner class now gets access to the ServletConfig.

Yes, I should have access to it -- inner classes have access to
their parent's fields. In this case my inner class *should* have
complete access to the ServletConfig object stored in
GenericServlet.

By the time my init() is called, the ServletConfig object has
already beens set by GenericServlet.init(ServletConfig config).

The problem is that the ServletConfig object in GenericServlet is
transient. When I serialize the Inner object the following
objects get serialized as well:

  1. My Servlet
  2. GenericServlet (contains the transient ServletConfig object)

I have more investigation to do....



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: ??? Tomcat Bug? -- Throws NullPointerException ???

Posted by Jacob Kjome <ho...@visi.com>.
Just because you are creating an inner class within a servlet does not mean 
that that inner class now gets access to the ServletConfig.   That is what 
is happening when you call getServletContext() from the init() method.  You 
are implicitly saying config.getServletContext (where config is the current 
ServletConfig object).

If you pass in the ServletConfig object, you will be able to use it and not 
go "boom"

  private void readObject(ObjectInputStream ois, ServletConfig config) .....

call that from the init() by doing:

Inner inner = (Inner)ois.readObject(this);

BTW, I don't understand how you have the method defined as:
  private void readObject(ObjectInputStream ois)
but then you access it like:
Inner inner = (Inner)ois.readObject();

readObject() doesn't exist, but readObject(ObjectInputStream) does.

I'm probably just missing something.

Anyway, you have to pass the implicit "this" config object in there or you 
won't have access to the ServletConfig object.


Jake

At 07:53 PM 7/17/2002 -0500, you wrote:
>Hello,
>
>I was hoping somebody could run this on a non-Tomcat server. I've
>used TC v4.0.4 and v4.1.7 and both result in NPEs being thrown
>when I call getServletContext() from within the readObject()
>method of an inner class. Below is a very simple servlet that
>shows the problem.
>
>As you can see, the init() method is able to call
>getServletContext() with no problem. BUT, when init() tries to
>de-serialize an object which is an inner class, the object's
>readObject() method cannot call getServletContext().
>
>I'm not looking for "work-arounds" -- I just want to know if this
>is a Tomcat bug.
>
>
>
>
>
>
>import java.io.*;
>import javax.servlet.*;
>import javax.servlet.http.*;
>
>public class HelloWorld extends HttpServlet {
>    public void doGet(HttpServletRequest request,
>                      HttpServletResponse response)
>                      throws ServletException, IOException {
>       response.setContentType("text/html");
>       PrintWriter out = response.getWriter();
>       out.write("<html><head><title>Hello</title></head><body>");
>       out.println("Hello there....</body</html>");
>    } // doGet()
>
>    private class Inner implements Serializable {
>       private Inner() {}
>
>       private void readObject(ObjectInputStream ois)
>                               throws Exception {
>          System.out.println("In Inner.readObject()...");
>          ois.defaultReadObject();
>          System.out.println("defaultReadObject completed...");
>          ServletContext sc = getServletContext();  // BOOM!!
>          System.out.println("Got the servlet context!!!");
>       } // readObject()
>    } // Inner
>
>    public void init() {
>       try {
>          System.out.println("The servlet context is: " +
>getServletContext());
>          ByteArrayOutputStream baos = new
>ByteArrayOutputStream();
>          ObjectOutputStream oos = new ObjectOutputStream(baos);
>          oos.writeObject(new Inner());
>          oos.close();
>
>          // Now, deserialize it....
>          ObjectInputStream ois = new ObjectInputStream(new
>ByteArrayInputStream(baos.toByteArray()));
>          Inner inner = (Inner)ois.readObject();
>          System.out.println("Got the inner object...");
>       } catch(IOException e) {
>          System.err.println("Got an exception in init()..." + e);
>          e.printStackTrace();
>       } catch(ClassNotFoundException e) {
>          System.err.println("Got an exception in init()..." + e);
>          e.printStackTrace();
>       }
>    } // init()
>} // HelloWorld
>
>
>
>--
>To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>