Spring não reconhece EJB Stateless para injeção de dependência

8 respostas
spring
R

Saudações, meu caros.

Estou implementando uma solução de autenticação e autorização baseada no Spring Security num projeto feito com JEE.
Meu problema é o seguinte: Na classe AppUserDetailsService tenho uma injeção de dependência do meu repository, que é um EJB Stateless, porém, o spring não consegue fazer essa injeção e lança um NPE.

Classe AppUserDetailsService que é um bean do Spring

@Service
public class AppUserDetailsService implements UserDetailsService {

    @Inject
    Usuarios usuarios;

    @Override
    public UserDetails loadUserByUsername(String nome) throws UsernameNotFoundException {
        Usuario usuario = usuarios.findByUsername(nome);
        UsuarioSistema user = null;
        if (usuario != null) {
            user = new UsuarioSistema(usuario, getGrupos(usuario));
        }
        return user;
    }

    private Collection<? extends GrantedAuthority> getGrupos(Usuario usuario) {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();

        for (Grupo grupo : usuario.getGrupos()) {
            authorities.add(new SimpleGrantedAuthority(grupo.getNome().toUpperCase()));
        }

        return authorities;
    }

}

Meu EJB Stateless que representa meu Repositório de usuários

@Stateless
public class Usuarios{

    @PersistenceContext
    private EntityManager manager;

    private Usuarios usuarios;

    @Override
    public Usuario findByUsername(String username) {
        return manager.createQuery("from Usuario where nome = :nome", Usuario.class)
                .setParameter("nome", username).getSingleResult();
    }

}

A NPE é lançada na injeção do EJB dentro do Bean Spring.

Também tentei a abordagem de criar uma interface Usuarios e criar sua devida implementação como EJB. Feito isso, registrei o EJB criado por meio do JNDI no applicationContext do Spring, ficando da seguinte forma:

Bean Spring

@Service
public class AppUserDetailsService implements UserDetailsService {

    @Autowired
    Usuarios usuarios;
........
}

applicationContext.xml

<jee:local-slsb jndi-name="java:global/projeto-base/UsuariosImpl!br.com.raphaelneves.dao.Usuarios"
                    id="usuarios" business-interface="br.com.raphaelneves.dao.Usuarios" />

    <beans:bean id="usuariosImpl" class="br.com.raphaelneves.dao.UsuariosImpl">
        <beans:property name="usuarios" ref="usuarios" />
    </beans:bean>

Alguém poderia dar uma luz de como fazer o Spring reconhecer e injetar o EJB Stateless na implementação da UserDetailsService? :frowning:

8 Respostas

M

Bom dia, @raphaeloneves.

Eu estou enfrentando o mesmo problema que você descreveu.
Você encontrou alguma solução?

Obrigado

I

Sao contextos diferentes… Spring vai entender anotacoes/contextos Spring, e o mesmo pra EJBs

L

Em todos estes anos nessa indústria vital, eu nunca vi algo assim.
A ideia do EJB é justamente não precisar de coisas externas, como o Spring.
Até onde sei, um EJB só pode ser injetado em outro EJB, numa servlet ou num managed bean.
EJB tem como filosofia depender de implementação e ambiente de execução (application servers).
O Spring, por sua vez, foi desenvolvido para ser livre, independente de implementação ou ambiente de execução. Ele gerencia de uma forma específica seus beans, seria outra thread, para simplificar.

M

Valeu pela atenção.

Mas apenas para tentar deixar a discussão mais clara: a idéia é utilizar o Spring Security como framework de segurança em uma aplicação Java EE (JSF, JPA, EJB = @Stateless e @PersistenceContext para instanciar uma entity manager).

Obrigado

L

E por quê não JAAS?

M

Vou procurar um tópico que compare o JAAS e o Spring Security (ou Apache Shiro) para responder sua pergunta.

Valeu

R

Marcel, este link me ajudou.
Na documentação do Spring Security tem uma seção que fala dessa injeção tb. Caiu como uma luva pra mim.
A abordagem não é a mais bonita, mas resolveu.

No meu caso foi por familiaridade e falta de tempo pessoal e de projeto pra encarar uma curva de aprendizado mais extensa e complexa - no meu ponto de vista - que é a do JAAS. Além disso, tive dificuldade de encontrar material de referência do tipo “how to” e “from scratch”. Talvez o tempo de entrega fez com que eu entrasse no comodismo de entregar o que tinha mais facilidade e conhecimento.

Ainda neste viés, conhecem algum material de “fácil entendimento” que possibilite implementar o JAAS com roles dinâmicas?

M

@raphaeloneves, obrigado pela atenção.

Percebi que meu problema é diferente do problema que você enfrentou. Eu gostaria de utilizar Spring Security sem precisar do core Spring. O seu objeto é um bean do Spring e o meu não é.

A minha classe

@Named
public class UsuarioService implements UserDetailsService {

	@Inject
	UsuarioDAO usuarioDAO;
	
	@Override
	public UsuarioSpring loadUserByUsername(final String login) throws UsernameNotFoundException {
		return usuarioDAO.retornaUsuarioPeloLogin(login); 
	}	
}

O erro ocorre na injeção do UsuarioDAO que é um bean @Stateless e tem a injeção do Entity Manager através da notação @PersistenceContext.

Valeu

Criado 12 de dezembro de 2016
Ultima resposta 17 de abr. de 2017
Respostas 8
Participantes 4