SAM February 2016

How to get ApplicationScoped producer in Java SE via weld?

I'm trying to implement dependency injection in my Java SE program using weld and I have problems using an application scoped producer. This is a PoC of my problem with minimal code. The MyBean class:

public class MyBean implements Serializable{
  private int value;

  public MyBean(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }

  public void setValue(int value) {
    this.value = value;
  }
}

The injection point:

@Path("api")
public class MyResource implements Serializable {
  @Inject
  private MyBean bean;

  @GET
  @Path("bean")
  @Produces(MediaType.APPLICATION_JSON)
  public Response getBean() {
    return Response.ok(bean).build();
  }
}

The producer that I want it's produced instance be @ApplicationScoped is:

public class BeanProducer {

  @Produces
  @ApplicationScoped
  public MyBean beanProducer(){
    System.out.println("producing");
    return new MyBean(42);
  }
}

And it all bound together in a main class:

public class Main {
  public void main(@Observes ContainerInitialized event) {
    try {
      URI baseUri = UriBuilder.fromUri("http://localhost").port(1234).build();
      ResourceConfig config = new ResourceConfig(MyResource.class)
          .register(JacksonFeature.class);
      SimpleServer server = SimpleContainerFactory.create(baseUri, config);
      System.in.read();
      server.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

When I try to run this, I get following exception:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001410: The injection point [BackedAnnotatedField] @Inject @ApplicationScoped private MyResource.bean has non-proxyable dependencies at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.

Answers


John Ament February 2016

This happens because @ApplicationScoped is a normal scope, it needs to be proxyable. To be proxyable, you need a no-args constructor.

To clarify one of your points

it works as I want, means I will have a single instance of the bean in the entire lifecycle of my app.

This isn't accurate. Injection points don't define scope, the producer does. There's just no type-safe way to do this in Java, since you can have a producer field.

Post Status

Asked in February 2016
Viewed 3,938 times
Voted 8
Answered 1 times

Search




Leave an answer