-1

When injecting java.util.Random into a Bean, deployment fails:

CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Random with qualifiers @Default at injection point [BackedAnnotatedField] @Inject myPackage.MyBean.random

Question: Why can't an instance of the java.util.Random class be injected ?

I created a class A with similar properties (like having a final method with default visibility) that injects without problems. Here's the code:

@Named
@SessionScoped 
public class MyBean implements Serializable { 
  @Inject private java.util.Random random;   // (R) 
  @Inject private A a; 
  ...
} 

public class A implements Serializable { 
  int n; 
  public A() { System.out.println("A"); }
  public A(int n) { this.n = n; }  
  final int nextInt(int bound) { return bound -n; } 
} 

If line (R) is commented out, everything deploys and runs fine.

user120513
  • 531
  • 4
  • 12

3 Answers3

5

You cannot inject java.util.Random as a bean because your application does not recognize any bean or producer of that given type.

You have beans.xml with discovery all - meaning CDI will go over classes within your application and turn them into beans if possible (if they meet the requirements set by CDI specification). java.util.Random is not withing your application and hence CDI knows no way to instantiate such bean for you and throws an exception. On the other hand your A bean is within your application and since you have discovery to all and it meets the requirements, CDI will consider it a bean (of @Dependent scope with @Any and @Default qualifiers).

To be able to inject java.util.Random, you need to tell CDI how to do that. You can achieve that fairly easily with a producer method. Note that producer method must be declared inside CDI bean in order for CDI to find it.

@Produces
@Dependent //choose desired scope, or none and it will be dependeny
// you can also add qualifiers, optional
public Random produceRandom() {
  return new Random();
}

With the above producer, CDI will not detect it and be able to create such object when you need to @Inject it.

Siliarus
  • 6,393
  • 1
  • 14
  • 30
1

For a class to be discovered as a bean, it has to be deployed in a bean archive, see http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_archive

As far as I understand, this also includes something like target/classes, but not the contents of rt.jar.

As I think that your question is only about the general mechanics and not about "how-to-inject-Random", I'll leave it at that. See the other answers on how to make Random injectable by a producer method.

mtj
  • 3,381
  • 19
  • 30
-1

Your class has to be discovered by CDI as a bean. For that you have to do something like this:

Put a bean defining annotation on it. As @Model is a stereotype it's why it does the trick. A qualifier like @Named is not a bean defining annotation, probably the reason why it doesn't work.

Vitruvie
  • 2,327
  • 18
  • 25
Tom
  • 224
  • 3
  • 9
  • Neither A nor java.util.Random has a corresponding annotation. The question is: Why can (an instance of) A be injected but Random not ? I should add that I've an empty beans.xml file in the WEB-INF directory for instructing the container to discover CDI beans. – user120513 Feb 05 '18 at 02:41