Jump to: navigation, search

Hudson-ci/features/Java EE7 Support

Hudson uses dependency injection based on Guice by Google and does not use CDI that is now a standard part of Java EE (6 and later).

(No problem before Java EE 7) Java EE 6 included CDI 1.0 but it is not automatically enabled if beans.xml is not included, so Hudson is happy with any Java EE 6 servers.

(Problem with Java EE 7) To resolve issues that many users forget to include beans.xml (I guess), CDI 1.1 introduced bean discovery modes and CDI is automatically enabled in the 'annotated' mode even if there is no beans.xml (see Default CDI Enablement in Java EE 7). At least one (and the reference) CDI implementation, Weld by JBoss, tries to discover a bean that can be injected to any method and field annotated with @Inject even if it will not actually use CDI for injection, which causes conflicts to the use of @Inject in Hudson.

(Workaround) Most (or all) Java EE 7 servers has an option to disable the automatic CDI when deploying an application. By disabling the automatic CDI, Hudson can be deployed successfully on such servers. A problem is the way to activate the option differs by servers.

(No simple resolution) Although CDI 1.1 introduced bean discovery modes and one of which is 'none', CDI 1.0 implementations will not see the value and might enable CDI by the existence of beans.xml contrary to the intent to disable it. So including beans.xml is not an option to resolve this problem at all.

Hudson works in EE containers 5.x and below because there is no CDI. It also works in EE 6 because CDI is not enabled by default. However DI works in Hudson because Guice used in Hudson properly takes care of DI annotations (@Inject etc).

In EE7 CDI is enabled. Since CDI finds DI annotations in the code, it thinks it service is required. However, since it finds the wrong Injection Helpers (Specified as a Singleton), which is really meant for Guice, it throws error.

Three suggestions so far:

1. Add some dummy implementation for CDI Injection Helpers, so CDI will be happy, though it does nothing. But still Guice takes care of the DI annotations

2. Change all javax.inject.Singleton to com.google.inject.Singleton. Since CDI will not understand this annotation, it will not try to incorrectly use the Injection Helpers and throw exception. However, Guice understands this annotation and works a normal.

3. Replace Guice with CDI for a cleaner core.

Option 3 is the cleaner solution and is the most difficult choice. It can drop support for Java EE 5 servers and even for newer ones such as Tomcat or Jetty that do not support CDI out of the box unless a CDI implementation is bundled with Hudson.

Option 2 might be impossible since (at least) Weld tries to find the @javax.inject.Inject annotations in all managed beans even if they have no annotations. Any class that has a constructor with no parameters and has no annotations is implicitly a managed bean in CDI. Even if it is not discovered in the default 'annotated' discovery mode, all @Inject annotations in managed beans will be checked for dependencies.

An experimental implementation for option 1 is under review (part 1 and part 2). An alternative version that throws a RuntimeException instead of just returning null is also in drafts (part 1 and part 2).