使用Cargo Maven插件部署WAR到WildFly后EJB注入失败
Let's walk through the most common reasons why your TimerEjb2 is coming up null, even with a specified lookup—since your WAR deploys successfully and the JNDI binding is visible, the issue is likely tied to how your Testejb is managed or how you're referencing the EJB:
1. Is Testejb a container-managed class?
Dependency injection (whether via @EJB or CDI) only works for classes controlled by the application server's container. If Testejb is a plain Java class (e.g., you're instantiating it with new Testejb() yourself, or it has no EJB/CDI annotations), the container has no way to inject dependencies into it.
- Fix: Ensure
Testejbis a managed component:- If it's a business bean, annotate it with
@Stateless/@Stateful/@Singletonto make it an EJB - If it's a web component, use annotations like
@WebServletor@WebFilter - For CDI-managed beans, add a scope annotation like
@RequestScopedor@Named(and confirm yourbeans.xmlenables discovery)
- If it's a business bean, annotate it with
2. Verify your JNDI lookup name matches WildFly 10's format
WildFly uses a stricter JNDI naming convention than older JBoss AS versions. The global JNDI name for an EJB follows this pattern:
java:global/[application-name]/[module-name]/[bean-class-name]![fully-qualified-bean-class-name]
If the bean is in the same module as Testejb, you can use the shorter module-scoped name:
java:module/[bean-class-name]![fully-qualified-bean-class-name]
- Check your WildFly server logs for the exact bound name—look for lines like:
Bound Ejb with class name com.yourpackage.TimerEjb2 to java:global/your-app-name/your-war-name/TimerEjb2!com.yourpackage.TimerEjb2
- Make sure the
lookupvalue in your@EJBannotation exactly matches this string. Old-style names likeTimerEjb2/localwon't work in WildFly 10.
3. Validate your beans.xml configuration
WildFly 10 implements Java EE 7, where beans.xml defaults to bean-discovery-mode="annotated". This means CDI only recognizes classes with explicit CDI/EJB annotations.
- If
Testejbisn't an EJB, add a CDI scope annotation (like@RequestScoped) so the container picks it up. - Ensure
beans.xmlis correctly placed inWEB-INF/beans.xmland isn't malformed (no typos in XML structure).
4. Avoid static fields for injection
Static fields cannot be injected by the container—this is a common oversight. Make sure your injected field is non-static and uses a private modifier:
❌ Wrong:
@EJB(lookup = "your-jndi-name") private static TimerEjb2 timerEjb; // Will always be null
✅ Correct:
@EJB(lookup = "your-jndi-name") private TimerEjb2 timerEjb;
5. Confirm TimerEjb2 is properly packaged and annotated
- Double-check that
TimerEjb2has the correct@Statelessannotation (no typos like@Statefulor missing imports). - Verify the
TimerEjb2.classfile exists inWEB-INF/classesof your deployed WAR (you can extract the WAR to inspect its contents). - Ensure
TimerEjb2doesn't have conflicting annotations (e.g., mixing@ApplicationScopedwith@Statelesswithout proper configuration).
6. Check for class loader mismatches
If TimerEjb2 is in a separate EJB JAR module that your WAR depends on, ensure the dependency is properly declared in your pom.xml (use compile scope, not provided, if it's part of your deployment) and that the JAR is included in the WAR's WEB-INF/lib directory.
7. Look for injection warnings in WildFly logs
Check your server's server.log for specific warnings about injection failures—WildFly often logs details like:
- "Injection point has unsatisfied dependencies"
- "Could not resolve EJB reference"
These messages will pinpoint exactly what's going wrong.
内容的提问来源于stack exchange,提问作者robyp7

