myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Scott O'Bryan <darkar...@gmail.com>
Subject Re: [MyFaces 2.0] how to handle _SystemEventServletRequest and _SystemEventServletResponse classes (attn:Werner)
Date Wed, 02 Dec 2009 06:29:09 GMT
I don't know why you couldn't just pass the proxy, and just throw  
IllegalOperationExceptions for unrecognized methods.  But this one may  
be a bit cleaner.  Don't know.

Sent from my iPhone

On Dec 1, 2009, at 6:21 PM, Bernhard Huemer  
<bernhard.huemer@gmail.com> wrote:

> 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