0

I am using Glassfish 3.1.2.2 and I want to collect and store authentication information to my MySQL database attached to the Glassfish application server. So far I successfully implemented a customized audit module which I put into my ejb-project. This works so far without problems.

Now I want to set some flags and counters when login attempts fail. For this purpose I tried to inject an EntityManager instance to the AuditModule class/object, but this throws always a null pointer exception, since the injection fails.

I already tried to add the @Stateless annotation (in order to tell that this class should be container-managed), but without success. The entity manager instance "em" is still null.

Here's my customized audit module:

@Stateless
public class CustomAuditModule extends AuditModule {

    @PersistenceContext(unitName = "MyPersistenceUnit-ejbPU")
    private EntityManager em;

    @Override
    public void init(Properties props) {
        this.props = props;
    }

    @Override
    public void authentication(String username, String realm, boolean success) {
        if(success) {
            try {
                User user = em.createQuery("SELECT u FROM User u WHERE u.name='"+username+"'", User.class).getSingleResult();
                user.setLastLoginFail(new Long(-1L));
                user.setLoginFails(0);
                em.merge(user);
                em.flush();
            } catch(NoResultException ex) {
                Logger.getLogger(CustomAuditModule.class.getName()).log(Level.WARNING, "User "+username+" does not exist.");
            }
        } else {
            try {
                User user = em.createQuery("SELECT u FROM User u WHERE u.name='"+username+"'", User.class).getSingleResult();
                user.setLastLoginFail(System.currentTimeMillis());
                int fails = user.getLoginFails().intValue();
                fails++;
                user.setLoginFails(fails);
                em.merge(user);
                em.flush();
            } catch(NoResultException ex) {
                Logger.getLogger(CustomAuditModule.class.getName()).log(Level.WARNING, "User "+username+" does not exist.");
            }
        }
    }

    @Override
    public void ejbInvocation(String user, String ejb, String method, boolean success) {
        Logger.getLogger(CustomAuditModule.class.getName()).log(Level.INFO, "EJB Invocation.");
    }

    @Override
    public void serverStarted() {
        Logger.getLogger(CustomAuditModule.class.getName()).log(Level.INFO, "Server Started.");
    }

    @Override
    public void serverShutdown() {
        Logger.getLogger(CustomAuditModule.class.getName()).log(Level.INFO, "Server Shutdown.");
    }

}

Somebody any idea how to access the jdbc resource / correctly injecting the EntityManager instance ?

Many thanks in advance!

salocinx
  • 3,715
  • 8
  • 61
  • 110

1 Answers1

1

I don't have experience in AuditModule. But I suspect that your @Stateless annotation doesn't have any effect, because the EJB should be injected through @EJB annotation, and I doubt this is the case.

I would go with the creation of EntityManagerFactory in the Java SE way:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPersistenceUnit-ejbPU");
EntityManager em = emf.createEntityManager(); 

Note that the first line is an expensive operation, therefore it's advisable to invoke it only once when application starts.

perissf
  • 15,979
  • 14
  • 80
  • 117