Apologies for the delay, it seems this list takes a couple of days
sometimes to process my messages.
On Sat, 19 Feb 2000, Ernie Varitimos wrote [on servlet casting]:
> This is the method as described in the Sun Java documentation and tutorials. I
> think if more people on this board took the time to digest these documents, then
> these topics wouldn't be such a mistery. I don't understand where you get the
> notion that casting a servlet is any different than casting any other kind of java
> type. What possible "legitimate reason" might casting fail because it's a servlet?
> Servlets are fundamentally no different that any other type of Java class.
I am not related to Jason Hunter or his bank account by any means <grin>
but I do find his explanation quite clear, hence I quote (pp. 338-339):
"Casting the Servlet object returned by getServlet() or getServlets() to
its specific subclass can, in some situations, throw a ClassCastException.
For example, the following code sometimes works as expected and sometimes
throws an exception:
MyServlet servlet = (MyServlet) getServletContext().getServlet("MyServlet") ;
The reason has to do with how a servlet can be automatically reloaded when
its class file changes. As we explained in Chapter 3, The Servlet Life
Cycle, a server uses a new ClassLoader each time it reloads a servlet.
This has the interesting side effect that, when the MyServlet class is
reloaded, it is actually a different version of MyServlet than the version
used by other classes. Thus, although the returned class type is MyServlet
and it's being cast to the type MyServlet, the cast is between different
types (from two different class loaders) and the cast has to throw a
ClassCastException. The same type mismatch can occur if the class
performing the cast (that is, the servlet containing the above code) is
reloaded. Why? Because its new ClassLoader won't find MyServlet using the
primordial class loader and will load its own copy of MyServlet."
<OK, I admit, I scanned and OCRed this, but it was for educational
reasons:->
I think that in view of the above you would agree that casting a servlet
IS NOT like casting any other class, and the legitimate reasons I
mentioned are indeed legitimate whether the methods are sanctioned by Sun
or not. Jason suggests three workarounds for the above problem, last of
which is the interface solution I mentioned. I am afraid that the
.setAttribute() approach would run the same casting 'danger' like above.
I do not see why your 'this' which is referred to by the attribute won't
be different if the servlet is reloaded and the init() runs again.
Deprecating getServlet() means you are left to do your own
context-managing. That's quite honest on the part of Sun, albeit a bit
delayed. However, as I am not versed in the intrinsics of distributed
context creation I am left with the naive question: Since some 'entity' in
my servlet-system will know which servlet is loaded where, otherwise the
system wouldn't work, why shouldn't I get access to this information, even
under prvillege, through a method?
Kostas
> The reason getServlet() was deprecated, as well as the SessionContext was for
> security reasons (so that scope is protected). So the method I described is THE
> legitimate, fully sanctioned by Sun, method of servlet communication.
>
> -ernie
>
> "K.V. Chandrinos" wrote:
>
> > I am in doubt if both these techniques are GUARANTEED to work because they
> > involve servlet casting. Unless the point raised for example by Jason
> > Hunter in his book is false, this casting might fail for quite legitimate
> > reasons. Am I right? Or does this set/getAttribute() methodology mimicks
> > an interface implementation, hence by-passing the problem?
[two methods presented for getting a servlet. They both involve casting:]
> > >
> > > servletobj s = (servletobj)getServletContext().getServlet("servletobj");
> > > String foo = s.someMethod().toString();
> > >
> > > public void init(ServletConfig cfg) throws ServletException
> > > {
> > > super.init(cfg);
> > > // Add this servlet to the context
> > > getServletContext().setAttribute("callableServlet", this);
> > > }
> > > Then put this in the calling servlet:
> > > CallableServlet cs =
> > > (CallableServlet)getServletContext().getAttribute("callableServlet");
> > > Now you can use the reference "cs" to invoke methods in the callable
> > > servlet.
> > > -ernie
___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".
Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html