gpt4 book ai didi

java - @Resource 注释在 Tomcat 10.0.10 中不起作用

转载 作者:行者123 更新时间:2023-12-04 11:29:11 24 4
gpt4 key购买 nike

最近我尝试了 Tomcat 10.0.10,当尝试将连接池作为 JNDI 资源注入(inject)时,发现 @Resource注释不起作用。
然后我尝试通过创建 InitialContext 以编程方式获取它它奏效了。最初我认为它只适用于 java:comp/env/jdbc 所以我尝试了一个像下面这样的简单 bean 并尝试用 @Resource 注入(inject)它注释它再次不起作用。当我尝试通过创建 InitialContext 以编程方式获取它时它有效。然后我检查是否@PostConstruct@PreDestroy注释有效,发现它们也不起作用。

package lk.ijse.test.tomcatdbcp;

public class Something {
}
<?xml version="1.0" encoding="UTF-8"?>
<Context>

<Resource name="bean/Something" auth="Container"
type="lk.ijse.test.tomcatdbcp.Something"
factory="org.apache.naming.factory.BeanFactory"
/>

</Context>
<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="false" xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">

<resource-env-ref>
<resource-env-ref-name>bean/Something</resource-env-ref-name>
<resource-env-ref-type>lk.ijse.test.tomcatdbcp.Something</resource-env-ref-type>
</resource-env-ref>
</web-app>
package lk.ijse.test.tomcatdbcp;

import java.io.*;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;

import javax.naming.InitialContext;
import javax.naming.NamingException;

@WebServlet(name = "helloServlet", value = "/hello", loadOnStartup = 1)
public class HelloServlet extends HttpServlet {
private String message;

@Resource(name= "java:comp/env/bean/Something")
private Something something;

@PostConstruct
public void doSomething(){
System.out.println("Does it work?");
}

public void init() {
message = "Hello World!";
try {
InitialContext ctx = new InitialContext();
Something lookup = (Something) ctx.lookup("java:comp/env/bean/Something");
System.out.println(lookup);
System.out.println(something); // null
} catch (NamingException e) {
e.printStackTrace();
}
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");

// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}

public void destroy() {
}
}
为了重现同样的问题,我在这里创建了一个示例存储库: https://github.com/sura-boy-playground/play-with-tomcat10
(完整的代码可以在那里找到)
起初,我用过 javax.annotation.Resource注释,所以我认为这是因为 javax.* 的原因至 jakarta.*命名空间更改。然后我用 jakarta.annotation.Resource 试了一下但结果是一样的。
我在 Tomcat 9.0.41 plus javax.* 上尝试了相同的应用程序命名空间,它完美地工作。
我需要在 Tomcat 10.0.10 上做任何额外的事情来启用这些注释吗? 我挖掘了 Tomcat 10 文档,但找不到与我的问题相关的任何内容。
我发现以前在 Tomcat 7 中有类似的情况,但我现在不喜欢这种解决方法。
Tomcat @Resource annotations API annotation stops working in Tomcat 7

最佳答案

您应该声明您的 jakarta.annotation 的范围依赖为 provided :

<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
如果您有两份 jakarta.annotation.Resource (一个在公共(public)类加载器中,一个在应用程序的类加载器中),这两个类是不同的。 InstanceManager将查找用公共(public)类加载器的副本 @Resource 注释的字段, 而 something字段用您的 web 应用程序的副本 @Resource 进行注释.
同时添加 jakarta.annotation范围不同于 provided肯定是一个错误,这可能是一个常见的错误,Tomcat 有一个故障安全功能,它会忽略与您的应用程序一起分发的某些类(参见 source code)。自 jakarta.annotation.*类不在其中,您可以提交(愿望 list )错误报告。
备注 : 如果您使用 Java 11 或更高版本,您将在 Tomcat 9.0 中遇到同样的问题。在 Java 11 之前 javax.annotation.* JRE 中包含的类。 Servlet 容器需要在 bootstrap/JRE 类加载器中查找 之前 查看 webapp 类加载器(覆盖 javax.* 类违反了 Java 的许可证),因此 Tomcat 永远不会找到这些类的附加副本。

关于java - @Resource 注释在 Tomcat 10.0.10 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69249988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com