myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bernhard Huemer <bernhard.hue...@gmail.com>
Subject Re: [MyFaces 2.0] how to handle _SystemEventServletRequest and _SystemEventServletResponse classes (attn:Werner)
Date Wed, 02 Dec 2009 01:21:04 GMT
Hello,

regarding the 1st solution:
According to the JavaDocs the ServletRequestWrapper throws an 
IllegalArgumentException if you pass "null" as delegate, so this won't 
work (I'll come back to that later though). However, given that you're 
worried about NullPointerExceptions in case someone calls methods that 
have been introduced in the Servlet 3.0 version release, I assume that 
MyFaces isn't really concerned about those methods anyway. Otherwise 
you'd probably override those methods? If I'm mistaken, please correct 
me as some suggestions later on rely on this assumption.

regarding the 2nd solution:
Just ignoring the @Override annotation won't work as the respective 
interfaces introduce dependencies to artifacts that are only available 
in a Servlet 3.0 environment (for example, there's the startAsync() 
method that returns an AsyncContext). If a class loader were to load 
your request / response dummy class, he would now also have to load the 
class AsyncContext as it's a dependency of your class itself, which 
apparently the class loader cannot do in a Servlet 2.5 environment.

Given that I'd say you'll have to create two different dummy 
implementations, one that implements the Servlet 2.5 ServletRequest 
interface and one that implements the Servlet 3.0 ServletRequest (i.e. 
the only thing that changes is the set of methods you have to 
implement). However, now another problem arises as you can't just use 
two different versions of the same API in a single build, i.e. there's 
no way to tell the compiler that one class just implements the methods 
in the Servlet 2.5 version whereas another class has to implement the 
methods of the Servlet 3.0 version. Both versions have to be compilable 
using the same Servlet API version and as the Servlet 2.5 API is just a 
subset of the Servlet 3.0 API, both versions have to be compilable using 
the Servlet 3.0 version.

The big issue now is that we've got a contradiction now. If we want to 
support a Servlet 3.0 environment, we'll have to use this version in our 
build (again, Servlet 3.0 is if I'm not mistaken a superset of Servlet 
2.5, that's the reason for that). However, the 2.5 version of the dummy 
class cannot compile if one uses the 3.0 version for the actual build. 
Maybe that sounds a little bit strange up until now, but hopefully now 
it will get clearer: A 2.5 compatible implementation of the 
ServletRequest interface must not implement the method "startAsync" as 
it introduces an unsatisfiable dependency, but a 3.0 compatible build 
environment requires any implementation to implement the method 
"startAsync" (amongs others) as it is a part of the interface after all.

Hence I'm afraid but this solution just won't work either. Of course, 
the third solution would probably work, but why bother about the 
performance implications if there's another solution? :-)

I think the preferable solution is actually the first one. It's easy to 
  implement as we don't have to deal with the difference between the 
Servlet 2.5 API and Servlet 3.0 API, but as I've already mentioned there 
is the IllegalArgumentException issue that you just can't ignore either. 
We just want to get rid of the null value somehow, so why not use a 
dummy proxy instead? Note that there are no performance implications if 
you override the wrapped methods anyway, i.e. in fact, the proxy won't 
be called even once. It's sole purpose is to replace the "null", that's 
it. It could look like the following:

///

public class DummyServletRequest extends ServletRequestWrapper {

   public DummyServletRequest() {
     super(Proxy.newProxyInstance(
       DummyServletRequest.class.getClassLoader(),
       new Class[] { ServletRequest.class },
       new InvocationHandler() {
         public Object invoke(Object proxy, Method m, Object[] args) {
           throw new UnsupportedOperationException(...);
         }
       }
     );
   }

   // --------- "Implement" the interface ServletRequest now!

   public Object getAttribute(String name) {
     // ...
   }

   // ...

}

\\\

Hope that helps. :-)

regards,
Bernhard Huemer

On 12/01/2009 09:48PM GMT, Michael Concini wrote:
> I need some help with the best way to handle updating the dummy 
> request/response objects that we use for system event listeners kicked 
> off when there isn't a request context.  Currently, we're implementing 
> ServletRequest and ServletResponse directly.  This is broken when using 
> a servlet 3.0 runtime though since we're not implementing the new 
> methods added by the servlet 3.0 spec.
> I tried already updating the classes to extend the request/response 
> wrapper classes, but that turned out to be problematic since the 
> constructor requires a request/response object to be passed.  Since we 
> don't have access to that as we're outside of a request I hit an NPE try 
> to use FacesContext that wasn't there.
> I've come up with a couple of potential solutions on this and would like 
> some input as to the best way to go.
> 
> 1) We could also extend the wrapper classes, but add a no-arg 
> constructor to the dummy classes that would just call super(null).  This 
> would be fine in most cases, but if an application tried to call any of 
> the new ServletContext methods from Servlet 3.0 we'd get an NPE instead 
> of a runtime exception (not ideal)
> 
> 2) We can simply add the new methods from the Servlet 3.0 API to our 
> dummy classes.  I think as long as we don't include the @Override 
> annotation it should build and run in either a 2.5 or 3.0 environment.
> 3) We could implement a dynamic proxy to handle the calls.  Would be a 
> little more complex to implement, but might be the most elegant 
> solution.  Not fully sure if there are performance implications here 
> though.
> Personally, I'd lean towards (2), I'd like to here from Werner as well 
> since he was the one that initially implemented this.  Any additional 
> feedback from others in the community is of course welcome.
> 
> Thanks,
> Mike
> 


Mime
View raw message