6 Replies Latest reply on Jun 20, 2010 10:13 PM by wu haixing

    Injection of a proxied interface

    alberto Gori Novice

      I am trying to write an extension where a particular annotated interface is implemented at startup (using CGLIB) generating a proxy class.
      Then user should be allowed to inject this implementation:

      @Inject MyInterface bean;

      The problem is that WELD can't resolve the dependency, and I don't know why.
      The extension is this:

      Enhancer e = new Enhancer();
      e.setInterfaces(new Class[]{javaClass}); //it is MyInterface
      final Class proxyClass = e.create().getClass();
      AnnotatedTypeBuilder builder = AnnotatedTypeBuilder.newInstance(proxyClass).readAnnotationsFromUnderlyingType();
      BeanBuilder beanBuilder = new BeanBuilder(builder.create(), bm);
      Bean bean = beanBuilder.create();

      As you can see I am using weld exception to build the Bean object. The Bean is then added on AfterBeanDiscovery event.
      What is wrong with my idea/code?

      The exception is:

      Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Injection point has unsatisfied dependencies.  Injection point:  field org.lambico.cdi.LambicoTest.dao;  Qualifiers:  [@javax.enterprise.inject.Default()]
           at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:276)
           at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:122)
           at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:141)
           at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:331)
           at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:317)
           at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:399)
           at org.jboss.arquillian.weld.WeldSEContainer.deploy(WeldSEContainer.java:113)
           at org.jboss.arquillian.impl.handler.ContainerDeployer.callback(ContainerDeployer.java:62)
           at org.jboss.arquillian.impl.handler.ContainerDeployer.callback(ContainerDeployer.java:50)
           at org.jboss.arquillian.impl.event.MapEventManager.fire(MapEventManager.java:63)
           ... 14 more

        • 1. Re: Injection of a proxied interface
          wu haixing Newbie

          I implemented something similiar with @Produce and override type extesion,reference GenericDAO in the forum.
          I think the document told us there is a typesafe resolution  and what is considered is a bean .

          • 2. Re: Injection of a proxied interface
            he youlin Novice

            I gues you should veto your original MyInterface or extension from ProcessAnnotatedType so you have only one MyInterface bean define.

            • 3. Re: Injection of a proxied interface
              Stuart Douglas Master


              should probably be:

              beanBuilder.getQualifiers.add(new AnnotationLiteral<Default>(){});

              • 4. Re: Injection of a proxied interface
                alberto Gori Novice

                Ok I was able to implement this in WELD. For completeness I report the code here so that you can comment it and tell me where I can improve the WELD and CGLIB part.
                I see there is another implementation in this forum of a generic dao in WELD, but following a different approach with producer and interceptor. Maybe this extension is a little cleaner because doesn't force the user to configure an interceptor and doesn't need to write an empty producer.

                Dao.java (the annotation)

                @Target({ ElementType.TYPE })
                public @interface Dao {
                     Class<?> value();

                GenericDao interface

                public interface GenericDao<T, PK extends Serializable> {
                     T load(PK id);

                Generic dao implementation

                public class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK> {
                    private Class<T> type;
                     public T load(PK id) {
                          System.out.println("load object of type " + getType().getName() + " from id " + id);
                          try {
                               return getType().newInstance();
                          } catch (Exception e) {
                               throw new RuntimeException(e);
                     public void setType(Class<T> type) {
                          this.type = type;
                     public Class<T> getType() {
                          return type;

                CDI Extension.java:

                public class MyExtension implements Extension {
                     private final Collection<Bean<?>> additionalBeans = new ArrayList<Bean<?>>();
                     public <X> void processAnnotatedType(
                               @Observes final ProcessAnnotatedType<X> pat, final BeanManager bm) {
                          final AnnotatedType<X> at = pat.getAnnotatedType();
                          if (!at.isAnnotationPresent(Dao.class)) {
                          final Class<X> javaClass = at.getJavaClass();
                          final Enhancer e = new Enhancer();
                          e.setInterfaces(new Class[]{javaClass});
                          e.setCallback(new MethodInterceptor() {
                               public Object intercept(Object target, Method method, Object[] args,
                                         MethodProxy proxy) throws Throwable {
                                    if (method.getName().equals("setType")) {
                                         return proxy.invokeSuper(target, args);
                                    GenericDaoImpl genericDaoImpl = (GenericDaoImpl) target;
                                    return proxy.invokeSuper(target, args);
                          final Class proxyClass = e.create().getClass();
                          AnnotatedTypeBuilder builder = AnnotatedTypeBuilder.newInstance(proxyClass)
                          BeanBuilder beanBuilder = new BeanBuilder(builder.create(), bm);
                          beanBuilder.setBeanLifecycle(new BeanLifecycleImpl() {
                               public Object create(BeanImpl bean, CreationalContext creationalContext) {
                                     Object instance = e.create();
                                     bean.getInjectionTarget().inject(instance, creationalContext);
                                     return instance;
                          beanBuilder.getQualifiers().add(new AnnotationLiteral<Default>(){});
                          Bean bean = beanBuilder.create();
                     void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
                          for (Bean<?> bean : additionalBeans) {

                Arquillian test:

                public class LambicoTest {
                     public static Archive<?> createTestArchive() {
                          Archive<?> archive = ShrinkWrap.create("test.jar", JavaArchive.class)
                        .addPackages(true, LambicoTest.class.getPackage())
                        .addServiceProvider(Extension.class,  LambicoExtension.class);
                          return archive;
                     @Inject MyDao dao;
                     public void test() {
                          User user = dao.load(2L);

                • 5. Re: Injection of a proxied interface
                  wu haixing Newbie

                  Another approach no interceptor to config,and producer is responsiable to create proxy class as you do in the extension.

                  • 6. Re: Injection of a proxied interface
                    wu haixing Newbie

                    Does InjectionTarget more suit this work?