掲示板

Deployment Error with custom slf4j/log4j logging configuration

7年前 に Simon Beaulieu によって更新されました。

Deployment Error with custom slf4j/log4j logging configuration

New Member 投稿: 7 参加年月日: 16/09/19 最新の投稿
Hi all,

Quick summary of the technology stack I am using :
  • Liferay 6.2.5
  • Maven archetypes for portlets
  • Spring MVC portlets

I am trying to implement custom logging for my portlets, I want one separate file for each portlet and I found two interesting blog posts from Liferay Developpers on the subject.

I went on the github page of Denis Signoretto to observe the code for his project and used his configuration for my portlet.
However, I keep getting this error at deployment time
java.lang.ClassCastException: org.apache.log4j.rolling.RollingFileAppender cannot be cast to org.apache.log4j.Appender


Now I have seen other posts with people having the same error but the cause of their problems was that they were including jar files like portal-impl in the liferay-plugin-package.properties. That does not seem to be my case.

Here is my liferay-plugin-package.properties file :


name=zone-selector
module-group-id=liferay
module-incremental-version=1
tags=zoneselector
short-description=zone-selector-portlet
change-log=
page-url=http://www.liferay.com
author=Liferay, Inc.
licenses=LGPL
deploy-excludes=\                
        **/WEB-INF/lib/log4j.jar,\
        **/WEB-INF/lib/log4j-extras.jar,\
        **/WEB-INF/classes/log4j.properties,\        
        **/WEB-INF/classes/logging.properties
portal-dependency-jars=\
  util-slf4j.jar,\
  slf4j-api.jar\


Here is my portal-log4j.xml :


<!--?xml version="1.0"?-->


<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    
    <appender name="ZSRollingFile" class="org.apache.log4j.rolling.RollingFileAppender">                     
        <rollingpolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
            <param name="FileNamePattern" value="@liferay.home@/logs/zoneselector-portlet.%d{yyyy-MM-dd}.log.zip">
            <param name="ActiveFileName" value="@liferay.home@/logs/zoneselector-portlet-%d{yyyy-MM-dd}.log">
        </rollingpolicy>
            
        <layout class="org.apache.log4j.EnhancedPatternLayout">
            <param name="ConversionPattern" value="%-5p %d{HH:mm:ss,SSS} %c [%t] %m%n">
        </layout>
    </appender>

    <logger name="com.mycompany.zoneselector">
        <level value="DEBUG" />
        <appender-ref ref="ZSRollingFile" />
    </logger>
    
    <root>
        <level value="ERROR" />
        <appender-ref ref="ZSRollingFile" />
    </root>
    
</log4j:configuration>


And Finally, here is my pom.xml :


