Search code examples
javaspring-bootlog4j2tomcat8java-11

After JDK11 upgrade, log4j2 RollingFileAppender throws java.io.FilePermission error


After upgrading from JDK8 to JDK11, we are getting the following message when starting tomcat:

     ERROR Could not create plugin of type class 
     org.apache.logging.log4j.core.appender.RollingFileAppender
     for element RollingFile: java.security.AccessControlException:
     access denied ("java.io.FilePermission" "/zdata/svrgrp/logs/qam1" "read")
     java.security.AccessControlException: access denied ("java.io.FilePermission"
     "/zdata/svrgrp/logs/qam1" "read")

Java has no problems writing other files to that directory; for example, we have a -outfile /zdata/tomcat/qam1/logs/catalina.out in the command line and we see output being written there.

But the most puzzling thing is that this worked just fine when we were running this on JDK8 using the exact same catalina policy.

Is there some fundamental change in the way JDK11 uses log4j that could explain this behavior?

Our log4j configuration xml is below. sys:applogdir is defined as /zdata/svrgrp/logs/qam1:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration>
  <Appenders>
    <RollingFile
      name="default.file"
      fileName="${sys:applogdir}/myapp.log"
      filePattern="${sys:applogdir}/myapp.log.%d{yyyy-MM-dd}">
      <PatternLayout>
        <Pattern>%d %-5p [%t]:${sys:bi.tomcat.instanceName} (%F:%L) - %m%n</Pattern>
      </PatternLayout>
      <TimeBasedTriggeringPolicy/>
    </RollingFile>

  <Loggers>
    <Root level="debug">
      <AppenderRef ref="default.file"/>
    </Root>
  </Loggers>

</Configuration>

Has anyone else experienced this behavior upgrading from JDK8 to JDK11? Any thoughts on what might have changed?


Solution

  • UPDATED

    Starting with JDK9, java.io.FilePermission stopped canonicalizing pathnames by default. This means that symlinks will no longer be followed.

    In our environment, "/zdata/svrgrp/logs/qam1" is a symlink to a location on another file system. So java.io.FilePermission would not follow that symlink, causing the "access denied" errors to appear.

    You can tell java.io to revert to its old behavior by setting the permissionsUseCanonicalPath property to True. So I added this to our startup script:

    -Djdk.io.permissionsUseCanonicalPath=true
    

    And everything started working.