【问题标题】:Stateless EJB not injected in message driven bean (MDB)无状态 EJB 未注入消息驱动 bean (MDB)
【发布时间】:2016-05-10 14:52:59
【问题描述】:

我有一个消息驱动的 bean (MDB),它实现了 MessageListener 并具有多个 EJB 属性,但没有注入它们,因此我必须手动注入它们。 MDB 还有一个资源和一个 CDI bean,可以很好地注入。

为什么没有自动注入 EJB?我在应用程序的其他部分使用 NotificationService EJB,它们被注入。关于如何找出问题的任何线索?

我没有收到来自 Weblogic 12.1.3 的任何错误,所以我无法弄清楚这里发生了什么。我的代码是(充满了用于调试目的的痕迹)。我已经删除了与问题无关的 javadocs 和方法实现:

@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
    }
}

【问题讨论】:

  • 好问题,我的一个同事也有同样的问题

标签: dependency-injection java-ee-6 ejb-3.1 weblogic12c message-driven-bean


【解决方案1】:

使用@Inject 代替@EJB 注释注入EJB 效果很好。所以应该是一些Weblogic的补丁有问题,因为在另一个Weblogic(相同版本,不同补丁)中测试它也能正常工作

【讨论】:

  • 你知道确切的补丁吗?我们有 12.2.1 的确切情况
  • 对不起,不知道。我不负责 Weblogic 管理方面。
  • 不幸的是,在 JBoss EAP 7 中,Inject 无法与我的 MDB 一起使用,我还得到了一个 NPE - 我读了很多书,基本上每个人都说不要尝试使用注入的 bean,直到你验证了一个方法用 @PostConstructs 注释的被调用 - 但这甚至对我不起作用。我知道该类已经构建,因为我为构造函数和 postconstruct 方法放置了跟踪输出 - 一切都被调用但仍然是 NPE - 更多谷歌搜索
  • 嗯,我的问题发生在 Weblogic 上,解决方案就是为此目的,我不知道其他应用程序服务器中的情况,但很明显这是他们如何实现一些规格。
  • 我知道我参加聚会迟到了,但我的 2 美分:还要测试 bean 上是否没有 @Stateless 和 @TransactionAttribute(TransactionAttributeType.MANDATORY) 注释。
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
  • 2012-02-27
  • 2016-08-21
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多