Jboss @PostConstruct调用了有状态EJB调用,但不是无状态的,为什么?

Jboss @PostConstruct调用了有状态EJB调用,但不是无状态的,为什么?,jboss,ejb,stateless-session-bean,postconstruct,stateful-session-bean,Jboss,Ejb,Stateless Session Bean,Postconstruct,Stateful Session Bean,这个问题是我几周前发布的另一个问题的一个分支: . 在那篇文章中,我提出了一个问题,并最终提出了一个解决方案,用于将部署为EJB JAR(而不是EAR)的EJB上的初始化记录到JBoss EAP 7服务器上,并从另一个servlet调用。这些EJB是通过本地接口调用的 我在该链接中介绍的解决方案在我尝试使用的第一个EJB(有状态EJB)中运行良好。调用@PostConstruct注释的方法并初始化日志上下文,一切都很好 解决方案在我使用的第二个EJB上失败。这个EJB是无状态的@PostCon

这个问题是我几周前发布的另一个问题的一个分支: . 在那篇文章中,我提出了一个问题,并最终提出了一个解决方案,用于将部署为EJB JAR(而不是EAR)的EJB上的初始化记录到JBoss EAP 7服务器上,并从另一个servlet调用。这些EJB是通过本地接口调用的

我在该链接中介绍的解决方案在我尝试使用的第一个EJB(有状态EJB)中运行良好。调用@PostConstruct注释的方法并初始化日志上下文,一切都很好

解决方案在我使用的第二个EJB上失败。这个EJB是无状态的@PostConstruct方法永远不会被调用,并且第一次尝试记录日志会导致失败,因为logger为null。我能看到的两个bean之间的唯一区别是,第二个bean是无状态的,而第一个bean是有状态的。作为一个实验,我做了第二个有状态的实验。一旦我这样做了,@PostConstruct被调用,日志被初始化,一切基本正常

根据 ,假定在无状态bean实例化时调用@PostConstruct方法。那么,为什么有状态会话bean实例化调用@PostConstruct,而无状态会话bean实例化不调用@PostConstruct,我该怎么办呢

谢谢

更新:添加源代码。

ejbjar.xml

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         version="3.2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd">
    <module-name>DealerLocatorBean</module-name>
    <enterprise-beans>
        <session>
            <ejb-name>DealerLocatorBean</ejb-name>
            <home>com.whatever.ServiceLogicHome</home>
            <remote>com.whatever.ServiceLogic</remote>
            <local-home>com.whatever.ServiceLogicLocalHome</local-home>
            <local>com.whatever.ServiceLogicLocal</local>
            <ejb-class>com.whatever.ejbs.DealerLocatorBean</ejb-class>
            <session-type>Stateless</session-type>
            <!-- <session-type>Stateful</session-type> No problem if this is made stateful-->
            <transaction-type>Bean</transaction-type>
        </session>
    </enterprise-beans>
</ejb-jar>
如果bean被部署为有状态的(在ejb jar.xml中),那么在部署后第一次使用bean时就会调用@postConstruct,并且一切正常<代码>DealerLocatorBean.postConstruct()显示在输出中,并且所有子分量的日志记录都有效


如果bean部署为无状态(在ejbjar.xml中),则永远不会调用@postConstruct<代码>DealerLocatorBean.postConstruct()在输出中看不到。日志记录未初始化,当代码试图通过日志记录器记录某些内容时,就会产生NullPointerException。

您是否看到此bean在部署时报告给日志?SLSB中也不允许最终静态。我建议更改私有静态LoggerContext logctx;至专用静态最终LoggerContext logctx=Configurator.initialize(记录器\上下文\名称,记录器\配置);如果可能的话,对logger也是如此,从@PostConstruct中删除相应的语句,或者只删除logctx和logger声明中的static关键字。

您是否看到这个bean在部署时报告给日志?SLSB中也不允许最终静态。我建议更改私有静态LoggerContext logctx;至专用静态最终LoggerContext logctx=Configurator.initialize(记录器\上下文\名称,记录器\配置);如果可能的话,对logger也一样,从@PostConstruct中删除相应的语句,或者只删除logctx和logger声明中的static关键字。

我不使用EAP,但我使用的所有JBOSS社区EE6和EE7版本都是“@PostConstruct”工作完美无瑕,EAP版本应该更稳定。搜索日志以查找最终在特定SLSB的“@PostConstruct”期间发生的运行时异常。谢谢,但我认为这不是原因。我添加了一个System.out.println语句作为@PostConstruct方法的第一行,当bean是无状态的(表示没有调用该方法)时,它不会出现在server.log中,当bean变成有状态时,它会出现。在这两种情况下都不会发生运行时异常。也许您应该发布特定SLSB的代码。我无法发布此SLSB的代码。它包含了太多的专有业务逻辑,所有这些都与当前的问题无关。我将尝试发布ejb-jar.xml以及PostConstruct和PreDestroy方法,这应该是所有必要的。@garfield-将您的评论作为“答案”,我很乐意给您投票。我不使用EAP,但我使用的所有JBOSS社区EE6和EE7版本都是“@PostConstruct”工作完美无瑕,EAP版本应该更稳定。搜索日志以查找最终在特定SLSB的“@PostConstruct”期间发生的运行时异常。谢谢,但我认为这不是原因。我添加了一个System.out.println语句作为@PostConstruct方法的第一行,当bean是无状态的(表示没有调用该方法)时,它不会出现在server.log中,当bean变成有状态时,它会出现。在这两种情况下都不会发生运行时异常。也许您应该发布特定SLSB的代码。我无法发布此SLSB的代码。它包含了太多的专有业务逻辑,所有这些都与当前的问题无关。我将尝试发布ejb-jar.xml以及PostConstruct和PreDestroy方法,这应该是所有必要的。@garfield-将您的评论作为“答案”,我将很高兴投票支持您。
public class DealerLocatorBean implements SessionBean
{

    private static final String LOGGER_CONFIG = "/path/to/log4j2.xml";
    private static final String LOGGER_CONTEXT_NAME = "VTDLLOC-EJB";
    private static LoggerContext logctx;
    private static Logger logger = null;

    public DealerLocatorBean() {
        System.out.println("calling DealerLocatorBean() constructor");
    }
    @PostConstruct
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED)
    private void postConstruct() {
        System.out.println("DealerLocatorBean.postConstruct()");
        logctx = Configurator.initialize(LOGGER_CONTEXT_NAME, LOGGER_CONFIG);
        logger = logctx.getLogger(getClass().getName());
        logger.log(Level.INFO, ("postConstruct() in DealerLocatorBean called"));
        logger.log(Level.INFO, ("******END OF THE postConstruct() CALL******"));
    }

    @PreDestroy
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED)
    private void preDestroy() {
        logger.log(Level.INFO, ("preDestroy() in DealerLocatorBean called.  Shutting down logging."));
        Configurator.shutdown(logctx);
    }