Grails log4j SMTPAppender NoClassDefFoundError - grails

How do I configure SMTPAppender in a new Grails 2.4.5 project? I receive a NoClassDefFoundError when running in the development environment:
| Error log4j:ERROR Error initializing log4j: javax/mail/Message
| Error java.lang.NoClassDefFoundError: javax/mail/Message
Gist: Detailed stacktrace
I have configured a dependency for javax.mail and configured log4j as follows:
dependencies {
provided 'javax.mail:mail:1.4.7'
}
log4j = {
appenders {
appender new org.apache.log4j.net.SMTPAppender(
name: 'smtp',
layout: pattern(conversionPattern: '%d{MM-dd-yyyy HH:mm:ss.SSS} [%t] %c %M %x%n%p: %m%n')
to: 'example#example.com',
from: 'example#example.com',
subject: 'Grails Message',
SMTPHost: '127.0.0.1')
)
}
}
GitHub: Example Project

I know this post is old, but I struggled with the same till I found a solution that is at least working for me (not with SMTPAppender but with Sentry - same purpose).
The explanation I found with the errors you where receiving
Error log4j:ERROR Error initializing log4j: javax/mail/Message
Error java.lang.NoClassDefFoundError: javax/mail/Message
Come from this piece of code:
dependencies {
provided 'javax.mail:mail:1.4.7'
}
The thing is that when you compile things work, when you try to do grails run-app you receive this error.
The explanation I found is that the log4j initializes before the maven dependency is resolved.
I wrote a comment of how I've used Sentry as an appender.
https://github.com/getsentry/raven-java/issues/184#issuecomment-259432057
Basically, instead of adding the maven dependency I've downloaded the java file, and added it to the grails project in src/java
So for Sentry por example I added the SentryAppender.java to my.package.sentry so then in log4j I added:
appenders {
environments {
// This block is set up to use the stock raven SentryAppender in
// production. Sentry Appender runs into all kinds of
// class loading weirdness when used in a forked grails environment
production {
appender new my.package.sentry.SentryAppender(
name: 'sentry',
dsn: 'REDACTED',
threshold: org.apache.log4j.Level.WARN
)
}
// Uncomment this block if you need to test sentry
// in a dev environment
development {
appender new my.package.sentry.SentryAppender(
name: 'sentry',
dsn: 'REDACTED',
threshold: org.apache.log4j.Level.WARN
)
}
}
}
root {
warn 'stdout', 'sentry'
error 'stdout', 'sentry'
additivity = false
}
in that way, it does not depend on an external dependency.
I guess that you could do something similar to the mail dependency and add the java files to the src folder.
I hope it helps!

That looks weird - are you combining the dependencies block and the log4j block here unintenionally, or are they in the same file in your app? The dependency should be in BuildConfig.groovy and the log4j block should be in Config.groovy. Also, it shouldn't be log4j { but rather log4j = {.
This is likely a timing issue. If Config.groovy is parsed before the Javamail dependency is resolved, it will fail. Try commenting out the parts that reference the Javamail classes and run grails clean and grails compile. That will resolve dependencies and add that jar to the classpath. Then you can uncomment that code and run grails compile again.

Related

[Jboss 4.3][Grails 2.3.x] Log does not work properly (ERROR: invalid console appender config detected, console stream is looping)

If we deploy our Grails application in a JBoss 4.3, it always shows the same error message:
ERROR: invalid console appender config detected, console stream looping
In the Config.groovy file we have defined the log4j:
log4j = {
root {
info 'unoAppender','communications', 'hibernate', 'dependencies'
}
appenders {
appender new CustodianDailyRollingFileAppender(
name:'unoAppender',
file:'logs/app-uno.log',
append:true, maxNumberOfDays:60,
compressBackups:true,
threshold:Level.DEBUG,
layout: pattern(conversionPattern: "%d{ISO8601} %-5p [%t:%1X{JSESSION_ID}] [%c{1}] - %m%n"))
.....
}
}
And also there are appenders in the jboss-log4j.xml of the default server.
Finally we have tried to add the following paramenter in the JAVA_OPTS of the run.sh [-Dorg.jboss.logging.Log4jService.catchSystemOut=false] the logs works properly in the console but it does not work in the server.log.

