2017-04-03 1 views
1

Ich muss Ereignisse von einigen ejb (Staatenlos und Singleton) mit Abhängigkeitsinjektion auslösen. Ich benutze nicht Spring, Guice etc. Das Problem ist, dass ich NPE in einer der Bohnen beim Aufruf der Methode durch getInstance() erhalten. Hier ist der Code-Schnipsel:Singleton CDI @Inject Nullzeiger Ausnahme

@Stateless 
@LocalBean 
public class ControllerStartStop { 
    @Inject 
    private Event<SomeWebMessage> webEvent; 

    public String startCircle(String passwordP, String passwordH) { 
    ......... 
    String res = "some msg"; 
    webEvent.fire(new SomeWebMessage(res, 0)); // this works fine 
    MainDay.getInstance().startDay();  // NullPointerException 

hier MainDay Singletons ist:

@Singleton 
public class MainDay { 
    private static final MainDay mDay = new MainDay(); 
    public static MainDay getInstance() { return mDay ; } 

    @Inject 
    private Event<SomeWebMessage> webEvent; 

    public void startDay() { 
     String s = new String("MainDay"); 
     webEvent.fire(new SomeWebMessage(s,0)); // NullPointerException 

beans.xml ist in META-INF:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     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/beans_1_1.xsd" 
     version="1.1" bean-discovery-mode="all"> 

</beans> 

Es gibt keine NPE ist, wenn ich Ereignis ausgelöst von ein Aufruf der statischen Methode wie MainDay.initDS(), oder wenn Methode StartDay() durch einen Planer zu (@Schedule (h = "", minute = "", zweite aufgerufen = "/10") *. Ich habe keine Ahnung, was der Grund ist

Antwort

0

Beachten Sie, dass @Singleton bedeutet, dass der Behälter (EJB oder CDI, hängt davon ab, welche Anmerkung, es ist) wird die Instanz verwalten, das heißt Sie sollte es sich nicht erstellen.

Wenn Sie die Instanz über private static final MainDay mDay = new MainDay(); erstellen, erfolgt keine Injektion durch den Container, und webEvent ist somit null. Außerdem weiß der Container nichts über diese Instanz, und die Verwendung von @Inject MainDay an einem anderen Ort führt sehr wahrscheinlich zu einer anderen Instanz.

So verwenden nur injizieren (oder Lookups, wenn Sie benötigen) direkt:

class ControllerStartStop { 
    @Inject 
    private MainDay mDay; 

    ... 
    public String startCircle(String passwordP, String passwordH) { 
    ... 
    String res = "some msg"; 
    webEvent.fire(new SomeWebMessage(res, 0)); 
    mDay.startDay();  
    ... 
    } 

Es gibt keine NPE, wenn ich Ereignis von einem Aufruf der statischen Methode wie MainDay.initDS Feuer() oder wenn Verfahren StartDay() von einer Task-Manager eines (@Schedule (Stunde aufgerufen = "", Minute = "", zweite = "/ 10") *. ich habe keine Ahnung, was der Grund

ist

ohne den Code zu wissen, es ist nur eine Vermutung, aber ich würde annehmen, dass Sie hier MainDay injizieren oder eine CDI/JNDI-Suche verwenden Der Container erstellt eine Instanz, wenn keine vorhanden ist und injiziert die Objekte Event.

+0

Danke, Thomas! Sein klar jetzt und es funktioniert :) – Buch

0

NPE 1:

Sollte nicht die anvisierten EJB MainDay "beobachten" die Veranstaltung und rufen seine startDay() Methode?

public void onEvent(@Observes SomeWebMessage event) { 
    // if (...) 
     startDay(); 
} 

So gibt es keine Notwendigkeit für eine statische getInstance() Methode.

NPE 2:

@Inject Event<SomeWebMessage> webEvent; 

Dependency Injection (DI) funktioniert nur, wenn Sie rufen Sie nicht manuell den Konstruktor new MainDay() aber Instanzen der gesuchten Bohne zu injizieren und die DI-Container Griffkonstruktion lassen.

Aber mit @Observes (javax.enterprise.event.Beobachtungen) Sie sollten in der Lage sein, alle stinkenden static Sachen sowieso zu entfernen.

+0

Es ist ein weiterer Singleton, die Ereignisse ausgelöst in ControllerStartStop, MainDay und vielleicht einem oder zwei andere beobachtet: '@Singleton public class LongPollingNotifier { \t Privat letzten Queue Peers = new ConcurrentLinkedQueue (); @Asynchronous \t public void notifyPeers (@Observes SomeWebMessage SWM) ... ' Ist dieser Ansatz in Ordnung? – Buch

+0

Ja, Sie können mehrere unabhängige Beobachter haben. –