在web.xml中使用表达式语言(EL)来访问JVM变量

时间:2015-03-20 14:49:30

标签: java spring jvm el java-ee-6

我有两个在同一个WebSphere 8.5.5服务器上运行的Web应用程序。第一个应用程序能够在web.xml中使用表达式语言(EL)来访问JVM变量,如下所示:

<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/config/log4j-${app.env}.xml</param-value>
</context-param>

这允许我在服务器上设置名为app.env的JVM变量,该变量确定使用哪个log4j配置文件。根据环境将此变量设置为rad,test或production。

此外,因为这些应用程序将在集群环境中运行但是登录到同一网络共享,所以我需要在log4j配置文件中使用EL来区分日志文件。这是在log4j配置文件中使用EL实现的,如下所示:

<appender name="file" class="com.example.util.CustodianDailyRollingFileAppender">
    <param name="maxNumberOfDays" value="10" />
    <param name="compressBackups" value="yes" />
    <param name="File" value="/netshare/logs/${app.serv}_app.log" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%d] %-5p %c - %m%n" />
    </layout>
</appender>

app.serv JVM变量在集群中的第一台服务器上设置为“1”,在第二台服务器上设置为“2”,这导致每个正在创建的服务器的日志文件分别名为1_app.log和2_app.log 。

第一个应用程序使用Servlets 2.4和Spring Framework 3.0.4。

在第二个应用程序中,我正在尝试对我的日志文件使用相同的方案,但是,我正在使用Servlets 3.0而不使用Spring Framework,而是试图坚持使用JEE6。但是,不会在web.xml或log4j配置文件中评估EL。

如果我将EL放在第二个应用程序的web.xml中,那么log4j会抛出异常,因为它无法在定义的位置找到配置文件,因为EL尚未被评估:

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>/WEB-INF/log4j2-${app.env}.xml</param-value>
</context-param>

这会导致异常,因为log4j正在寻找log4j2 - $ {app.env} .xml而不是log4j2-rad.xml。

类似地,如果我硬编码配置位置并尝试在log4j2配置中使用EL,则EL不会被评估,并且当它应该评估时,我最终得到名为$ {app.serv} _app.log的日志文件。 EL并命名文件1_app.log。

提出了我的问题:

1)应用程序1和应用程序2之间的区别是导致我的web.xml和log4j配置中的EL不被评估?

2)如何在应用程序2中的web.xml和log4j配置文件中使用EL?

1 个答案:

答案 0 :(得分:0)

我想我已经设法回答了我自己的问题:

1)应用程序1和应用程序2之间有什么区别导致我的web.xml和log4j配置中的EL无法评估?

差异是双重的:

首先,Applicaton A是一个Spring应用程序,它使用Spring附带的Log4JConfigListener类。 Log4JConfigListener是一个ServletContextListener,它基本上只是帮助Log4j配置类查找配置文件。此外,在执行此操作之前,它会解析web.xml中Log4J配置位置上下文参数中使用的任何占位符。我自己能够通过实现自己的ServletContextListener来重现这种行为,它与Spring完全相同。

其次,应用程序A使用的是Log4j 1.2.x,而应用程序B正在尝试使用Log4j 2.x.最初,我认为Log4j 2.x根本没有做Log4j 1.2.x在其OptionConverter类中所做的占位符分辨率。所以,我通过恢复到Log4j 1.2.x解决了这个问题。从那以后,我将更改回Log4j 1.2.x,我注意到log4j-1.2-api-2.x.jar中似乎有适配器类。这个罐子不存在于我的应用程序B的类路径中,如果他们在那里可能会有所不同。我可能会在以后对此进行调查,但是现在,我很高兴能够使用Log4j 1.2.x。

2)如何在应用程序2中的web.xml和log4j配置文件中使用EL?

上面回答了问题2,其中ServletContextListener在将文件位置传递给Log4j配置器之前解析表达式,并使用Log4j 1.2.x而不是Log4j 2.x解析表达式。我再次强调,如果log4j-1.2-api-2.x.jar在类路径上,Log4j 2.x可能会有相同的行为,但我现在无法亲自验证这一点。