Weblogic 10.3.0.0 + JSF 2.0 + @EJB Injection
January 27, 2011 10:00 am Java EE, ProgramaçãoAo se colocar o JSF 2.0 no Weblogic 10.3.0.0, os EJB’s não são injetados nos manageds beans do JSF através da anotação @EJB.
Para corrigir esse problema, basta utilizar a classe abaixo:
import java.lang.reflect.Field;
import java.util.*;
import javax.ejb.EJB;
import javax.el.*;
import javax.naming.NamingException;
import com.sun.faces.el.ManagedBeanELResolver;
public class VariableResolver extends CompositeELResolver {
private final Map, List> ejbFields;
public VariableResolver() {
this.ejbFields = new HashMap, List>();
add(new ManagedBeanELResolver());
}
private void preencherEjbFields(List fields, Class clazz, Set> visitados) {
if (clazz != null && !visitados.contains(clazz)) {
visitados.add(clazz);
for (Field field : clazz.getDeclaredFields()) {
EJB ejb = field.getAnnotation(EJB.class);
if (ejb != null) {
field.setAccessible(true);
fields.add(new EJBField(field, ejb.mappedName(), field.getType()));
}
}
preencherEjbFields(fields, clazz.getSuperclass(), visitados);
for (Class i : clazz.getInterfaces()) {
preencherEjbFields(fields, i, visitados);
}
}
}
private List getEjbFields(Object obj) {
List fields = ejbFields.get(obj.getClass());
if (fields == null) {
fields = new ArrayList();
Set> visitados = new HashSet>();
preencherEjbFields(fields, obj.getClass(), visitados);
synchronized (ejbFields) {
ejbFields.put(obj.getClass(), fields);
}
}
return fields;
}
private void processarEjbs(Object obj) throws IllegalAccessException, ClassCastException, NamingException, IllegalArgumentException {
for (EJBField field : getEjbFields(obj)) {
if (field.getField().get(obj) == null) {
Object ejb = ServiceLocator.lookup(field.getType(), field.getMappedName());
field.getField().set(obj, ejb);
}
}
}
@Override
public Object getValue(ELContext arg0, Object arg1, Object arg2) {
try {
Object obj = super.getValue(arg0, arg1, arg2);
if (obj != null) {
processarEjbs(obj);
}
return obj;
} catch (IllegalArgumentException ex) {
throw new ELException(ex.getMessage(), ex);
} catch (IllegalAccessException ex) {
throw new ELException(ex.getMessage(), ex);
} catch (NamingException ex) {
throw new ELException(ex.getMessage(), ex);
}
}
private class EJBField {
private Field field;
private String mappedName;
private Class type;
public EJBField(Field field, String mappedName, Class type) {
this.field = field;
this.mappedName = mappedName;
this.type = type;
}
public Field getField() {
return field;
}
public String getMappedName() {
return mappedName;
}
public Class getType() {
return type;
}
}
}
E declarar o el-resolver no faces-config.xml:
<faces-config> <application> <el-resolver>VariableResolver</el-resolver> </application> </faces-config>
February 21st, 2011 at 14:29
Poderia me mandar o codigo ?
por email … os mesmo se encontram com erro e eu preciso mutio deste codigo….
Obrigado.
February 23rd, 2011 at 7:30
Olá,
Qual é o erro que você está tendo?
Abraços
February 23rd, 2011 at 17:53
Erro no blog…
Exemplo esta comendo as tags ..
EX:
private final Map, List> ejbFields;
Mais tudo bem eu dou uma estudada no codigo melhor … e que eu estava com um pouquinho de pressa. mais Obrigado assim mesmo…
May 26th, 2011 at 16:47
olá fabio boa tarde.
você poderia postar os imports
por que eu não entendi esse metodo ServiceLocator.lookup(field.getType(), field.getMappedName());
obrigado.
May 28th, 2011 at 9:26
Olá Wedenson,
O ServiceLocator.lookup faz basicamente o seguinte código:
javax.rmi.PortableRemoteObject.narrow(new javax.naming.InitialContext().lookup(field.getMappedName()), field.getType());
Abraços