2011-11-17 28 views
9

Tôi mới sử dụng Java EE 6 và CDI. Tôi đã đọc một vài hướng dẫn và tài liệu hàn. Tuy nhiên một cái gì đó mà nên làm việc từ sự hiểu biết của tôi không vì vậy tôi cần giúp đỡ.Tiêm CDI của EJB dẫn đến NullPointerException

Tôi có tình huống sau. Tôi đã tạo ra một ứng dụng Java EE 6 với NetBeans 7.0.1 bằng cách sử dụng nguyên mẫu maven được cung cấp cùng với IDE và tôi triển khai cho GlassFish 3.1 cũng được cung cấp bởi IDE.

Bean.xml nằm trong thư mục META-INF của bình EJB của tôi.

Tôi đã tạo ra một lớp học mà làm việc Chỉ duy nhất như là một lớp sản xuất cho Artifacts EJB của tôi (và 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; 
    }  

} 

Tôi cố gắng để áp dụng các chú thích @Produces trực tiếp đến lĩnh vực một phương pháp như trên.

Tuy nhiên sau đây không tiêm bất cứ điều gì trong một EJB

@Inject 
private NewsEntryFacadeLocal newsEntryFacade; 

này được thực hiện trong một phiên ejb quốc tịch nhưng khi tôi thử truy cập newsEntryFacade trong bất kỳ các phương pháp kinh doanh của tôi một NullPointerException được ném. Vì vậy, rõ ràng không có tiêm đang xảy ra hoặc nhà sản xuất của tôi sản xuất tài liệu tham khảo null.

Tôi có thiếu gì đó không? Hoặc nên tác phẩm này theo CDI/Weld?

Điều lạ lùng dường như hoạt động theo cách đó khi tôi cố gắng @Inject EJB vào phần ứng dụng web (tuy nhiên tôi cần thêm thêm lớp sản xuất trong chiến dịch .war của tôi để làm việc này, phải không?) .

EDIT: Dự án hoạt động với kiến ​​trúc xây dựng (được tạo bởi NetBeans). Có vấn đề với nguyên mẫu Maven do NetBeans cung cấp không? Dường như với nguyên mẫu Maven có một số vấn đề với việc tiêm CDI giữa mô-đun chiến tranh và ejb. Tôi thấy rằng nếu tôi có các nhà sản xuất riêng trong mô hình web và ejb Glassfish tạo ra lỗi triển khai cho biết có hai triển khai không thể phân biệt được của một giao diện. Nhưng khi tôi loại bỏ các nhà sản xuất trong mô-đun web Weld phàn nàn rằng EJB tôi muốn tiêm vào đậu của tôi trong mô-đun web không thể được giải quyết. Ngoài ra với các EJB xây dựng Ant có thể được @Injected mà không có một nhà sản xuất trong khi xây dựng maven cần các lĩnh vực sản xuất trên một lớp. Tôi không thể giải thích làm thế nào điều này có thể xảy ra. Sau khi tất cả các triển khai cuối cùng nên được nhiều hơn hoặc ít hơn bằng nhau, phải không?

+0

Các khác EJB bạn đã cố gắng tiêm vào, có phải trong cùng một EJB Jar hay một kho lưu trữ khác không? Lưu ý: Để cho phép bean-discovery (hoặc CDI) beans.xml có mặt trong mỗi kho lưu trữ triển khai. Trong WEB-INF cho .wars và trong META-INF cho .jars – stratwine

+0

Có. Cả hai đều có tệp beans.xml. –

+0

Tôi đã cố gắng chuyển đổi dự án của mình thành bản dựng kiến. Tất cả mọi thứ hoạt động tốt ngay bây giờ. Tôi thậm chí không cần phải tạo ra các nhà sản xuất riêng biệt cho các mô-đun chiến tranh và ejb nữa. Câu hỏi bây giờ là: Có vấn đề gì với nguyên mẫu maven không? Hoặc có bất kỳ cảnh báo đặc biệt nào để xem xét không? –

Trả lời

0

Cố gắng đặt @Named vào EjbArtifactProducer. Ngoài ra, nếu các sản phẩm là loại đơn giản, tôi nghĩ rằng nó tốt hơn để loại bỏ nó quá (khác, bạn nên làm một thay đổi nhiều hơn).

1

Nếu bạn muốn sử dụng @Inject thì hãy chú thích nó là @Named @ApplicationScoped, nếu không hãy sử dụng @EJB khi tiêm singleton của bạn.

0

Khó để nói những gì đang xảy ra nhưng điều chắc chắn không hiệu quả đối với chúng tôi là sử dụng CDI giữa các ranh giới của trình nạp lớp. Ví dụ, nếu ứng dụng của bạn được đóng gói như một tập tin tai bạn sẽ có ejbs của bạn trong một tập tin jar và webapp của bạn trong tập tin chiến tranh của bạn. Trong trường hợp này bạn không thể sử dụng CDI để tiêm ejbs của bạn trong lớp web của bạn. Vấn đề là bình và chiến tranh được nạp bởi các trình nạp lớp khác nhau. Có lẽ các triển khai CDI mới hơn hoạt động khác nhau nhưng ít nhất JBoss 6 và Glassfish có vấn đề này.

1

Jordan Denison là chính xác. Bạn đang cố gắng để @Inject và EJB, nhưng bạn đang sử dụng @EJB cho EJB.Bạn là lớp EJB có thể được chú thích với @Stateless hoặc một cái gì đó. @Inject nên được sử dụng trên đậu phiên có chú thích với @Named và một số loại phạm vi.

0

bạn đang trộn hai khái niệm khác nhau ... sử dụng CDI làm hạt sao lưu cho JSF. (CDI trong Web Container) và sử dụng EJB và JPA trong lớp kinh doanh ... lớp CDI có thể tiêm một EJB để gọi phương thức kinh doanh cụ thể.

trong trường hợp này, bạn có sự phân tách rõ ràng về các mối quan tâm.

BTW: bạn không cần bất kỳ giao diện EJB nào cả! chỉ sử dụng giao diện nếu bạn có yêu cầu giao tiếp từ xa ... (@Remote). với chú thích @LocalBean, bạn có thể tự mình chèn trực tiếp vào EJB ..

nếu bạn tách riêng từng lớp với mối quan tâm của riêng mình, tôi nghĩ bạn nên tìm lý do cho NullPointerException .. và tôi nghĩ NullPointerException của bạn không tồn tại nữa sau này ...

Phân tán:

Web Browser -> JSF Facelet -> CDI Sao Bean -> EJB Service (s) -> EntityManager

+0

liên kết thú vị về giao diện -> http://www.adam-bien.com/roller/abien/entry/how_to_deal_with_interfaces – StefanHeimberg

Các vấn đề liên quan