jsf - Tomcat @Resource 注释 API 注释在 Tomcat 7 中停止工作

标签 jsf tomcat annotations tomcat6 tomcat7

多年来,我一直在使用 Tomcat 6.0.26-6.0.35 和 JSF 2 Mojarra,各种版本一直到 2.1.2,我已经使用了几个月。我有几个请求范围和 session 范围的 bean,代码如下:

private @Resource(name="jdbc/cLabs", mappedName="jdbc/cLabs") DataSource cLabs;

它已正确注入(inject)我使用的每个版本的 Tomcat 6 中。我还有其他类型的 @Resource 也不起作用,所以它不仅仅是 DataSource 资源。 我试过切换到 Tomcat 7.0.27 并突然这些结构都不再起作用了。资源未注入(inject)。我还有其他类型的 @Resource 也不起作用,所以它不仅仅是 DataSource 资源。然而,在每种情况下,命名的资源确实存在,并且可以通过例如

new InitialContext().lookup("java:comp/env/jdbc/cLabs");

[它们由 context.xml 中的元素定义]

这当然是皇家 PITA,因为我在一两年前花了一些时间用前者替换了后者。我是否需要对 Tomcat 7 编织一些其他魔法才能使其再次运行?

请注意,资源正确地注入(inject)到 Servlet 中,因此它并没有完全损坏。 Tomcat 和 JSF 之间的一些交互。

最佳答案

我的猜测是某些原因导致 org.apache.catalina.core.DefaultInstanceManager 忽略注释,因为面部需要 @PostConstruct 方法来处理 @Resource 字段。我创建了一个解决方法,适用于使用 @Resource 注释的字段。

将以下内容添加到 web.xml 中:

<context-param>
    <param-name>com.sun.faces.injectionProvider</param-name>
    <param-value>com.example.faces.Tomcat7InjectionProvider</param-value>
</context-param>

并将该类添加到您的源中:

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);
                    }
                }
            }
        }
    }
}

关于jsf - Tomcat @Resource 注释 API 注释在 Tomcat 7 中停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10814557/

相关文章:

java - 如何在 java 中创建自定义注释?

java - 在ExternalContext中找不到pages/index.xhtml作为资源

java - 浏览器在后退按钮上注销

JSF 2 重用 JPA 实体中定义的验证?

java - JSF2 ArrayList 的搜索方法

java - 无需等待上传即可上传文件,并在同一页面上开始其他一些工作

java - 如何在 Linux 上使用 plesk 为基于服务的 tomcat 版本设置 JAVA_OPTS?

asp.net-mvc - View 无法访问模型 MVC

java - 在Tomcat上通过war部署源,更改html时必须重启服务器吗?

java - 如何告诉 Hibernate 注解 @Column 区分大小写?