3

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:

  • org.grails.plugins:tomcat:7.0.54 depends on:
    • org.apache.tomcat.embed:tomcat-embed-logging-log4j:7.0.53; and
  • org.grails:grails-plugin-rest:2.4.2 depends on:
    • org.grails:grails-plugin-datasource:2.4.2 which depends on:
    • org.apache.tomcat.embed:tomcat-embed-logging-log4j:7.0.50

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

unfettered
  • 351
  • 3
  • 13
  • 1
    unsure if this will help https://github.com/grails-plugins/grails-logback/issues/3 temporary solution worked mavenRepo "http://repo.grails.org/grails/repo/" – V H Nov 21 '14 at 15:46
  • Thanks @vahid (+1) - however its not that I can't find the logback jar, its that Log4j has been removed from my Grails app (due to me installing the logback transform) and somehow, somewhere, something in my Grails app is still dependent on log4j. – unfettered Nov 21 '14 at 16:13
  • 1
    sorry for misleading, I would try a few things 1 do a dependency-report and see if any of the other plugins is trying use log4j - if anything then try to exclude log4 from the plugin call in your buildConfig.. the other thing I would also try doing is doing a basic vanilla grails app with nothing but this plugin to see if its happening on a new created app or if it relates to as above another plugin causing the issue.... Sorry I can;t give you anything more concrete – V H Nov 21 '14 at 16:31
  • Thanks again @vahid (+1 again) - please see my update which includes running `dependency-report`. Any ideas as to what I should do from here? – unfettered Nov 21 '14 at 18:51
  • Usually in a defined plugin you add compile ':something:0.1', { excludes = 'something ' } but in this case there may be another alternative found here http://stackoverflow.com/questions/26313765/configuring-logging-for-grails-standalone-app-runner with this another possible useful link http://stackoverflow.com/questions/11731730/how-do-disable-log4j-plugin-in-grails and the q about how to exclude stuff http://stackoverflow.com/questions/18924347/grails-is-it-possible-to-exclude-a-plugin-dependency-of-another-plugin – V H Nov 21 '14 at 23:17

1 Answers1

4

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.

charlv
  • 81
  • 1
  • 4