jsfundertowspring-boot-3joinfaces

IllegalStateException: CDI is not available


I have a JSF application which I'm rebuidung to using JoinFaces and Spring Boot 3

The dependencies I'm using are:

jsf-spring-boot-starter version 5.3.13
jakarta.faces:jakarta.faces-api version 4.0.1
org.glassfish:jakarta-faces version 4.1.4
org.primefaces:primefaces version 14.0.12

and

org.springframework.boot:spring-boot-starter-undertow version 3.3.12

or

org.joinfaces:undertow-spring-boot-starter version 5.3.13

I'm not sure if I have to use spring-boot-starter-undertow or undertow-spring-boot-starter

I also excluded spring-boot-starter-tomcat and spring-boot-starter-logging in the depepency deklaration for jsf-spring-boot-starter, because I want to use undertow.

I don't want to use CDI and I want Spring to handle the depencendy injection and so on.

While starting the application, I get following error:

Caused by: java.lang.IllegalArgumentException: CDI is not available
   at com.sun.faces.util.Util.getCdiBeanManager(Util.java:1534) ~[jakarta.faces-4.1.3.jar:4.14]
   at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:126) ~[jakarta.faces-4.1.3.jar:4.14]
   at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187) ~[undertow-servet-2.3.18.Final.jar:2.3.18.Final]
...

I'm not sure why I get this error. I think I have my dependencies mixed up or some configuration is missing.

Maybe it is because I still have org.glassfish:jakarta-faces version 4.1.4 in my pom.xmls and this tries to start CDI?


Solution

  • Yeah your right, The CDI is not available error in a JoinFaces + Spring Boot setup almost always comes from having a mismatched or redundant JSF implementation on the classpath that expects CDI (Weld or similar), even though Spring is managing DI.

    You’re getting the

    Caused by: java.lang.IllegalArgumentException: CDI is not available
    

    error because your dependencies are pulling in GlassFish’s Mojarra implementation, which tries to initialize CDI by default. That happens because of this line in your pom.xml:

    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>jakarta-faces</artifactId>
      <version>4.1.x</version>
    </dependency>
    

    and also:

    <dependency>
      <groupId>jakarta.faces</groupId>
      <artifactId>jakarta.faces-api</artifactId>
    </dependency>
    

    You don’t need either of those when using JoinFaces. JoinFaces already brings in a compatible JSF implementation and integrates it with Spring instead of CDI. Having the explicit GlassFish dependency is what triggers that CDI error.

    The following is what i recommend you should do, remove the above dependencies and just use something like this:

    <dependency>
      <groupId>org.joinfaces</groupId>
      <artifactId>jsf-spring-boot-starter</artifactId>
      <version>5.3.13</version>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    
    <dependency>
      <groupId>org.joinfaces</groupId>
      <artifactId>undertow-spring-boot-starter</artifactId>
      <version>5.3.13</version>
    </dependency>
    
    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>14.0.12</version>
    </dependency>
    

    also between,

    spring-boot-starter-undertow

    and,

    undertow-spring-boot-starter

    use the JoinFaces Undertow starter (undertow-spring-boot-starter) — it’s already configured to work properly with JSF. No need to add spring-boot-starter-undertow separately.

    Once you clean up the dependencies, JSF should start without trying to load CDI, and Undertow will work as expected with Spring DI.