本节介绍已知的 Web 容器问题和相应的解决办法。
如果您在 Windows 上部署应用程序时要求预编译 JSP,则以后尝试取消部署该应用程序或重新部署该应用程序(或任何具有相同模块 ID 的应用程序)的操作将不会按预期进行。出现此问题的原因是:JSP 预编译会打开应用程序中的 JAR 文件,但不能关闭这些文件,Windows 将禁止执行取消部署或重新部署操作以避免删除或覆盖它们。
请注意,取消部署在某种程度上是成功的,因为应用程序会从 Application Server 中被逻辑删除。另外请注意,asadmin 实用程序不会返回任何错误消息,但应用程序的目录以及锁定的 jar 文件会保留在服务器中。服务器的日志文件将包含用于说明未能删除文件和应用程序的目录的消息。
在取消部署后尝试重新部署应用程序的操作会失败,这是由于服务器尝试删除现有文件和目录,而这些尝试也失败了。如果您尝试部署的应用程序所使用的模块 ID 与最初部署的应用程序的模块 ID 相同,会出现这种情况,这是由于服务器在选择目录名来保存应用程序的文件时会使用模块 ID。
如果没有先取消部署应用程序而尝试重新部署该应用程序,也将会由于同样的原因而失败。
如果尝试重新部署应用程序或在取消部署后部署它,asadmin 实用程序将返回一个类似如下的错误。
An exception occurred while running the command. The exception message is: CLI171 Command deploy failed : Deploying application in domain failed; Cannot deploy. Module directory is locked and can't be deleted. |
如果在部署应用程序时指定 --precompilejsps=false(默认设置),则不会出现此问题。请注意,第一次使用应用程序时会触发 JSP 编译,因此第一个请求的响应时间将会长于随后的请求的响应时间。
另外,请注意,如果您确实进行了预编译,则在取消部署或重新部署应用程序之前,应先停止并重新启动服务器。关闭服务器后将释放锁定的 JAR 文件,这样在重新启动服务器后,取消部署或重新部署便可以成功。
web.xml 中的可选 load-on-startup servlet 元素表示相关的 servlet 将在启动对其进行声明的 Web 应用程序期间被加载和初始化。
此元素的可选内容是一个整数,用于表示该 servlet 相对于 Web 应用程序的其他 servlet 而被装入和初始化的顺序。只要该 servlet 在包含它的 Web 应用程序启动期间被加载和初始化,空的 <load-on-startup> 就表示顺序无关紧要。
web.xml 的 Servlet 2.4 模式不再支持空的 <load-on-startup>,这意味着在使用基于 Servlet 2.4 的 web.xml 时,必须指定一个整数。如果像在 <load-on-startup/> 中一样指定空的 <load-on-startup>,则 web.xml 将无法针对 web.xml 的 Servlet 2.4 模式进行验证,从而导致 Web 应用程序的部署失败。
向下兼容性问题。指定空的 <load-on-startup> 在基于 Servlet 2.3 的 web.xml 中仍起作用。
在使用基于 Servlet 2.4 的 web.xml 时,指定 <load-on-startup>0</load-on-startup>,以表明 servlet 的装入顺序无关紧要。
已访问 JSP 页面但是无法对其进行编译,并且服务器日志包含错误消息“无法执行命令”和以下堆栈跟踪:
at org.apache.tools.ant.taskdefs.Execute$Java13CommandLauncher. exec(Execute.java:655) at org.apache.tools.ant.taskdefs.Execute. launch(Execute.java:416) at org.apache.tools.ant.taskdefs.Execute.execute(Execute.java:427) at org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter. executeExternalCompile(DefaultCompilerAdapter.java:448) at org.apache.tools.ant.taskdefs.compilers.JavacExternal.execute (JavacExternal.java:81) at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:842) at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:682) at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:396) |
将 JSP 编译开关 "fork" 设置为 "false"。
可以通过以下两种方式之一来实现:
在全局范围内,通过将 domain-dir/config/default-web.xml 中 JspServlet 的 fork 初始化参数设置为 false:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> .... <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> .... </servlet> |
在每个 Web 应用程序基础上,通过将 sun-web.xml 中的 fork JSP 配置属性设置为 false:
<sun-web-app> <jsp-config> <property name="fork" value="false" /> </jsp-config> </sun-web-app> |
以上任何一种设置都将阻止 ant 产生用于 javac 编译的新进程。
Sun GlassFish Enterprise Server 2.1.1 添加了对 Sun GlassFish Enterprise Server Enterprise Edition 7.1 中可用的 auth-passthrough 插件功能所提供的功能的支持。但是,在 Enterprise Server 2.1.1 中,auth-passthrough 插件功能的配置有所不同。
Enterprise Server Enterprise Edition 7.1 中的 auth-passthrough 插件功能在双层部署方案中非常有用,其中:
Application Server 实例受公司防火墙之后的第二层防火墙的保护。
不允许客户机直接连接到 Application Server 实例。
在这种网络体系架构中,客户机连接到前端 Web 服务器,而该 Web 服务器配置有 service-passthrough 插件功能,会将 HTTP 请求转发到代理的 Application Server 实例以供处理。Application Server 只能从 Web 服务器代理接收请求,而决不会从任何客户机主机接收请求。因此,当部署在代理的 Application Server 实例上的任何应用程序查询客户机信息时,该应用程序将收到代理主机的信息(例如,当该应用程序查询客户机 IP 地址时,会收到代理主机的 IP),这是因为代理主机才是中继请求的真正发出主机。
在 Application Server Enterprise Edition 7.1 中,可以在代理 Application Server 实例上配置 auth-passthrough 插件功能,以使该实例上所部署的所有应用程序可以直接获得远程客户机的信息,就像代理 Application Server 实例直接收到请求那样,而不是通过运行 service-passthrough 插件的中间 Web 服务器接收。
在 Enterprise Server 2.1.1 中,可以通过将 domain.xml 中 <http-service> 元素的 authPassthroughEnabled 属性设置为 TRUE 来启用 auth-passthrough 功能,如下所示:
<property name="authPassthroughEnabled" value="true"/> |
Application Server Enterprise Edition 7.1 中的 auth-passthrough 插件功能的安全注意事项也适用于 Enterprise Server 2.1.1 中的 authPassthroughEnabled 属性。由于 authPassthroughEnabled 可以覆盖可能用于进行验证的信息(例如,请求的来源 IP 地址或 SSL 客户机证书),因此,必须只允许可信的客户机或服务器连接到 authPassthroughEnabled 设置为 TRUE 的 Enterprise Server 2.1.1 实例。作为一项预防措施,建议仅将公司防火墙之后的服务器的 authPassthroughEnabled 设置为 TRUE,而不要将可通过 Internet 访问的服务器的 authPassthroughEnabled 设置为 TRUE。
请注意,当代理 Web 服务器已配置了 service-passthrough 插件并且将请求转发到 authPassthroughEnabled 设置为 TRUE 的 Enterprise Server 实例时,Web 服务器代理上可能启用了 SSL 客户机验证,而在代理的 Enterprise Server 实例上却禁用了该验证。在此情况下,代理的 Enterprise Server 实例仍会将请求当作通过了 SSL 验证,并向部署在其上的发出请求的所有应用程序提供客户机 SSL 证书。