EJBContext context = (EJBContext)new InitialContext().lookup("java:comp/EJBContext");
In OC4J 11 even this marginal piece of code won't be necessary as the EJBContext (and any other type of resource) can be injected directly into the interceptor.
Before I was made aware of the simpler solution above, I was resorting to using some reflection code to try and work out if there was an applicable way to get the EJBContext from the target bean. It uses first a direct field check and if that yields no results, it then looks for an accessible method that has returns an EJBContext class, or a derivative thereof.
// The EJBContext classes
final List
new Class[] {
javax.ejb.EJBContext.class,
javax.ejb.SessionContext.class });
/**
* Try and get the principal name from the target bean class
* @param target
* @return name of the principal
* @throws Exception
*/
String getPrincipalName(Object target) throws Exception {
String ret = getPrincipalNameFromField(target);
if(ret != null) {
return ret;
} else {
ret = getPrincipalNameFromMethod(target);
}
return(ret != null ? ret : "Ghost Rider");
}
private String getPrincipalNameFromField(Object target) throws Exception {
for(Field field : target.getClass().getFields()) {
if(contextClasses.contains(field.getType())) {
EJBContext ctx = (EJBContext)field.get(target);
return ctx.getCallerPrincipal().getName();
}
}
return null;
}
private String getPrincipalNameFromMethod(Object target) throws Exception {
Method[] methods = target.getClass().getMethods();
for (Method method: methods) {
if(contextClasses.contains(method.getReturnType())) {
EJBContext ret = (EJBContext)method.invoke(target, null);
return ret.getCallerPrincipal().getName();
}
}
return null;
}
This worked pretty well in my tests, but of course it needs the target bean class to be in a cooperative form -- the EJBontext either needs to be accessible as a public field, or there needs to be a public method to get the object from the target bean.
The JNDI lookup is easier and more reliable.
No comments:
Post a Comment