How do disable log4j plugin in grails?

It appears the Grails 2.1 log4j plugin resets the log4j configuration during initialization of the grails application (see stack trace below).
at org.apache.log4j.LogManager.resetConfiguration(LogManager.java:233)
at org.apache.log4j.LogManager$resetConfiguration.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at org.codehaus.groovy.grails.plugins.log4j.Log4jConfig.initialize(Log4jConfig.groovy:66)
at org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener.contextInitialized(Log4jConfigListener.java:48)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3910)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4389)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:313)
at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145)
Is there any way to disable this "feature" or to remove this plugin altogether?
My JBoss server is already configured through jboss-log4j.xml and I do not want grails to make any changes to the configuration. I have already tried removing the log4j section of Config.groovy, but doing so had no effect.
As Kelly suggested, I have already removed all logging-related jars from my war file. Log4j classes are provided by JBoss.
EDIT I also tried the trick described in https://stackoverflow.com/a/1190438/539048 but that didn't seem to make any difference.
The solution was to remove the following section from the generated web.xml file:
<listener>
<listener-class>org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener</tag0:listener-class>
</listener>
To do so, I edited the scripts/Events.groovy file according to this blog but changed the listener class name to org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener.
eventWebXmlEnd = {String tmpfile ->
def root = new XmlSlurper().parse(webXmlFile)
def log4j = root.listener.findAll {node ->
node.'listener-class'.text() == 'org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener'
}
log4j.replaceNode {}
webXmlFile.text = new StreamingMarkupBuilder().bind {
mkp.declareNamespace("": "http://java.sun.com/xml/ns/j2ee")
mkp.yield(root)
}
}
Modify your BuildConfig.groovy like this:
inherits("global") {
excludes 'log4j', 'jcl-over-slf4j', 'slf4j-api', 'slf4j-log4j12'
}
This should remove all the logging libraries.
I tried the above suggestion on this grails application, so that I could expect to exclude the log4j dependencies of grails. However, after applying the suggestion, the jar files expected to be removed are still there in the generated war file. These jar files are: ./lib/grails-plugin-log4j-2.4.4.jar and ./lib/log4j-1.2.17.jar

Grails javamelody plugin warnings

I've been using the javamelody monitoring plugin for a while in Grails with no problem, but lately I had to move my developments to another computer (I'm now using netbeans 7.1.2). After reinstalling the plugins, I run the app flawlessly in my development environment. But when I run the war to my production environment, the following warnings show up:
log4j:WARN No appenders could be found for logger (net.bull.javamelody).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
The appenders section in Config.groovy is:
appenders {
console name:'stdout', layout:pattern(conversionPattern: '%d [%t] %-5p %c{2} %x - %m%n')
appender new DailyRollingFileAppender (
name: 'dailyAppender',
datePattern: "'.'yyyy-MM-dd",
fileName: "logs/${appName}.log",
layout: pattern(conversionPattern:'%d [%t] %-5p %c{2} %x - %m%n')
)
}
My questions are:
Why aren't these warnings present in the development environment's log ?What are possible consecuences on the application ?
I'm running Grails 1.3.9, Melody 1.2, tomcat 7.0.23
Thanks
It might be different form environment to environment if you have
setup a logging appender in the development section of your Grails
Config.groovy file but not for your production section.
The consequences are that you will not have logging. You may have code in your application that says log.error("Critical Error!") but since this is not linked to any appender you will never see it anywhere.
Check out logging in the documentation.

Grails: Replace log4j with logback

