Glassfish 4.1.1通过JNDI配置项目阶段失败求助
我理解你的需求:让不同GlassFish服务器实例使用各自的JSF PROJECT_STAGE,同时不用每次Git推送时修改web.xml。结合GlassFish 4.1.1(自带JSF 2.2.12)的特性,我整理了以下排查和解决步骤:
先排查优先级冲突
首先确认你的web.xml中没有直接配置javax.faces.PROJECT_STAGE的context-param——如果存在这个配置,它的优先级会高于JNDI设置,导致你配置的JNDI值被覆盖。如果有下面这段代码,一定要删掉:
<!-- 请移除该配置,否则会覆盖JNDI设置 --> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Production</param-value> </context-param>
修正JNDI配置细节
你的现有配置已经接近正确,只需调整几个关键点:
1. web.xml的resource-ref配置(保持不变即可)
你的web.xml配置是正确的,JSF会通过jsf/ProjectStage资源引用,映射到服务器端的javax.faces.PROJECT_STAGE JNDI资源:
<resource-ref> <res-ref-name>jsf/ProjectStage</res-ref-name> <res-type>java.lang.String</res-type> <mapped-name>javax.faces.PROJECT_STAGE</mapped-name> </resource-ref>
2. domain.xml的custom-resource配置(关键修正)
在GlassFish 4.1.1对应的JSF 2.2版本中,ProjectStageJndiFactory需要的参数名称是value而非stage,同时确保配置格式规范:
<custom-resource jndi-name="javax.faces.PROJECT_STAGE" res-type="java.lang.String" factory-class="com.sun.faces.application.ProjectStageJndiFactory"> <property name="value" value="Development"/> </custom-resource>
必须执行:重启GlassFish服务器
GlassFish对domain.xml的修改不会实时生效,一定要重启对应服务器实例,让新的JNDI资源配置加载生效。
排查项目依赖冲突
如果以上步骤完成后仍未生效,大概率是项目打包了与服务器自带版本冲突的JSF库:
- GlassFish 4.1.1自带JSF 2.2.12,如果你的项目WEB-INF/lib中包含
javax.faces-api.jar、jsf-impl.jar等JSF相关jar包,会覆盖服务器的类,导致ProjectStageJndiFactory行为异常。 - 解决方法:如果用Maven/Gradle构建,将JSF相关依赖的scope设置为
provided,让项目运行时使用服务器自带的JSF库。
替代方案:用系统属性配置(更简单)
如果JNDI配置始终有问题,可以换一种更直接的方式:在domain.xml的<java-config>中添加JVM系统属性,同样能实现不同服务器用不同PROJECT_STAGE,且无需修改web.xml:
<java-config> <!-- 保留原有配置,添加下面的jvm-options --> <jvm-options>-Djavax.faces.PROJECT_STAGE=Development</jvm-options> </java-config>
这种方式优先级高,配置更直观,适合快速解决问题。
验证配置是否生效
你可以在JSF页面中添加以下代码验证:
<h3>当前项目阶段:#{facesContext.application.projectStage}</h3>
或在Java代码中获取并打印:
ProjectStage stage = FacesContext.getCurrentInstance().getApplication().getProjectStage(); System.out.println("当前PROJECT_STAGE:" + stage);
内容的提问来源于stack exchange,提问作者robinvrd

