質問

I basically am trying to inject a @Stateless bean with a local interface into a class annotated with @Named! My understanding is that injection is only possible when the injection point is managed (makes perfect sense), so for example it wouldn't be possible to inject into a POJO but you could inject into a Servlet, a JSF managed or another EJB.

I would have thought that it would have been possible to subsequently use it with @Named! However I get a NullPointerException that specifically seems to imply that this in fact doesn't seem possible!?

My classes look like this (stripped for clarity);

@Named
public class EmailUtil {

// Logger-------------------------------------------------------------------
private static final Logger LOG = Logger.getLogger(EmailUtil.class.getName());

// Constructor--------------------------------------------------------------
public EmailUtil() {
}

// EJB----------------------------------------------------------------------
@EJB AuditDAO audit;

// Methods------------------------------------------------------------------
public void sendEmail(
        String emailSender,
        String emailRecipient,
        String emailSubject,
        String emailHtmlBody,
        String emailTextBody) throws FailedEmailException {

    ... code removed for clarity ...

    // Call Amazon SES to send the message 
    try {
        new SES().getClient().sendEmail(request);

        // Create an audit log of the event
        audit.create("Email sent to " + emailSender);
    } catch (AmazonClientException ace) {
        LOG.log(Level.SEVERE, ace.getMessage(), ace);
        throw new FailedEmailException();
    } catch (Exception e) {
        LOG.log(Level.SEVERE, e.getMessage(), e);
    }
}
}


@Stateless
public class AuditDAOImpl implements AuditDAO {

    // Logger-------------------------------------------------------------------
    private static final Logger LOG = Logger.getLogger(AuditDAOImpl.class.getName());
    // EntityManager------------------------------------------------------------
    @PersistenceContext(unitName = "iConsultPU")
    private EntityManager em;

    @Override
    public void create(String event) {
        String subject;
        try {
            /*
             * If the current subject has authenticated and created a session we
             * want to register their ID. However it is possible that a subject
             * does not have an ID so we want to set it to unknown.
             */
            subject = SecurityUtils
                    .getSubject()
                    .getPrincipals()
                    .asList()
                    .get(1)
                    .toString();
        } catch (Exception e) {
            subject = "UNKNOWN";
        }

        Audit audit = new Audit();
        audit.setUserId(subject);
        audit.setEventTime(Calendar.getInstance());
        audit.setEvent(event);

        em.persist(audit);

    }
}

@Local
public interface AuditDAO {
    public void create(String event);    
}

I've tried using @Inject as well but that doesn't seem to work either. Have I misunderstood the specification or just poorly implemented it?

役に立ちましたか?

解決

You should be injecting your dependencies. So if your EmailUtil is being manually constructed, injection won't work. It needs to be container managed. So if you use a servlet, or any managed bean, you can @Inject it. CDI injection only works for managed objects.

You can do some additional work arounds, such as manually invoking it against a constructed instance. Take a look at this question for an example like that: Parallel webservices access in a Weld CDI environment

他のヒント

Do you have the beans.xml in the correct location? Injection for @Named (and other CDI beans) is handled by CDI, which isn't started unless you have the beans.xml file in the correct location (WEB-INF for war and META-INF for jar).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top