2016-01-06 17 views
5

Tôi muốn lấy bean từ phương thức sản xuất để đọc các thuộc tính của nó. Trong một số trường hợp, đậu là một hạt đậu EJB Singleton.injectionPoint.getBean() trả về null nếu bean là bean EJB trong Java EE 7 (CDI 1.1)

Tôi đã đơn giản hóa mã của mình để tập trung vào vấn đề.

vòng loại đơn giản của tôi:

@Qualifier 
@Retention(RUNTIME) 
@Target({TYPE, METHOD, FIELD, PARAMETER}) 
public @interface InjectMe {} 

Simple sản xuất:

@Dependent 
public class SimpleProducer { 

    @Produces 
    @InjectMe 
    public String getInjectMe(InjectionPoint ip) { 
     // ip.getBean() returns null for some reason 
     return "ip=" + ip + ", bean=" + ip.getBean(); 
    } 
} 

EJB (Singleton):

@Singleton 
@Startup 
public class SimpleSingleton { 

    @Inject 
    @InjectMe 
    private String injectMe; 

    @PostConstruct 
    public void init() { 
     System.out.println(injectMe); 
    } 

}

điều khiển đầu ra:

Thông tin: ip = [BackedAnnotatedField] @Inject @InjectMe com.test.ejb.SimpleSingleton.injectMe tin, bean=null

Khi tôi thay đổi Singleton đậu để CDI đậu tất cả mọi thứ hoạt động tốt (ip.getBean() lợi nhuận không phải là null). Nó cũng hoạt động trong Java EE 6 thậm chí với Singleton đậu nhưng không có trong Java EE 7. Tôi đang sử dụng máy chủ ứng dụng Glassfish 4.

Hành vi này có được chỉ định ở đâu đó không?

+0

Nghe giống như lỗi thủy tinh. –

+0

@JohnAment: Đừng nghĩ như vậy, cùng một hành vi cho WildFly. Không thể trả lời câu hỏi, nhưng các lý do có thể có thể là: 1) thay đổi hành vi của mô-đun phát hiện bean (mặc định: 'chú thích'); 2) tiêm một chuỗi lớp (không theo ngữ cảnh); 3) không có phạm vi được khai báo nào ngoài 'Phụ thuộc ' –

+0

Nếu bạn gọi' ip.getMember(). GetDeclaringClass() ', bạn sẽ nhận được cả hai trường hợp FQCN, điều này cũng được sử dụng làm ví dụ trong tài liệu API InjectionPoint và Tôi đã nhìn thấy nó trong một ví dụ Deltaspike như một cuộc gọi tiếp theo sau khi 'bean' là' null'. –

Trả lời

1

Sử dụng

injectionPoint.getMember().getDeclaringClass() 

công trình đối với tôi trong WildFly 10.1.0 và tôi cũng nhanh chóng thử nghiệm nó trong Payara server 4.1.1.162 #badassfish (xây dựng 116). Tôi cũng đã làm một thử nghiệm trên thương hiệu mới Payara Server 4.1.1.164 #badassfish (xây dựng 28). Tuy nhiên, tôi phải thay đổi phạm vi của bean sản xuất thành @ApplicationScoped. Phạm vi mặc định không hoạt động. Trong trường hợp của tôi, nó thậm chí còn có ý nghĩa :)

Phương pháp

injectionPoint.getBean().getBeanClass() 

làm việc cho tôi trong Payara cũ, nhưng không phải trong WildFly 10.1.0.Final mới và mới Payara server 4.1.1.164 # badassfish (xây dựng 28).

Nếu bạn nhìn vào Payara, phiên bản mới hiện tại 164 chứa Weld 2.4.0.Final và WildFly 10.1.0Final sử dụng phiên bản 2.3.5.Final. Trong cả hai phiên bản, mã cổ điển không hoạt động!

Kết luận là, khi triển khai CDI cũ hơn (Weld), nó hoạt động. Trong một số Weld mới hơn (được giới thiệu trong Payara 161), hành vi đã thay đổi. Tôi không biết điều này có chủ ý hay không.

Tuy nhiên, giải pháp là sử dụng

injectionPoint.getMember().getDeclaringClass() 

và chú thích các hạt sản xuất với

@javax.enterprise.context.ApplicationScoped 

chú thích.

+1

Thử nghiệm trên weblogic 12.2.1 (CDI 1.1) và tôi cũng có cùng một vấn đề. Trong khi nó hoạt động tốt trên weblogic 12.1.3 (CDI 1.0). Như bạn đã nói, tôi đã giải quyết vấn đề bằng cách sử dụng 'injectionPoint.getMember(). GetDeclaringClass()' – Rouliboy

+0

Có vẻ như điều này đã được nhận ra: https://issues.jboss.org/browse/WELD-2339 –

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