NetBeans16+Gradle构建Jakarta EE9项目部署GlassFish时CDI不可用
用NetBeans 16创建了基于Gradle、Jakarta EE 9和PrimeFaces 12的Web项目,基础项目可正常部署到GlassFish 6.2.5服务器。但添加Jakarta EE和PrimeFaces依赖(未修改其他项目内容)后,部署时出现以下错误:
Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: java.lang.IllegalStateException: CDI is not available. Please see server.log for more details.
项目文件
build.gradle
apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'war' group = 'mygroup' repositories { mavenCentral() } dependencies { testImplementation 'junit:junit:4.13' compileOnly 'jakarta.platform:jakarta.jakartaee-api:9.1.0' implementation 'org.primefaces:primefaces:12.0.0:jakarta' }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"> <context-param> <param-name>jakarta.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
glassfish-web.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0, which is available at http://www.eclipse.org/legal/epl-2.0. This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License v. 2.0 are satisfied: GNU General Public License, version 2 with the GNU Classpath Exception, which is available at https://www.gnu.org/software/classpath/license.html. SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 --> <!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> <glassfish-web-app error-url=""> <class-loader delegate="true"/> <jsp-config> <property name="keepgenerated" value="true"> <description>Keep a copy of the generated servlet class' java code.</description> </property> </jsp-config> </glassfish-web-app>
测试情况
- 移除PrimeFaces依赖后,错误消失;
- 复制可正常部署的项目,仅保留
build.gradle、web.xml和glassfish-web.xml,仍出现“java.lang.IllegalStateException: CDI is not available”错误。
解决方法
1. 添加CDI启用配置文件
GlassFish 6.x默认支持CDI,但项目缺少标识文件触发CDI初始化。在src/main/resources/META-INF目录下创建beans.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd" version="3.0" bean-discovery-mode="all"> </beans>
bean-discovery-mode="all"会让CDI扫描项目所有类,适合开发阶段使用。
2. 调整依赖配置(可选)
PrimeFaces 12 Jakarta版本依赖CDI,当前jakarta.jakartaee-api使用compileOnly范围(仅编译时可用),GlassFish自带API实现,无需额外添加实现类,但可补充CDI API依赖确保编译时无缺失:
compileOnly 'jakarta.enterprise:jakarta.enterprise.cdi-api:3.0.0'
3. 更新glassfish-web.xml的DTD版本
当前glassfish-web.xml使用的是Servlet 3.0的DTD,与Jakarta EE 9(对应Servlet 5.0)不兼容,更新为GlassFish 6对应版本:
<!DOCTYPE glassfish-web-app PUBLIC "-//Eclipse Foundation//DTD GlassFish Application Server 6.0 Servlet 5.0//EN" "https://jakarta.ee/xml/ns/jakartaee/glassfish-web-app_5_0-1.dtd">
4. 清理并重新构建部署
执行gradle clean war清理旧构建文件,确保新配置和依赖被正确打包,之后重新部署到GlassFish。若仍有问题,查看server.log获取更详细的错误堆栈信息。
内容的提问来源于stack exchange,提问作者Antonio J. Vélez Q.

