Recently I tried Tomcat 10.0.10 and when trying to inject the connection pool as a JNDI resource find out that the @Resource annotation doesn't work.
Then I tried obtain it programmatically by creating a InitialContext and it worked. Initially I thought it was only for the java:comp/env/jdbc so I tried with a simple bean like below and tried to inject it with the @Resource annotation it didn't work again. When I try to obtain it programmatically by creating a InitialContext and it works. Then I check whether the @PostConstruct or @PreDestroy annotation works and found out that they also don't work.
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() {
}
}
To reproduce the same issue, I created a sample repo here: https://github.com/sura-boy-playground/play-with-tomcat10 (Complete code can be found there)
At first, I had used javax.annotation.Resource annotation, so I thought that was the reason because of the javax.* to jakarta.* namespace change. Then I tried it with jakarta.annotation.Resource but the result was same.
I tried the same application with Tomcat 9.0.41 plus javax.* namespace, it works perfectly.
Is there any extra stuff that I need to do on Tomcat 10.0.10 to enable these annotations? I dug the Tomcat 10 documentation but I wasn't able to find out any thing related to my issue.
I found out that there was a similar case in Tomcat 7 previously, but I don't like that kind of workaround now. Tomcat @Resource annotations API annotation stops working in Tomcat 7