3

I have a message driven bean (MDB) that implements MessageListener and has several EJB attributes but non of them are injected so I have to inject them manually. The MDB also has a resource and a CDI bean that are injected fine.

Why the EJBs are not injected automatically? I use NotificationService EJB at other parts of the application and they are injected. Any clue about how to figure out the problem?

I don't get any error from Weblogic 12.1.3, so I can't figure out what's happening here. My code is (full of traces for debugging purposes). I've removed javadocs and method implementations that are not relevant to the problem:

@MessageDriven(name = "MailMessageConsumer", description = "JMS consumer", mappedName = MailJndiConfiguration.JNDI_QUEUE,
    activationConfig = {
            @ActivationConfigProperty(propertyName = "acknowledgeMode",
                                      propertyValue = "Auto-acknowledge"),
            @ActivationConfigProperty(propertyName = "destinationType",
                                      propertyValue = "javax.jms.Queue")
    })
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@MessageReceiver(responsibility = "Consumes JMS messages of type MailMessage")
public class MailMessageConsumer implements MessageListener {
    private static final Logger log = LoggerFactory.getLogger(MailMessageConsumer.class);
    @Resource
    private MessageDrivenContext messageDrivenContext;
    @EJB
    private NotificationService notificationService;
    @EJB
    private MailClient mailClient;
    @Inject
    private ApplicationInformation applicationInformation;

    @Override
    public void onMessage(Message message) {
        if (mailClient == null) {
            log.error("mailClient object is null");
            try {
                log.info("Instantiating MailClient manually...");
                mailClient = BeanManagerHelper.getReference(MailClient.class);
            } catch (Exception e) {
                log.error("Cannot instantiate MailClient manually", e);
            }
        }
        if (notificationService == null) {
            log.error("notificationService object is null");
            try {
                log.info("Instantiating NotificationService manually...");
                notificationService = BeanManagerHelper.getReference(NotificationService.class);
            } catch (Exception e) {
                log.error("Cannot instantiate NotificationService manually", e);
            }
        }
        // This never happens
        if (applicationInformation == null) {
            log.error("applicationInformation object is null");
        }
        // This never happens
        if (messageDrivenContext == null) {
            log.error("messageDrivenContext object is null");
        }
        deliverMessage(message);
    }

    private void deliverMessage(Message message) {
        // Not important
    }

    private MailMessage retrieveMessage(Message message) {
        // Not important
    }

    private void sendEmail(MailMessage mailMessage) {
        // Not important
    }
}

MailClient EJB:

@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.MANDATORY)
@Service
public class MailClient {
    private static final Logger logger = LoggerFactory.getLogger(MailClient.class);
    @Resource(mappedName = MailJndiConfiguration.JNDI_MAIL_SESSION)
    private Session mailSession;
    @EJB
    private NotificationService notificationService;
    @Inject
    private ApplicationInformation applicationInformation;

    enum ValidationError {
        NULL_OBJECT("Mail message is null"),
        CONTENT_TYPE_EMPTY("Content type not initialized"),
        BODY_EMPTY("Message body content is empty");
        private static final String ERROR_MESSAGE_PREFIX = "Invalid mail message: ";
        private String message = ERROR_MESSAGE_PREFIX;

        ValidationError(String message) {
            this.message += message;
        }

        public String getMessage() {
            return message;
        }
    }

    public void sendMail(MailMessage mailMessage) throws MailMessageSendingException {
        // Not important
    }
}

NotificationService EJB:

@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.MANDATORY)
@Service
public class NotificationService {
    private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);
    @PersistenceContext(unitName = "myEntityManager")
    private EntityManager entityManager;
    @EJB
    private NotificationPendingMessageValidator notificationPendingMessageValidator;
    @EJB
    private NotificationFinder notificationFinder;
    @Inject
    private ApplicationInformation applicationInformation;

    public NotificationPendingMessageEntity saveNotificationMessageForDeferredMail(NotificationPendingMessageEntity notificationPendingMessageEntity) throws ValidationException {
        // Not important
    }

    public List<NotificationPendingMessageEntity> findNotificationPendingMessageEntities(TimeSlot timeSlot) {
        // Not important
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public NotificationMailEntity createNewMailEntity() {
        // Not important
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void updateMailEntity(NotificationMailEntity mailEntity) {
        // Not important
    }

    public void createNotificationMessageProcessedEntity(NotificationProcessedMessageEntity notificationProcessedMessageEntity) {
        // Not important
    }

    public void removeNotificationMessagePendingEntity(NotificationPendingMessageEntity notificationPendingMessageEntity) {
        // Not important
    }

    public void reportMailFailure(NotificationMailEntity mailEntity, String failureNotice) {
        // Not important
    }
}
Eduardo Yáñez Parareda
  • 9,126
  • 4
  • 37
  • 50

1 Answers1

2

Using @Inject for injecting the EJBs instead of @EJB annotation works fine. So there should be a problem with some Weblogic's patches, because testing it in another Weblogic (same version, different patches) it worked as well

Jaumzera
  • 2,305
  • 1
  • 30
  • 44
Eduardo Yáñez Parareda
  • 9,126
  • 4
  • 37
  • 50
  • By any chance, do you know the exact patch? We've had the exact case with 12.2.1 – meskobalazs Jun 28 '17 at 09:26
  • I'm sorry, no idea. I was not in charge of that Weblogic administration side. – Eduardo Yáñez Parareda Jun 28 '17 at 14:28
  • Unfortunately, Inject is not working with my MDB in JBoss EAP 7, I also get a NPE - I read around alot and everyone basically said dont try to use the injected bean until after you verify that a method annotated with @PostConstructs been called - but that's not even working for me. I know the class has been constructed as i put trace outputs for both the constructor and postconstruct method - everythings being called but still the NPE - more googling – JGlass Feb 13 '18 at 20:18
  • Well, my problem was happening on Weblogic, and the solution was for that purpose, I don't know the case in other application servers, but it's clear that is a problem on how they are implementing some specifications. – Eduardo Yáñez Parareda Feb 14 '18 at 07:47
  • I know I am late for the party, but my 2 cents: Also test if you don't have @Stateless and @TransactionAttribute(TransactionAttributeType.MANDATORY) annotations on the bean. – Lefteris Bab Jun 15 '20 at 05:33
  • Thanks, but as you can see in my code, I had those annotations. Anyway I solved the issue at the time. – Eduardo Yáñez Parareda Jun 15 '20 at 09:30