Re: AsyncListeners and resource injection

2010-09-16 Thread David Jencks

On Sep 15, 2010, at 10:51 PM, David Jencks wrote:

 
 On Sep 15, 2010, at 9:58 PM, David Jencks wrote:
 
 I think this is how AsyncContextImpl creates async listeners (lines 228ff)
 
   @Override
   public T extends AsyncListener T createListener(ClassT clazz)
   throws ServletException {
   T listener = null;
   try {
listener = clazz.newInstance();
   } catch (InstantiationException e) {
   ServletException se = new ServletException(e);
   throw se;
   } catch (IllegalAccessException e) {
   ServletException se = new ServletException(e);
   throw se;
   }
   return listener;
   }
 
 
 
 but the 3.0 spec section 15.5 page 179 says
 
 Annotations must be supported on the following container managed classes 
 that implement the following interfaces and are declared in the web 
 application deployment descriptor or using the annotations defined in 
 Section 8.1, “Annotations and pluggability” on page 8-61 or added 
 programmatically.
 
 and includes AsyncListener in the table following.  
 
 So shouldn't this be using the instance manager to create the instance so 
 the resource injection machinery can do its stuff?
 
 
 Secondly, if you do try to register an AsyncListener with  the 
 ServletContext so it can be scanned for annotations, aside from not actually 
 scanning it, it quickly gets to this code (ApplicationContext lines 1262 ff)
 
   @Override
   public T extends EventListener void addListener(T t) {
   if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
   throw new IllegalStateException(
   sm.getString(applicationContext.addListener.ise,
   getContextPath()));
   }
 
   // TODO SERVLET3
   // throw UnsupportedOperationException - if this context was passed to 
 the
   // {...@link 
 ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)}
   // method of a {...@link ServletContextListener} that was not declared
   // in web.xml, a web-fragment or annotated with {...@link WebListener}.
 
   boolean match = false;
   if (t instanceof ServletContextAttributeListener ||
   t instanceof ServletRequestListener ||
   t instanceof ServletRequestAttributeListener ||
   t instanceof HttpSessionAttributeListener) {
   context.addApplicationEventListener(t);
   match = true;
   }
 
   if (t instanceof HttpSessionListener
   || (t instanceof ServletContextListener 
   newServletContextListenerAllowed)) {
   context.addApplicationLifecycleListener(t);
   match = true;
   }
 
   if (match) return;
 
   throw new IllegalArgumentException(sm.getString(
   applicationContext.addListener.iae.wrongType,
   t.getClass().getName()));
 
   }
 
 
 which doesn't accept AsyncListeners.  (of course it shouldn't do anything 
 with then).
 
 Thoughts?
 
 thanks
 david jencks
 
 
 BTW I opened bug 49937 with  fixes that work for me for these problems.
 
 david jencks
 

The situation seems to be more complicated than I thought at first.

As noted above, section 15.5 clearly indicates annotation based resource 
injection is supported for all servlet related listeners including 
AsyncListener, and that these can be specified in the xml deployment 
descriptor, via annotation, or by adding programatically.

However 

4.4.3 indicates that an AsyncListener cannot be added programatically

4.4.3.5 indicates that resource injection is not supported for listeners added 
programatically unless the listener is a managed bean.  I think this directly 
contradicts 15.5.

8.1.4 indicates that an AsyncListener cannot be annotated with @WebListener

11.3.2 says

Listener classes are declared in the Web application deployment descriptor 
using the listener element. They are listed by class name in the order in which 
they are to be invoked. Unlike other listeners, listeners of type AsyncListener 
may only be registered (with a ServletRequest) programmatically.

I can't figure out what this is supposed to mean.  It might mean that you 
aren't allowed to list an AsyncListener in your web.xml, or it might mean that 
you can, but to use it you have to explicitly add it to an AsyncContext.

Despite the contradictions in the spec, it seems pretty clear that an 
asyncListener can be a managed bean and thus be subject to resource injection.  
It might also be possible for it to be listed in web.xml, have a @WebListener 
annotation, and be added programatically so it can be scanned for normal ee 
resource injection annotations (depending on how much weight you put on 15.5 
compared with the other sections).  So, I think that the 
AsyncContext.createListener method should use the instance manager in any case. 
 I think it makes sense to relax the restrictions on @WebListener and 
programatically adding AsyncListeners 

AsyncListeners and resource injection

2010-09-15 Thread David Jencks
I think this is how AsyncContextImpl creates async listeners (lines 228ff)