<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <artifactid>sample-parent-project</artifactid>
        <groupid>com.liferay.sample</groupid>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupid>com.mycompany.zoneselector</groupid>
    <artifactid>zone-selector</artifactid>
    <packaging>war</packaging>
    <name>zone-selector Portlet</name>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupid>com.liferay.maven.plugins</groupid>
                <artifactid>liferay-maven-plugin</artifactid>
                <version>${liferay.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>build-css</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <autodeploydir>${liferay.auto.deploy.dir}</autodeploydir>
                    <appserverdeploydir>${liferay.app.server.deploy.dir}</appserverdeploydir>
                    <appserverlibglobaldir>${liferay.app.server.lib.global.dir}</appserverlibglobaldir>
                    <appserverportaldir>${liferay.app.server.portal.dir}</appserverportaldir>
                    <liferayversion>${liferay.version}</liferayversion>
                    <plugintype>portlet</plugintype>
                </configuration>
            </plugin>
            <plugin>
                <artifactid>maven-compiler-plugin</artifactid>
                <version>2.5</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>1.6
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactid>maven-resources-plugin</artifactid>
                <version>2.5</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
                        
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupid>com.liferay.portal</groupid>
            <artifactid>portal-service</artifactid>
            <version>${liferay.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>com.liferay.portal</groupid>
            <artifactid>util-bridges</artifactid>
            <version>${liferay.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>com.liferay.portal</groupid>
            <artifactid>util-taglib</artifactid>
            <version>${liferay.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>com.liferay.portal</groupid>
            <artifactid>util-java</artifactid>
            <version>${liferay.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>javax.portlet</groupid>
            <artifactid>portlet-api</artifactid>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>servlet-api</artifactid>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>javax.servlet.jsp</groupid>
            <artifactid>jsp-api</artifactid>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>jstl</artifactid>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-aop</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-beans</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-context</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-core</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-expression</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-web</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-webmvc</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.springframework</groupid>
            <artifactid>spring-webmvc-portlet</artifactid>
            <version>3.0.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupid>org.slf4j</groupid>
            <artifactid>slf4j-api</artifactid>
            <!-- slf4jversion = 1.7.2 -->
            <version>${slf4jVersion}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupid>com.liferay.portal</groupid>
            <artifactid>util-slf4j</artifactid>
            <!-- liferay.version = 6.2.5 -->
            <version>${liferay.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>


Any criticism / ideas is much, much appreciated ! I'm running out of ideas here emoticon
7年前 に Simon Beaulieu によって更新されました。

RE: Deployment Error with custom slf4j/log4j logging configuration

New Member 投稿: 7 参加年月日: 16/09/19 最新の投稿
After more investigation, I am positive that the log4j-extras.jar and log4j.jar are always copied in the WEB-INF/lib directory of my exploded war right after the liferay:deploy maven goal is executed.

However, I am under the impression that I did configure my liferay-plugin-package.properties correctly and that I specified that these two jars needed to be excluded from the deployment.

What am I doing wrong ?
7年前 に Simon Beaulieu によって更新されました。

RE: Deployment Error with custom slf4j/log4j logging configuration

New Member 投稿: 7 参加年月日: 16/09/19 最新の投稿
This is a major blocker for me right now, can anyone help ?

If not, can someone confirm the existence of the deploy-excludes property in the liferay-plugin-package.properties file ?
I have looked in available documentation online, and I can't find proof of its existence for Liferay 6.2.5 (6.2 ga6)
Has anyone used it ?

I have also tried to configure the portal-ext.properties file with the following configurations with no success (I can see that Liferay reads the file upon startup), the libraries are still copied to the WEB-INF/lib folder of my exploded war :

  • auto.deploy.copy.log4j=false
  • auto.deploy.copy.commons.logging=false
7年前 に Simon Beaulieu によって更新されました。

RE: Deployment Error with custom slf4j/log4j logging configuration (回答)

New Member 投稿: 7 参加年月日: 16/09/19 最新の投稿
I GOT IT !

First of all, I was wrong about the "deploy-excludes" property not being read, it is, and the proof can be found here :
Github - com.liferay.portal.tools.deploy.BaseDeployer source code

It it possible to verify what is being read by setting the logging level to "DEBUG" for the package
com.liferay.portal.tools.deploy

To be more specific, set the logging level specifically on the
com.liferay.portal.tools.deploy.BaseDeployer
class.

You should see a message like
09:39:38,613 DEBUG [com.liferay.portal.kernel.deploy.auto.AutoDeployScanner][BaseDeployer:770] Excludes **/WEB-INF/lib/el-api.jar,**/WEB-INF/lib/log4j.jar,**/WEB-INF/lib/log4j-extras.jar,**/WEB-INF/classes/log4j.properties,**/WEB-INF/classes/logging.properties,
in your container's / liferay's log file while the portlet is being deployed (the liferay maven plugin's liferay:deploy goal is what triggers it for me)

Now, for the root cause of the problem. I don't know if Tomcat is the problem or Liferay but the "deploy-excludes" property seems to work ONLY if the files that need to be excluded are not already deployed in the exploded war that is on your container (in my case, Tomcat). To sum it up, you have to make sure that the deployment is made in a clean environment if you want to exclude things that were there before you have to flush everything and re-deploy (i.e. delete the exploded war by hand before redeploying the portlet or use the maven-clean plugin as explained later).

After another day of trying, I finally got the solution in Denis Signorreto's blog working with my Spring MVC portlet ! After reflexion, it was the fact that Tomcat never deletes anything in the webapps/ folder that caused the problem but I learned a whole lot on Liferay's architecture and logging system that's for sure !

What solved my problem is the following maven-clean configuration plugin configuration.
The liferay.app.server.deploy.dir points to the webapps folder of my tomcat inside the liferay installation, and zone-selector-1.0 is the name of my portlet.

<plugin>
    <artifactid>maven-clean-plugin</artifactid>
    <version>3.0.0</version>
    <configuration>
        <filesets>
            <fileset>
                <directory>${liferay.app.server.deploy.dir}/zone-selector-1.0</directory>
                <includes>
                    <include>**/*</include>
                </includes>
                <followsymlinks>false</followsymlinks>
            </fileset>
        </filesets>
    </configuration>
</plugin>   

As you can see, its not really optimal because the path is binded to both the portlet name and the path on my development environment, but for now... IT. WORKS. My portlet has its dedicated file and I can customize the log4j config.

I'm so, so happy, I spent weeks on that thing, and for someone who didn't even know what Liferay was a month ago, well, it feels awesome emoticon !