Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can CDI inject standard library POJOs into an EJB?

Tags:

java

cdi

ejb

I can inject my own POJO into a managed object like this:

import javax.ejb.Stateless;
import javax.inject.Inject;
@Stateless
public class SomeEjb {
    @Inject
    private SomePojo somePojo;
}

And I have this POJO:

// No annotations
public class SomePojo {   
}

This works fine. If I inject the EJB into a JSF backing-bean, I can see that the value of somePojo is non-null value, as expected.

However, if I try to inject a java.util.Date into SomeEjb, I get the following exception on deployment:

Severe: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)

SomeEjb now:

// No annotations
public class SomeEjb {
    @Inject
    private Date date;    
}

Date has a public, no-argument constructor, and I thought that's all CDI would need to "satisfy the dependency". I'm sure this behaviour is "to spec", but clearly there's a big hole in my understanding of CDI.

Can someone explain why this doesn't work? What's the difference between SomePojo and java.util.Date from a CDI perspective?

Context:

  • Java EE 6
  • GlassFish 3.1.2.2
  • I don't have a use-case for this. I know that I can just specify new Date().
like image 479
DavidS Avatar asked Apr 22 '15 19:04

DavidS


People also ask

What is CDI and EJB?

They are CDI, EJB3 and JSF Managed Beans. CDI is the new kid on the block. CDI beans feature dependency injection , scoping and an event bus . CDI beans are the most flexible with respect to injection and scoping. The event bus is very lightweight and very well suited for even the simplest of web applications.

How does an injected annotation work?

Injectable constructors are annotated with @Inject and accept zero or more dependencies as arguments. @Inject can apply to at most one constructor per class. @Inject is optional for public, no-argument constructors when no other constructors are present. This enables injectors to invoke default constructors.

What is CDI bean in Java?

A CDI bean is a POJO, plain old java object, that has been automatically instantiated by the CDI container, and is injected into all, and any qualifying injection points in the application. The CDI container initiates the bean discovery process during deployment.


1 Answers

I can reproduce this with EAP 6.3 as well.

The problem most likely occurs because of using Java EE 6. The java.util.Date is located in rt.jar and this JAR does not contain a beans.xml file which would enable CDI. You can only inject objects from JARs containing a beans.xml.

A common workaround is to use a producer method to inject such an object. You have to wirte this producer yourself but you will be able to inject objects from arbitrary classes regardless to which JAR they belong.

As far as I know the behaviour changed in Java EE 7, where the beans.xml is optional in some cases: https://blogs.oracle.com/theaquarium/entry/default_cdi_enablement_in_java

Hope that helps.

like image 154
roehrijn Avatar answered Oct 16 '22 21:10

roehrijn