@Override
public T extends AsyncListener T createListener(ClassT clazz)
throws ServletException {
T listener = null;
try {
 listener = clazz.newInstance();
} catch (InstantiationException e) {
ServletException se = new ServletException(e);
throw se;
} catch (IllegalAccessException e) {
ServletException se = new ServletException(e);
throw se;
}
return listener;
}



but the 3.0 spec section 15.5 page 179 says

Annotations must be supported on the following container managed classes that 
implement the following interfaces and are declared in the web application 
deployment descriptor or using the annotations defined in Section 8.1, 
“Annotations and pluggability” on page 8-61 or added programmatically.

and includes AsyncListener in the table following.  

So shouldn't this be using the instance manager to create the instance so the 
resource injection machinery can do its stuff?


Secondly, if you do try to register an AsyncListener with  the ServletContext 
so it can be scanned for annotations, aside from not actually scanning it, it 
quickly gets to this code (ApplicationContext lines 1262 ff)

@Override
public T extends EventListener void addListener(T t) {
if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
throw new IllegalStateException(
sm.getString(applicationContext.addListener.ise,
getContextPath()));
}

// TODO SERVLET3
// throw UnsupportedOperationException - if this context was passed to 
the
// {...@link 
ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)}
// method of a {...@link ServletContextListener} that was not declared
// in web.xml, a web-fragment or annotated with {...@link WebListener}.

boolean match = false;
if (t instanceof ServletContextAttributeListener ||
t instanceof ServletRequestListener ||
t instanceof ServletRequestAttributeListener ||
t instanceof HttpSessionAttributeListener) {
context.addApplicationEventListener(t);
match = true;
}

if (t instanceof HttpSessionListener
|| (t instanceof ServletContextListener 
newServletContextListenerAllowed)) {
context.addApplicationLifecycleListener(t);
match = true;
}

if (match) return;

throw new IllegalArgumentException(sm.getString(
applicationContext.addListener.iae.wrongType,
t.getClass().getName()));

}


which doesn't accept AsyncListeners.  (of course it shouldn't do anything with 
them).

Thoughts?

thanks
david jencks


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: AsyncListeners and resource injection

2010-09-15 Thread David Jencks

On Sep 15, 2010, at 9:58 PM, David Jencks wrote:

 I think this is how AsyncContextImpl creates async listeners (lines 228ff)
 
@Override
public T extends AsyncListener T createListener(ClassT clazz)
throws ServletException {
T listener = null;
try {
 listener = clazz.newInstance();
} catch (InstantiationException e) {
ServletException se = new ServletException(e);
throw se;
} catch (IllegalAccessException e) {
ServletException se = new ServletException(e);
throw se;
}
return listener;
}
 
 
 
 but the 3.0 spec section 15.5 page 179 says
 
 Annotations must be supported on the following container managed classes that 
 implement the following interfaces and are declared in the web application 
 deployment descriptor or using the annotations defined in Section 8.1, 
 “Annotations and pluggability” on page 8-61 or added programmatically.
 
 and includes AsyncListener in the table following.  
 
 So shouldn't this be using the instance manager to create the instance so the 
 resource injection machinery can do its stuff?
 
 
 Secondly, if you do try to register an AsyncListener with  the ServletContext 
 so it can be scanned for annotations, aside from not actually scanning it, it 
 quickly gets to this code (ApplicationContext lines 1262 ff)
 
@Override
public T extends EventListener void addListener(T t) {
if (!context.getState().equals(LifecycleState.STARTING_PREP)) {
throw new IllegalStateException(
sm.getString(applicationContext.addListener.ise,
getContextPath()));
}
 
// TODO SERVLET3
// throw UnsupportedOperationException - if this context was passed to 
 the
// {...@link 
 ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)}
// method of a {...@link ServletContextListener} that was not declared
// in web.xml, a web-fragment or annotated with {...@link WebListener}.
 
boolean match = false;
if (t instanceof ServletContextAttributeListener ||
t instanceof ServletRequestListener ||
t instanceof ServletRequestAttributeListener ||
t instanceof HttpSessionAttributeListener) {
context.addApplicationEventListener(t);
match = true;
}
 
if (t instanceof HttpSessionListener
|| (t instanceof ServletContextListener 
newServletContextListenerAllowed)) {
context.addApplicationLifecycleListener(t);
match = true;
}
 
if (match) return;
 
throw new IllegalArgumentException(sm.getString(
applicationContext.addListener.iae.wrongType,
t.getClass().getName()));
 
}
 
 
 which doesn't accept AsyncListeners.  (of course it shouldn't do anything 
 with then).
 
 Thoughts?
 
 thanks
 david jencks
 

BTW I opened bug 49937 with  fixes that work for me for these problems.

david jencks


 
 -
 To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: dev-h...@tomcat.apache.org
 


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org