Categorias
Java EE Programação

Weblogic 10.3.0.0 + JSF 2.0 + @EJB Injection

Ao 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<Class, List<EJBField>> ejbFields;

    public VariableResolver() {
        this.ejbFields = new HashMap<Class, List<EJBField>>();
        add(new ManagedBeanELResolver());
    }

    private void preencherEjbFields(List<EJBField> fields, Class clazz, Set<Class> 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<EJBField> fields = ejbFields.get(obj.getClass());

        if (fields == null) {
            fields = new ArrayList<EJBField>();
            Set<Class> 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>

11 respostas em “Weblogic 10.3.0.0 + JSF 2.0 + @EJB Injection”

Poderia me mandar o codigo ?
por email … os mesmo se encontram com erro e eu preciso mutio deste codigo….

Obrigado.

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… 😀

olá fabio boa tarde.
você poderia postar os imports
por que eu não entendi esse metodo ServiceLocator.lookup(field.getType(), field.getMappedName());

obrigado.

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

At this time it seems like Movable Type is the best blogging platform out there right
now. (from what I’ve read) Is that what you’re using on your blog?

Hola! Gracias por esta información. Llevaba un rato buscando por internet sobree este tema hasta el momento en que he
encontrado tu página. Está realmente bien el artículo.
Sigue de esta forma!

I’m curious to find out what blog system you are working
with? I’m experiencing some minor security issues
with my latest site and I’d like to find something more secure.
Do you have any solutions?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.