2016-01-06 48 views
5

Chcę pobrać komponent bean z metody producenta w celu odczytania jego właściwości. W niektórych scenariuszach fasola jest fasolką EJB Singleton.injectionPoint.getBean() zwraca null, jeśli komponent bean jest komponentem EJB w języku Java EE 7 (CDI 1.1)

Uprościliśmy kod, aby skoncentrować się na problemie.

mój prosty kwalifikator:

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

Proste producent:

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

}

Console wyjście:

Info: ip = [BackedAnnotatedField] @Inject @InjectMe prywatny com.test.ejb.SimpleSingleton.injectMe, bean=null

Kiedy zmienić Singleton fasola szparagowa do CDI wszystko działa w porządku (ip.getBean() powraca not null). Pracował również w Java EE 6, nawet z ziarnami Singleton, ale nie ma go w Java EE 7. Używam serwera aplikacji Glassfish 4.

Czy to zachowanie jest określone gdzieś?

+0

Brzmi jak błąd glassfish. –

+0

@JohnAment: Nie sądzę, to samo zachowanie dla WildFly. Nie można jeszcze odpowiedzieć na pytanie, ale możliwe przyczyny to: 1) zmiana zachowania modułu Disc Beans (domyślnie: "adnotowane"); 2) wstrzykiwanie (niezwiązanego z kontekstem) ciągu klasy; 3) bez zadeklarowanego zakresu innego niż 'Zależny' –

+0

Jeśli wywołasz metodę' ip.getMember(). GetDeclaringClass() ', otrzymasz dla obu przypadków FQCN, jest to również używane jako przykład w dokumencie InjectionPoint API i Widziałem to w przykładzie Deltaspike jako połączenie uzupełniające po 'bean' jest' null'. –

Odpowiedz

1

Korzystanie

injectionPoint.getMember().getDeclaringClass() 

działa na mnie w JBoss Application Server 10.1.0 i ja też go szybko przetestowany w Payara Server 4.1.1.162 #badassfish (build 116). Zrobiłem również test na zupełnie nowym serwerze Payara 4.1.1.164 #badassfish (kompilacja 28). Musiałem jednak zmienić zakres komponentu bean producenta na @ApplicationScoped. Domyślny zasięg nie działa. W moim przypadku, to nawet ma sens :)

Sposób

injectionPoint.getBean().getBeanClass() 

pracował dla mnie w starym Payara, ale nie w nowym JBoss Application Server 10.1.0.Final i nowy Payara Server 4.1.1.164 # badassfish (kompilacja 28).

Jeśli spojrzeć na Payara, aktualna nowa wersja 164 zawiera Weld 2.4.0. Finalna i WildFly 10.1.0Final używa wersji 2.3.5.Final. W obu wersjach klasyczny kod nie działa!

Wniosek jest taki, że na starszych implementacjach CDI (Weld) działa. W niektórych nowszych Weld (wprowadzone w Payara 161), zachowanie się zmieniło. Nie wiem, czy to celowe, czy nie.

Jednakże rozwiązanie jest użycie

injectionPoint.getMember().getDeclaringClass() 

i opisywanie fasoli producentowi

@javax.enterprise.context.ApplicationScoped 

adnotacji.

+1

Testowane na weblogic 12.2.1 (CDI 1.1) i mam również ten sam problem. Podczas gdy działało dobrze na weblogic 12.1.3 (CDI 1.0). Jak już powiedziałeś, rozwiązałem problem za pomocą 'injectionPoint.getMember(). GetDeclaringClass()' – Rouliboy

+0

Wygląda na to, że jest już rozpoznany: https://issues.jboss.org/browse/WELD-2339 –