unfettered
unfettered

Reputation: 351

Grails ClassNotFoundException: org.apache.log4j.Logger

I am trying to get my Grails app to log using the logback plugin. Per the documentation's instructions, here's what I've done so far:

BuildConfig
===========
grails.project.dependency.resolution = {
    inherits("global") {
        excludes 'grails-plugin-log4j', 'log4j', 'h2'
    }

    log "error"
    checksums true
    legacyResolve false

    repositories {
        inherits true

        grailsPlugins()
        grailsHome()
        mavenLocal()
        grailsCentral()
        mavenCentral()

        // For logback plugin.
        mavenRepo "http://repo.grails.org/grails/libs-releases/"
    }

    dependencies {
        // This plugin is a binary plugin, so it belongs here instead of under 'plugins'.
        compile 'org.grails.plugins:logback:0.3.1'

        test "org.grails:grails-datastore-test-support:1.0-grails-2.4"
    }
}

Config
======
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy

<lots of more configs here>

logback = {
    appenders {
    rollingFile name:
        'rollingAppender',
        file: '/tmp/rolling.log',
        encoder: pattern(pattern: '%-4relative [%thread] %-5level %logger{35} - %msg%n'),
        triggeringPolicy: new SizeBasedTriggeringPolicy(maxFileSize: 10*1024*1024),
        rollingPolicy: new FixedWindowRollingPolicy(fileNamePattern: '/tmp/rolling.%i.log.gz')
    }

    root {
        info rollingAppender
    }

    error rollingAppender: 'org.codehaus.groovy.grails.web.servlet',
        'org.codehaus.groovy.grails.web.pages'
}

I then ran a grails clean. When I do a grails run-app, I get an absolutely massive stacktrace as follows:

|Compiling 161 source files
    [groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
    [groovyc] General error during semantic analysis: Unable to load logging class
    [groovyc] 
    [groovyc] groovy.lang.GroovyRuntimeException: Unable to load logging class
    [groovyc]   at org.codehaus.groovy.transform.LogASTTransformation$AbstractLoggingStrategy.classNode(LogASTTransformation.java:269)
    [groovyc]   at groovy.util.logging.Log4j$Log4jLoggingStrategy.addLoggerFieldToClass(Log4j.java:72)
    [groovyc]   at org.codehaus.groovy.transform.LogASTTransformation$1.visitClass(LogASTTransformation.java:112)
    [groovyc]   at org.codehaus.groovy.transform.LogASTTransformation.visit(LogASTTransformation.java:157)

<massive stack trace omitted for brevity>

General error during semantic analysis: Unable to load logging class
groovy.lang.GroovyRuntimeException: Unable to load logging class
    at org.codehaus.groovy.transform.LogASTTransformation$AbstractLoggingStrategy.classNode(LogASTTransformation.java:269)
    at groovy.util.logging.Log4j$Log4jLoggingStrategy.addLoggerFieldToClass(Log4j.java:72)
    at org.codehaus.groovy.transform.LogASTTransformation$1.visitClass(LogASTTransformation.java:112)

<massive stack trace omitted for brevity>

    at org.codehaus.groovy.grails.cli.support.GrailsStarter.rootLoader(GrailsStarter.java:236)
    at org.codehaus.groovy.grails.cli.support.GrailsStarter.main(GrailsStarter.java:264)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:655)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:765)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:753)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:270)
    at org.codehaus.groovy.transform.LogASTTransformation$AbstractLoggingStrategy.classNode(LogASTTransformation.java:267)
... 608 more
6 errors

Additionally, in my GGTS IDE, I'm getting compiler errors on my two import statements added to Config.groovy. It sounds like I still have Log4j references somewhere in my Grails app, and running the grails clean removed the Log4j JAR from my classpath. That might explain the stacktrace. But it doesn't explain why Grails (or at least my GGTS IDE) can't find the logback classes I'm importing.

I do see I still have this in my Config:

grails.logging.jul.usebridge = true

So I ask: How do I fix this stack trace and my IDE errors?


Update

Doing a grails dependency-report produces a huge graph that does seem reveal I have 2 remaining dependencies on log4j:

+--- org.grails.plugins:tomcat:7.0.54
|    \--- org.apache.tomcat:tomcat-catalina-ant:7.0.53
|    \--- org.apache.tomcat.embed:tomcat-embed-jasper:7.0.53
|         \--- org.apache.tomcat.embed:tomcat-embed-el:7.0.53

<HERE>
|    \--- org.apache.tomcat.embed:tomcat-embed-logging-log4j:7.0.53

+--- org.grails:grails-plugin-rest:2.4.2
|    \--- org.slf4j:jcl-over-slf4j:1.7.5
|    \--- org.slf4j:slf4j-api:1.7.5
|    \--- com.google.code.gson:gson:2.2.4
|    \--- org.grails:grails-web:2.4.2
|         \--- org.grails:grails-web-common:2.4.2
|              \--- org.springframework:spring-webmvc:4.0.5.RELEASE
|              \--- org.springframework:spring-context-support:4.0.5.RELEASE
|              \--- org.grails:grails-databinding:2.4.2
|         \--- org.grails:grails-web-url-mappings:2.4.2
|         \--- org.grails:grails-web-fileupload:2.4.2
|              \--- commons-fileupload:commons-fileupload:1.3.1
|                   \--- commons-io:commons-io:2.2
|         \--- org.grails:grails-web-gsp:2.4.2
|         \--- org.springframework:spring-aspects:4.0.5.RELEASE
|         \--- org.grails:grails-web-mvc:2.4.2
|         \--- org.grails:grails-web-sitemesh:2.4.2
|              \--- opensymphony:sitemesh:2.4
|         \--- org.grails:grails-web-databinding:2.4.2
|         \--- org.grails:grails-web-jsp:2.4.2
|         \--- org.aspectj:aspectjweaver:1.8.0
|         \--- org.aspectj:aspectjrt:1.8.0
|    \--- org.grails:grails-plugin-controllers:2.4.2
|         \--- org.grails:grails-plugin-validation:2.4.2
|    \--- org.grails:grails-plugin-datasource:2.4.2
|         \--- org.springframework:spring-jdbc:4.0.5.RELEASE

<HERE>
|         \--- org.apache.tomcat.embed:tomcat-embed-logging-log4j:7.0.50

So:

So my next question: Are these the culprits? If so, how do I remove them safely?

Upvotes: 3

Views: 3268

Answers (1)

charlv
charlv

Reputation: 81

I had exactly the same stacktrace, and solved it by adding a slf4j log4j bridge to ensure that all transitive or plugins still depending on log4j will now log through logback:

runtime "org.slf4j:jul-to-slf4j:1.7.7"
runtime "org.slf4j:log4j-over-slf4j:1.7.7"

Hope that helps.

Upvotes: 4

Related Questions