I'm working on a Jakarta EE project where I have a custom annotation and an associated interceptor. The annotation is used to execute some logic, and it works as expected as a standalone. However, I need to pass a runtime value (specifically, the result of userContext.getUserId()
) to the interceptor when the annotated method is invoked.
Here's a simplified version of my setup:
@Named
@ViewScoped
public class MyClass {
@Inject
private UserContext userContext;
@MyLog
public void myMethod() {
// Method logic
}
}
The @MyLog
annotation and the interceptor are defined in dependency A, which does not have access to dependency B, which provides the UserContext. MyClass however has both dependencies, A and B.
My questions are:
userContext.getUserId()
as a parameter to the annotation at runtime?I'm looking for a solution that fits well within the Jakarta EE framework. Any guidance or examples would be greatly appreciated!
I initially tried to pass the userContext.getUserId()
directly to the annotation like this:
@MyLog(userContext.getUserId())
public void myMethod() {
// Method logic
}
I was hoping this would allow the userContext.getUserId()
value to be passed as an annotation value and then used by the interceptor at runtime. However, I realized that annotations in Java can only accept constant values, so this approach didn't work.
Following Solution worked for my problem:
A Solution that worked for me was Implementing a ContextHolder in Dependency A.
@Named
@SessionScoped
public class MyContextHolder implements Serializable {
private static final long serialVersionUID = 2L;
private static final ThreadLocal<String> userIdHolder = new ThreadLocal<>();
public static void setUserId(final String userId) {
userIdHolder.set(userId);
}
public static String getUserId() {
return userIdHolder.get();
}
}
Aditionally I created a new annotation @Contextualize
in the same Project as MyClass, which uses an interceptor to set the UserId in the ContextHolder (make sure that the @Contextualize0
Annotation has a higher (lower number) priority than the @MyLog
Annotation).
public class MyClass {
@Contextualize
@MyLog
public void myMethod() {
// do Something
}
}