Search code examples
propertiescdi

properties using cdi @Produces and @Inject with qualifiers


I am trying to come up with an easy to use CDI way to use properties. Based on several blogs this is the (not working) result (sorry for the layout cannot get that right).

1. EEProperties (the provider, seperate jar):

@Singleton
public class EEProperties extends AbstractPropertiesDecorator {
    @Inject
    public EEProperties(@InjectInEEProperties EnhancedMap properties) {
        super(properties);
    }

    private String[] getKeys(final InjectionPoint ip) {
        return (ip.getAnnotated().isAnnotationPresent(Property.class) && ip.getAnnotated().getAnnotation(Property.class).keys().length>0) ?
            ip.getAnnotated().getAnnotation(Property.class).keys() :
            new String[] {ip.getMember().getName()};
    }

    @Produces
    @Property
    public File[] getFileProperties(InjectionPoint ip) {
        return getFileProperties(null, getKeys(ip));
    }
}

2. A ManagedBean consumer (in war):

@Inject
@Property(keys = {"test"})
private String test;

3. ...that also produces the constructor argument for the provider:

@Produces
@InjectInEEProperties
public EnhancedMap getP() {

    EnhancedMap m = new Settings();
    m.put("test", "cdi works");
    return m;
}

4. annotation for cdi container:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD,ElementType.METHOD,ElementType.PARAMETER})
public @interface InjectInEEProperties {

   @Nonbinding String key() default "";   
}

5. annotation for consumer:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD,ElementType.METHOD})
public @interface Property {

   @Nonbinding String[] keys() default {};   
}

6. problem when running this (on payara 5):

Caused by: java.lang.NullPointerException at org.glassfish.weld.services.JCDIServiceImpl.createManagedObject(JCDIServiceImpl.java:463) at org.glassfish.weld.services.JCDIServiceImpl.createManagedObject(JCDIServiceImpl.java:314) at com.sun.enterprise.container.common.impl.managedbean.ManagedBeanManagerImpl.createManagedBean(ManagedBeanManagerImpl.java:476)

I've tried a lot of things, but cannot get this to work, including removing the @Produces from the ManagedBean.


Solution

  • Solved the issue by creating a seperate class responsible for providing constructor argument:

    @Singleton
    public class PP {
    
        @Produces
        @InjectInEEProperties
        public EnhancedMap getP() {
            EnhancedMap m = new Settings();
            m.put("test", "cdi works");
            return m;
        }
    
    }