1

Diese Frage ist ein Ableger eines anderen, den ich vor ein paar Wochen gepostet habe: log4j2 logging of code in EJB jar on JBoss EAP 7. In diesem Beitrag stellte ich ein Problem und schließlich eine Lösung für die Protokollierung der Initialisierung von EJBs, die als EJB-JAR-Dateien (nicht EARs) auf einem JBoss EAP 7-Server bereitgestellt und von einem anderen Servlet aufgerufen wurden. Diese EJBs werden über die lokale Schnittstelle aufgerufen.@PostConstruct aufgerufen Stateful EJB Aufruf, aber nicht Stateless Warum?

Die Lösung, die ich in diesem Link vorgestellt habe, funktionierte wunderbar für das erste EJB, das ich mit einem Stateful EJB ausprobierte. Die @ PostConstruct-Annotated-Methode wird aufgerufen und initialisiert den Logging-Kontext und alles funktioniert gut.

Die Lösung schlug auf dem zweiten EJB fehl Ich versuchte es mit. Diese EJB war staatenlos. @PostConstruct-Methode wird nie aufgerufen und der erste Versuch der Protokollierung bläst die Sache auf, weil Logger null ist. Der einzige Unterschied, den ich zwischen den beiden Bohnen sehen konnte, war, dass der zweite zustandslos war, während der erste zustandslos war. Als Experiment habe ich den zweiten Zustand gemacht. Sobald ich das getan hatte, wurde @PostConstruct aufgerufen, Logging wurde initialisiert und alles war im Grunde gut.

Gemäß der Oracle JavaEE6 tutorial, @PostConstruct-Methode soll auf statuslose Bean Instanziierung aufgerufen werden. Warum ruft die Instantiierung von statusbehafteten Session-Beans @PostConstruct auf, während die Instanziierung von Stateless Session-Beans dies nicht tut, und was könnte ich dagegen tun?

Danke.

Update: Hinzufügen von Quellcode.

EJB-jar.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> 

DealerLocatorBean.java:

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); 
    } 

Wenn die Bohnen als Stateful eingesetzt wird (in EJB-jar.xml), @PostConstruct heißt das erste Mal, dass die Bean nach dem Deployment verwendet wird und alles funktioniert. DealerLocatorBean.postConstruct() wird in der Ausgabe und allen Subsqeuent-Protokollierungen angezeigt.

Wenn die Bean als statusfrei (in ejb-jar.xml) bereitgestellt wird, wird @postConstruct nie aufgerufen. DealerLocatorBean.postConstruct() wird NICHT in der Ausgabe angezeigt. Die Protokollierung wird nicht initialisiert, und NullPointerExceptions treten auf, sobald der Code versucht, etwas über den Protokollierer zu protokollieren.

+0

Ich benutze nicht EAP, aber mit allen JBOSS Community EE6 und EE7 Editionen, die ich gearbeitet habe funktioniert "@PostConstruct" einwandfrei und das muss ein Fall sein mit EAP Versionen, die stabiler sein sollen. Durchsuchen Sie die Protokolle nach einer Laufzeitausnahme, die möglicherweise während des "@PostConstruct" des bestimmten SLSB aufgetreten ist. – garfield

+0

Danke, aber ich denke nicht, dass dies die Ursache sein kann. Ich habe eine System.out.println-Anweisung als erste Zeile der @ PostConstruct-Methode hinzugefügt und sie erscheint nicht in der Datei server.log, wenn die Bean zustandslos ist (zeigt keinen Aufruf der Methode an) und erscheint, wenn die Bean statusbehaftet ist . In beiden Fällen tritt keine Laufzeitausnahme auf. –

+0

Vielleicht sollten Sie den Code für die spezifische SLSB veröffentlichen. – garfield

Antwort

0

Haben Sie gesehen, dass diese Bean in den Protokollen als bereitgestellt gemeldet wurde? Auch nicht abschließende Statiken sind in SLSBs nicht erlaubt. Ich würde vorschlagen, den privaten statischen LoggerContext logctx zu ändern; zum privaten statischen endgültigen LoggerContext logctx = Configurator.initialize (LOGGER_CONTEXT_NAME, LOGGER_CONFIG); wenn möglich und für Logger gleich und entfernen Sie die entsprechenden Anweisungen aus @PostConstruct oder entfernen Sie einfach das statische Schlüsselwort in den Deklarationen von logctx und logger.

Verwandte Themen