I have a Jersey Rest API and Weld Dependency Injection set up.
The REST endpoint class looks as follows:
@Path("/userAPI")
public class UserAPI {
@Inject
private UserDAO userDAO;
@GET
@Path("/{userId}")
public Response getUser(@PathParam("userId") String userId) {
User targetUser = userDAO.getUser(userId);
//...
}
}
The UserDAO
that I want to inject is below:
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class UserDAO {
private static final Logger logger = Logger.getLogger(UserDAO.class.getName());
private String creationDate = LocalDateTime.now().toString();
public UserDAO() {
logger.info(creationDate + "> Instance of UserDAO created: " + this.getClass().getName());
}
public User getUser(String userID) {
return new User("Hello", "World");
}
}
Now, when I run the application in Tomcat 9 and send one requests to the userAPI
endpoint, I get the following log outputs:
com.my.project.dao.UserDAO <init>
2024-07-02T15:58:56.782817700> Instance of UserDAO created: com.my.project.dao.UserDAO
com.my.project.dao.UserDAO <init>
2024-07-02T15:58:56.882009> Instance of UserDAO created: com.my.project.dao.UserDAO$Proxy$_$$_WeldClientProxy
com.my.project.dao.UserDAO <init>
2024-07-02T15:58:56.941968900> Instance of UserDAO created: com.my.project.dao.UserDAO
com.my.project.dao.UserDAO <init>
2024-07-02T16:13:54.397002400> Instance of UserDAO created: com.my.project.dao.UserDAO
I know that Weld uses a Client Proxy and thus it’s perfectly normal that the constructor of the class annotated with @ApplicationScoped
is executed multiple times. Behind the proxies, there still should be one single instance of the class.
However, this seems not to work according to the logs. Each subsequent time, I get a new UserDAO
instance with a fresh creationDate
value. If the DI worked correctly, I would expect each subsequent call to return the same creationDate
value.
There are no errors occuring in the log file, and I think that I have all necessary dependencies set up in the build.gradle
file to enable CDI in Tomcat 9:
dependencies {
implementation group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.1.1'
// Jersey 2.41 (compatible with Tomcat 9)
implementation 'org.glassfish.jersey.core:jersey-server:2.41'
implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:2.41'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet:2.41'
implementation group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.41'
implementation group: 'org.glassfish.jersey.ext.cdi', name: 'jersey-cdi1x', version: '2.41'
// Weld
implementation group: 'org.jboss.weld.servlet', name: 'weld-servlet-shaded', version: '3.1.9.Final'
}
I added the necessary listener for Weld in my web.xml
:
<web-app>
<display-name>IAM2TC</display-name>
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
</web-app>
I added a beans.xml
file:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all">
</beans>
What could be the reason that there always is created a fresh instance of the UserDAO
?