问题
Is it possible to inject EJB 3.1 beans into POJO using CDI on Glassfish v3?
My classes (in EJB module):
@Singleton
@LocalBean
@Startup
@Named
public class NewSingletonBean {
@PostConstruct
public void init(){
System.out.println("NewSingletonBean INIT");
}
}
_
@Singleton
@LocalBean
@Startup
@DependsOn(value="NewSingletonBean")
public class NewSingletonBean2 {
@Inject NewSingletonBean newSingletonBean;
@PostConstruct
public void init(){
System.out.println("NewSingletonBean2 INIT");
System.out.println("EJB injected into EJB: " + (newSingletonBean != null));
MyPOJO p = new MyPOJO();
p.sth();
}
}
_
public class MyPOJO {
@Inject NewSingletonBean newSingletonBean;
public void sth(){
System.out.println("EJB injected into POJO: " + (newSingletonBean != null));
}
}
Server output:
Launching GlassFish on Felix platform
INFO: Registered org.glassfish.ha.store.adapter.cache.ShoalBackingStoreProxy for persistence-type = replicated in BackingStoreFactoryRegistry
INFO: Grizzly Framework 1.9.31 started in: 31ms - bound to [0.0.0.0:4848]
INFO: Grizzly Framework 1.9.31 started in: 109ms - bound to [0.0.0.0:8080]
INFO: Grizzly Framework 1.9.31 started in: 62ms - bound to [0.0.0.0:8181]
INFO: Grizzly Framework 1.9.31 started in: 141ms - bound to [0.0.0.0:3700]
INFO: Grizzly Framework 1.9.31 started in: 0ms - bound to [0.0.0.0:7676]
INFO: GlassFish Server Open Source Edition 3.1 (43) startup time : Felix (2 812ms), startup services(1 172ms), total(3 984ms)
INFO: JMXStartupService: Started JMXConnector, JMXService URL = service:jmx:rmi://9.167.213.195:8686/jndi/rmi://9.167.213.195:8686/jmxrmi
INFO: Hibernate Validator 4.1.0.Final
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
INFO: Grizzly Framework 1.9.31 started in: 16ms - bound to [0.0.0.0:8080]
INFO: Grizzly Framework 1.9.31 started in: 16ms - bound to [0.0.0.0:8181]
INFO: SEC1002: Security Manager is OFF.
INFO: SEC1010: Entering Security Startup Service
INFO: SEC1143: Loading policy provider com.sun.enterprise.security.provider.PolicyWrapper.
INFO: SEC1115: Realm [admin-realm] of classtype [com.sun.enterprise.security.auth.realm.file.FileRealm] successfully created.
INFO: SEC1115: Realm [file] of classtype [com.sun.enterprise.security.auth.realm.file.FileRealm] successfully created.
INFO: SEC1115: Realm [certificate] of classtype [com.sun.enterprise.security.auth.realm.certificate.CertificateRealm] successfully created.
INFO: SEC1011: Security Service(s) Started Successfully
INFO: WEB0169: Created HTTP listener [http-listener-1] on host/port [0.0.0.0:8080]
INFO: WEB0169: Created HTTP listener [http-listener-2] on host/port [0.0.0.0:8181]
INFO: WEB0169: Created HTTP listener [admin-listener] on host/port [0.0.0.0:4848]
INFO: WEB0171: Created virtual server [server]
INFO: WEB0171: Created virtual server [__asadmin]
INFO: WEB0172: Virtual server [server] loaded default web module []
INFO: Portable JNDI names for EJB NewSingletonBean2 : [java:global/CDITest/CDITest-ejb/NewSingletonBean2!tries.NewSingletonBean2, java:global/CDITest/CDITest-ejb/NewSingletonBean2]
INFO: Portable JNDI names for EJB NewSingletonBean : [java:global/CDITest/CDITest-ejb/NewSingletonBean!tries.NewSingletonBean, java:global/CDITest/CDITest-ejb/NewSingletonBean]
INFO: WELD-000900 ${parsedVersion (osgiVersion})
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
INFO: NewSingletonBean INIT
INFO: NewSingletonBean2 INIT
INFO: EJB injected into EJB: true
INFO: EJB injected into POJO: false
INFO: WEB0671: Loading application [CDITest#CDITest-war.war] at [CDITest-war]
INFO: CDITest was successfully deployed in 3 531 milliseconds.
Note lines:
INFO: EJB injected into EJB: true
INFO: EJB injected into POJO: false
So it looks like @Inject into EJB works fine, but into POJO doesn't. What am I doing wrong? I've tried on GlassFish 3.1 and 3.0.1 (with NetBeans 7.0.1).
EDIT: I'm using NetBeans 7.0.1. dist directory structure:
│ CDITest.ear
│
└───gfdeploy
└───CDITest
├───CDITest-ejb_jar
│ │ .netbeans_automatic_build
│ │ .netbeans_update_resources
│ │
│ ├───META-INF
│ │ beans.xml
│ │ MANIFEST.MF
│ │
│ └───tries
│ MyPOJO.class
│ NewSingletonBean.class
│ NewSingletonBean2.class
│
├───CDITest-war_war
│ │ index.jsp
│ │
│ ├───META-INF
│ │ MANIFEST.MF
│ │
│ └───WEB-INF
│ └───classes
│ .netbeans_automatic_build
│ .netbeans_update_resources
│
└───META-INF
MANIFEST.MF
Unpacked EAR structure:
│ CDITest-ejb.jar
│ CDITest-war.war
│
└───META-INF
MANIFEST.MF
Unpacked EJB module jar structure:
├───META-INF
│ beans.xml
│ MANIFEST.MF
│
└───tries
MyPOJO.class
NewSingletonBean.class
NewSingletonBean2.class
回答1:
I'm not very familiar with CDI but I guess if you're creating the POJO object yourself, no injection will happen. Did you try:
@Inject
private MyPOJO p;
Instead of:
MyPOJO p = new MyPOJO();
?
回答2:
Well I'm able to inject EJBs (and other resources) in non-EJB classes (like Servlets and DAOs) either using @EJB or @Inject. Normally you'd use @EJB to inject an ejb and @Inject for injecting a non-ejb resource.
Also, don't forget about the "beans.xml" file, this is needed to activate CDI:
http://download.oracle.com/javaee/6/tutorial/doc/gjbnz.html
I think this might be your problem. Missing this file in fact desactivates CDI, but you're still getting stuff injected into your EJBs only because this was possible even in the pre CDI versions of Java EE.
来源:https://stackoverflow.com/questions/8165482/cdi-inject-ejb-into-pojo-on-glassfish-v3