我正在使用 Netbeans 16 通过 Gradle、Jakarta EE 9 和 PrimeFaces 12 创建一个 Web 项目。基本项目创建工作正常,并在 Glassfish 6.2.5 服务器上正确部署。
添加 Jakarta EE 和 PrimeFaces 依赖项(不对项目进行任何其他修改)时,将其部署到 Glassfish 服务器时会生成以下错误:
部署期间发生错误:加载应用程序时出现异常:java.lang.IllegalStateException:ContainerBase.addChild:start:org.apache.catalina.LifecycleException:java.lang.RuntimeException:java.lang.IllegalStateException:CDI不可用。请参阅 server.log 了解更多详细信息。
项目文件如下:
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>
我进行了两项测试:
您需要在应用程序中启用 CDI 功能。在 WEB-INF 目录中创建一个空的 beans.xml 文件,或者创建一些类并在该类上添加 @ApplicationScoped 注释。
为什么:
Primefaces 启动 JSF 容器。在 GlassFish 6 中,JSF 容器需要 CDI 功能。但 GlassFish 6 中存在“设计缺陷”,因为如果 CDI 尚未启动,JSF 将不会启动 CDI。如果您的应用程序中没有任何内容可以触发 CDI,您会收到此错误。
我重现了此错误,只需将 PrimeFaces Jakarta JAR 放入 GlassFish 7 上的普通 Jakarta EE 10 中,不带任何 CDI 元素(是的,与 GlassFish 6 中的行为相同)。
如果您对堆栈跟踪感兴趣,这里是(在 GlassFish 7.0.6 上):
Critical error during deployment:
java.lang.IllegalStateException: CDI is not available
at com.sun.faces.util.Util.getCdiBeanManager(Util.java:1494)
at com.sun.faces.el.ELUtils.addCDIELResolver(ELUtils.java:199)
at com.sun.faces.el.ELUtils.buildFacesResolver(ELUtils.java:166)
at com.sun.faces.application.ApplicationAssociate.initializeELResolverChains(ApplicationAssociate.java:416)
at com.sun.faces.application.applicationimpl.ExpressionLanguage.performOneTimeELInitialization(ExpressionLanguage.java:144)
at com.sun.faces.application.applicationimpl.ExpressionLanguage.getELResolver(ExpressionLanguage.java:89)
at com.sun.faces.application.ApplicationImpl.getELResolver(ApplicationImpl.java:200)
at com.sun.faces.el.ELContextImpl.<init>(ELContextImpl.java:60)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:202)
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3911)
at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:601)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4450)
at com.sun.enterprise.web.WebModule.start(WebModule.java:551)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:935)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:917)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:644)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1796)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1484)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:88)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:97)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:262)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:353)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:535)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:259)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:467)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:570)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:566)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/javax.security.auth.Subject.doAs(Subject.java:376)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:596)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:588)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/javax.security.auth.Subject.doAs(Subject.java:376)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:587)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1478)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1847)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1723)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:535)
at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:222)
at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:150)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:425)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:144)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:174)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:153)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:196)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:88)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:246)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:178)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:118)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:96)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:51)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:510)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:82)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:83)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:101)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
at java.base/java.lang.Thread.run(Thread.java:833)
此问题已在 https://github.com/eclipse-ee4j/glassfish/issues/24336 中报告。但我不确定这是 GlassFish 中的错误还是预期行为。
如果您想使用 Spring IOC 而不是 CDI,并且完全想禁用 CDI,您需要更新 jboss-deployment-struct.xml。 排除模块resteasy-cdi并排除子系统焊接。 这解决了我使用 jboss 8 部署 Spring Boot 3 应用程序的问题。