2011-11-17 18 views
9

Sono nuovo di Java EE 6 e CDI. Ho letto un paio di tutorial e la documentazione sulla saldatura. Comunque qualcosa che dovrebbe funzionare dalla mia comprensione non ha quindi bisogno di aiuto.CDI Iniezione di un EJB porta a NullPointerException

Ho la seguente situazione. Ho creato un'applicazione Java EE 6 con NetBeans 7.0.1 utilizzando l'archetipo maven fornito con IDE e distribuito a GlassFish 3.1 fornito anche dall'IDE.

Il bean.xml si trova nella directory META-INF del mio jar EJB.

Ho creato una classe che lavora soley come classe produttrice per i miei artefatti EJB (e EntityManager)

@Stateless 
public class EjbArtifactProducer { 

    @PersistenceContext(unitName = "trackProfiler-PU")  
    private EntityManager em; 

    @EJB 
    private UserFacadeLocal userFacade; 

    @EJB 
    private AuthServiceLocal authService; 

    @EJB 
    private NewsEntryFacadeLocal newsEntryFacade; 

    @EJB 
    private RoleFacadeLocal roleFacade; 

    @EJB 
    private TrackCommentFacade trackCommentFacade; 

    @EJB 
    private TrackFacade trackFacade; 

    @EJB 
    private TrackTypeFacade trackTypeFacade; 

    @EJB 
    private WaypointFacadeLocal waypointFacade; 

    @Produces 
    public AuthServiceLocal getAuthService() { 
    return authService; 
    } 

    @Produces 
    public EntityManager getEm() { 
    return em; 
    } 

    @Produces 
    public NewsEntryFacadeLocal getNewsEntryFacade() { 
    return newsEntryFacade; 
    } 

    @Produces 
    public RoleFacadeLocal getRoleFacade() { 
    return roleFacade; 
    } 

    @Produces 
    public TrackCommentFacade getTrackCommentFacade() { 
    return trackCommentFacade; 
    } 

    @Produces 
    public TrackFacade getTrackFacade() { 
    return trackFacade; 
    } 

    @Produces 
    public TrackTypeFacade getTrackTypeFacade() { 
    return trackTypeFacade; 
    } 

    @Produces 
    public UserFacadeLocal getUserFacade() { 
    return userFacade; 
    } 

    @Produces 
    public WaypointFacadeLocal getWaypointFacade() { 
    return waypointFacade; 
    }  

} 

ho cercato di applicare l'annotazione @Produces direttamente ai campi una su metodi come indicato sopra.

Tuttavia Quanto segue non iniettare nulla in un altro EJB

@Inject 
private NewsEntryFacadeLocal newsEntryFacade; 

Questo viene fatto in un EJB di sessione senza stato, ma quando provo ad accedere newsEntryFacade in nessuno dei miei metodi di business è gettato un NullPointerException. Quindi chiaramente nessun'iniezione sta accadendo o i miei produttori producono riferimenti nulli.

Mi manca qualcosa? O dovrebbe questo lavoro secondo CDI/Weld?

Stranamente sembra funzionare in questo modo quando provo ad @Inject EJB nella parte dell'applicazione web (però avevo bisogno di un ulteriore classe produttore nel mio .war per questo lavoro, è questo come dovrebbe essere?) .

MODIFICA: il progetto funziona con una generazione di form (generata da NetBeans). Ci sono problemi con l'archetipo Maven fornito da NetBeans? Sembra che con l'archetipo Maven ci siano alcuni problemi con l'iniezione CDI tra i moduli war e ejb. Ho scoperto che se avessi produttori separati nel modulo web e ejb Glassfish generasse un errore di distribuzione affermando che ci sono due implementazioni indistinguibili di un'interfaccia. Ma quando rimuovo il produttore nel modulo web, Weld si lamenta che il bean che voglio iniettare nei miei bean nel modulo web non può essere risolto. Inoltre, gli EJB di build di Ant possono essere @Injected senza un producer mentre il build di maven necessita di campi di produzione su una classe. Non posso spiegare come potrebbe accadere. Dopotutto la distribuzione finale dovrebbe essere più o meno uguale, non dovrebbe?

+0

L'altro EJB che hai provato ad iniettare, è nello stesso Jar EJB o in un altro archivio? Nota: per abilitare bean-discovery (o CDI), bean.xml deve essere presente in ciascuno degli archivi di distribuzione. In WEB-INF per .wars e in META-INF per .jars – stratwine

+0

Sì. Entrambi hanno un bean.xml. –

+0

Ho provato a convertire il mio progetto in una formica. Adesso funziona tutto bene. Non ho nemmeno bisogno di creare produttori separati per moduli di guerra ed ejb più. La domanda ora è: c'è qualche problema con l'archetipo di Maven? O ci sono dei caveat speciali da considerare? –

risposta

0

Provare a inserire @Named in EjbArtifactProducer. Inoltre, se la produzione è così semplice, penso che sia meglio rimuoverla (altrimenti dovresti fare un altro cambiamento).

1

Se si desidera utilizzare @Inject, annotarlo come @Named @ApplicationScoped, altrimenti utilizzare @EJB quando si inserisce il singleton.

0

Difficile dire cosa sta andando male, ma quello che sicuramente non ha funzionato per noi è usare il CDI tra i limiti del caricatore di classe. Ad esempio, se la tua applicazione è confezionata come un file ear, avrai il tuo ejbs in un file jar e la tua webapp nel tuo file war. In questo caso non puoi utilizzare CDI per iniettare i tuoi ejbs nel tuo livello web. Il problema è che il vaso e la guerra sono caricati da diversi caricatori di classe. Forse le più recenti implementazioni del CDI si comportano diversamente, ma almeno JBoss 6 e Glassfish hanno avuto questo problema.

1

Jordan Denison è corretto. Stai provando a @Inject e EJB, ma stai usando @EJB per EJB.La tua classe EJB è probabilmente annotata con @Stateless o qualcosa del genere. @Inject deve essere utilizzato su bean di sessione annotati con @Named e una sorta di ambito.

0

stai mescolando due concetti diversi ... usa CDI come backing bean per JSF. (CDI nel contenitore Web) e utilizzare EJB e JPA nel Business Layer ... il livello CDI può iniettare un EJB per chiamare il metodo di business specifico.

in questo caso si ha una netta separazione tra preoccupazioni.

BTW: non hai bisogno di alcuna interfaccia EJB! utilizzare solo interfacce se si dispone di requisiti per comunicare da remoto ... (@Remote). con l'annotazione @LocalBean puoi iniettare direttamente l'EJB stesso ..

se hai una netta separazione dei livelli ciascuno con la sua preoccupazione penso che sia meglio trovare la ragione di questa NullPointerException .. e penso che la tua NullPointerException non esiste più dopo questo ...

stratificazione:

Browser Web -> JSF facelet -> CDI Backing Bean -> EJB servizi (s) -> EntityManager

+0

link interessante sulle interfacce -> http://www.adam-bien.com/roller/abien/entry/how_to_deal_with_interfaces – StefanHeimberg