I have been using Tomcat 6.0.26-6.0.35 for several years with JSF 2 Mojarra, various versions up to 2.1.2 which I have been using for some months. I have several request-scoped
My guess is something is causing org.apache.catalina.core.DefaultInstanceManager to ignore annotations because faces requires the @PostConstruct method to be processed apart from @Resource fields. I have created a workaround that works for fields annotated with @Resource.
Add the following to web.xml:
com.sun.faces.injectionProvider
com.example.faces.Tomcat7InjectionProvider
And add the class to your source:
package com.example.faces;
import java.lang.reflect.Field;
import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import org.apache.catalina.util.Introspection;
import com.sun.faces.spi.InjectionProviderException;
import com.sun.faces.vendor.WebContainerInjectionProvider;
public class Tomcat7InjectionProvider extends WebContainerInjectionProvider {
public Tomcat7InjectionProvider(ServletContext servletContext) {
}
@Override
public void inject(Object managedBean) throws InjectionProviderException {
if (managedBean != null) {
// see org.apache.catalina.core.DefaultInstanceManager
Field[] fields = Introspection.getDeclaredFields(managedBean.getClass());
for (Field field : fields) {
// field may be private
field.setAccessible(true);
if (field.isAnnotationPresent(Resource.class)) {
Resource annotation = null;
try {
annotation = field.getAnnotation(Resource.class);
Context ctx = new InitialContext();
Object resource = ctx.lookup("java:comp/env/" + annotation.name());
field.set(managedBean, resource);
} catch (Exception e) {
throw new InjectionProviderException("cannot find resource " + annotation.name(), e);
}
}
}
}
}
}