I am trying to replace log4j in my Grails app with logback but am always getting a
Embedded error: java.lang.reflect.InvocationTargetException
org.apache.log4j.LogManager
when running run-app or test-app.
I have included the following in BuildConfig.groovy which I thought is enough:
inherits("global") {
excludes "slf4j-log4j12"
}
[...]
dependencies {
build 'ch.qos.logback:logback-core:0.9.29', 'ch.qos.logback:logback-classic:0.9.29'
runtime 'ch.qos.logback:logback-core:0.9.29', 'ch.qos.logback:logback-classic:0.9.29'
}
I cannot find any more references to Log4J and have no idea where this call comes from?!
I am also trying replace Grails slf 1.5.8 by 1.6.2 and get the following in the console despite having excluded slf from all Grails modules:
SLF4J: The requested version 1.6 by your slf4j binding is not compatible with [1.5.5, 1.5.6, 1.5.7, 1.5.8]
SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details.
Thanks in advance for any help
Regards,
Jonas
Logback 0.9.21 and above depends on slf4j-api 1.6 which is what that error is telling you.
Add dependencies for org.slf4j:slf4j-api:1.6
This worked for me in BuildConfig.groovy when using Grails 2.1.0:
inherits("global") {
excludes 'grails-plugin-log4j'
}
[...]
dependencies {
compile 'ch.qos.logback:logback-classic:1.0.6'
runtime 'ch.qos.logback:logback-classic:1.0.6'
}
[...]
this.classLoader.rootLoader.addURL(new File("${basedir}/grails-app/conf/").toURI().toURL())
This last line makes Grails properly read grails-app/conf/logback.groovy if you want to set your configuration there.
I used logback 1.0.6. It did not not work. But I use another way. set environment variable "logback.configurationFile={groovy file address}". for example:
grails run-app -Dlogback.configurationFile=c:\log\logback.groovy
You can use this parameter in tomcat or any others that you put your war file in it.
It works for me.
I integrated Logback to Grails a few days ago - my steps to the working solution are here: Grails 2.1.1 - Logback integration
Also, there is just a new Plugin 'round the block: http://grails.org/plugin/logback which seems promising!
Good luck with this issue - it's worth the effort!
It might be helpful for others:
specify the config in Config.groovy
logback = {
appenders {
console name: 'stdout', encoder: pattern(pattern: "%d{dd-MMM-yyyy HH:mm:ss} %-5p %c - %m%n")
rollingFile(
name: 'fileAppender',
file: logFileName,
encoder: pattern(pattern: "%d{dd-MMM-yyyy HH:mm:ss} %-5p %c - %m%n"),
triggeringPolicy: new SizeBasedTriggeringPolicy(maxFileSize: 10*1024*1024), // Max is 10 MB log files
rollingPolicy: new FixedWindowRollingPolicy(fileNamePattern: iLogFileName)
)
}
error fileAppender: 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
info fileAppender: 'org.springframework.web.client',
'com.yourpackage',
'com.linkedin.grails'
debug fileAppender: 'com.yourpackage', // Set debug level for non-grails artifacts, e.g. src/groovy, under the com.yourpackage.package
'grails.app' // Set debug level for all application artifacts
trace fileAppender: 'org.springframework.web.client',
'org.springframework.social',
'com.yourpackage'
root {
info 'stdout', 'fileAppender'
}
}
Include the logback plugin and Exclude the require packages:
in BuildConfig.groovy
inherits("global") {
excludes 'grails-plugin-log4j', 'log4j' //using logback as grails-log4j have serialization issues with spark libraries
}
inside dependencies: include compile 'org.grails.plugins:logback:0.3.1'
Disable Fork mode execution. It will not work with logback.
The above configurations will ONLY work with the WAR mode.
If you even want to control logging during normal local dev mode, Include a logback.xml file in your conf directory.
logback.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="warn">
<appender-ref ref="STDOUT"/>
</root>
<shutdownHook/>
</configuration>

Where can I find the Tomcat log written out by 'grails run-app'?

While running grails app in 'dev' mode using 'grails run-app', where is the default Tomcat log file located written out by the embedded Tomcat come with Grails (1.2.2) installation?
There isn't a default log file, the output to the log gets written to stdout.
Should be $CATALINA_HOME/logs/catalina.out
You have to define an log4j root logger in your Config.groovy like this:
log4j = {
appenders {
// console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
// file name:'file', file:'app.log'
}
// By default, messages are logged at the warn level to the console and the app.log
root {
warn 'stdout'
// warn 'stdout','file'
additivity = true
}
...
}
This example also shows how to configure the logging pattern. Also it shows how to configure file logging. The appenders section is optional and just needed to configure the logging pattern or file logger.

Resources