Search code examples
jakarta-eedependency-injectioncdi

right place for putting all annotations and CDI beans in multi modules projects


I've an Enterprise Application with 5 maven modules (common-Jar,EJB,WEB,EAR,GAR)
the beans.xml file is under the Web module\webapp\WEB-INF and i use this code to list all the discovered beans:

Set<Bean<?>> beans = beanManager.getBeans(Object.class, new AnnotationLiteral<Any>() {
});
for (Bean<?> bean : beans) {
    System.out.println(bean.getBeanClass().getName());
}

but some of my classes (Entity classes with @Stateless annotation) have not been discovered. and i cant inject them to a field.(Error: unsatisfied dependency injection point)
Question 1: is there any Exception or limitation for discovered beans ?


** i create some Qualifier to clear ambiguous state but they can't be used in simple form like @MyQualifier and it must be use only by it's full reference name like @com.test.packagename.MyQualifier.
Question 2: what is the right place for putting all annotations and CDI beans in multi modules projects ?


Solution

  • Question 1: is there any Exception or limitation for discovered beans ?

    Yes, very many of them in fact. Welcome to Java EE. This whole thing is mandated by Java EE "umbrella" spec (JSR 342) to which CDI spec has to conform. For instance, WAR can see into EJB jar but not vice versa so this will translate into bean injection. Furthermore. EE umbrella spec is not exactly clear on many things so it happens that different AS (Wildfly, GlassFish,...) might slightly differ in their behaviour.

    Question 2: what is the right place for putting all annotations and CDI beans in multi modules projects ?

    Again not a simple thing to answer; due to visibility rules you need to decide if you care which deployments will see which beans. Then you can use different alternatives of the same base bean type in different WARs and so on and so forth. If you want it all accessible from all deployded archives, then EAR/lib is probably the place (NOTE: does not imply shared beans).

    Most projects choose to fine-grain this and put the bean into the archive which will need it. In case more archives need them, extract it (according to visibility rules) to an archive visible from all requires places (EAR/lib being the last resort).

    Also note that you will probably need to have beans.xml in multiple archives if you want to have CDI enabled there (not in all of them, but to simplify, if you put it there, it will be enabled for sure).

    Last but not least, your code to retrieve all beans might not work (as you expect it) because of the visibility rules - the BeanManager is restricted to only the accessible set of beans.