CF9 Problem using log4j when sending an email (org.apache.log4j.net.SMTPAppender)

Copy link to clipboard
Copied
Hi,
i've problem using log4j when i sending email with log4j on CF9 (org.apache.log4j.net.SMTPAppender). The code under works fine with CF8 (version 8,0,0,176276) :
<cfset parameters = structnew()>
<cfset parameters.category="MyCategory">
<cfset parameters.message="#randRange(1000, 100000)# Test Error">
<cfscript>
configurator = CreateObject("java", "org.apache.log4j.PropertyConfigurator");
configurator.configure('C:/cflog4j/cflog4j.properties');
category = CreateObject("java", "org.apache.log4j.Category");
logger = category.getInstance(parameters.category);
logger.error(parameters.message);
</cfscript>
Here the stack trace in the coldfusion runtime log (coldfusion-out.log):
log4j:ERROR Error occured while sending e-mail notification.java.lang.ClassCastException: com.sun.mail.handlers.text_plain cannot be cast to javax.activation.DataContentHandler at javax.activation.MailcapCommandMap.getDataContentHandler(MailcapCommandMap.java:581)at javax.activation.MailcapCommandMap.createDataContentHandler(MailcapCommandMap.java:535)at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:597)at javax.activation.DataHandler.writeTo(DataHandler.java:301)at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:264)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1299)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1008)at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:414)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1285)at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2071)at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2039)at javax.mail.Transport.send(Transport.java:119)at org.apache.log4j.net.SMTPAppender.sendBuffer(Unknown Source)at org.apache.log4j.net.SMTPAppender.append(Unknown Source)at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:221)at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:57)at org.apache.log4j.Category.callAppenders(Category.java:187)at org.apache.log4j.Category.forcedLog(Category.java:372)at org.apache.log4j.Category.error(Category.java:286)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at coldfusion.runtime.StructBean.invoke(StructBean.java:502)at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2393)at cflogError22ecfm1601859185.runPage(D:\projets\phswebservice\global\web_phs_front\test\logError2.cfm:14)at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:342)at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)at coldfusion.filter.PathFilter.invoke(PathFilter.java:87)at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:74)at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:53)at coldfusion.CfmServlet.service(CfmServlet.java:200)at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)at jrun.servlet.FilterChain.service(FilterChain.java:101)at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Here the cflog4j.properties file :
log4j.category.MyCategory=
frontAppender, mail
#file appender works fine
log4j.appender.frontAppender =org.apache.log4j.RollingFileAppender
log4j.appender.frontAppender.File=D:/front.log
log4j.appender.frontAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.frontAppender.layout.ConversionPattern=
%-5p %c %d - %m%n
log4j.appender.frontAppender.MaxFileSize=1024KB
#SMPT appender
log4j.appender.mail=org.apache.log4j.net.SMTPAppenderlog4j.appender.mail.SMTPHost=
smtp.mysite.com
log4j.appender.mail.Subject=
Error Message
log4j.appender.mail.BufferSize=10
log4j.appender.mail.Threshold=
info
log4j.appender.mail.layout=
org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=
%-5p %c %d{ISO8601} - %m%n
If i look at CF8 Classpath, CF8 seems not to use javax.activation.jar and so mail.jar does not seem to be the same as in CF9.
If someone have any idea to resolve this problem, thanks a lot !
Copy link to clipboard
Copied
I suspect it is due to the WEB-INF\lib\cfmx_bootstrap.jar. The CF9 properties include a bunch of mail packages to be loaded by the bootstrap class loader, (CF8 did not). Some of the mail packages are contained in multiple jars. Example javax.activation.* classes are found in both the \lib\rt.jar and \lib\mail.jar. So the jvm/logger may be getting confused and falling down when faced with multiple versions.
You could update the appropriate *.properties file in cfmx_bootstrap.jar, and move the necessary packages to from the bootstrap section to the App Server class loader section. That might work. But I have no idea what it might break in the process ...
Message was edited by: -==cfSearching==-
Copy link to clipboard
Copied
This seems that a really serious issue : it would mean that in order to use any java package that could send mail one has to
tweak ColdFusion 9 at a very low level with the risk of breaking ColdFusion itself. It would mean the end of use of many external java packages because lot of them potentially send email if they use log4j for example.
Maybe there is an Adobe supported way to do this kind of things in ColdFusion 9 ?
Copy link to clipboard
Copied
norbertAdobe wrote:
It would mean the end of use of many external java packages because lot of them potentially send email if they use log4j for example.
Why would you say that? The issue described does not stop log4j or external libraries from working, just the email feature.
Unfortunately, Issues with log4j + other java applications are not new. There are some common class loader conflicts that can occur in any java application due to how class loaders work and how log4j is designed. In thinking about it further, that may be what is happening here. So it might be worth trying the ignoreTCL flag and/or adding the appenders to the main log4j.properties used by CF.

Copy link to clipboard
Copied
Hi,
I try adding the appenders to the main log4j.properties used by CF(C:\ColdFusion9\lib\log4j.properties). Here the log4j.properties file :
# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=INFO, CONSOLE
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
# New category added
log4j.category.frontPHS=INFO, frontAppender, mail
### Setup Axis Log
log4j.logger.org.apache.axis=WARN, AXISCONSOLE
log4j.additivity.org.apache.axis=false
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, AXISCONSOLE
###--------------- Hibernate Log Settings ------
### Set Hibernate log
log4j.logger.org.hibernate=ERROR, HIBERNATECONSOLE
### log just the SQL
#log4j.logger.org.hibernate.SQL=DEBUG, HIBERNATECONSOLE
#log4j.additivity.org.hibernate.SQL=false
### Also log the parameter binding to the prepared statements.
#log4j.logger.org.hibernate.type=DEBUG
### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=ERROR
### log cache activity ###
log4j.logger.org.hibernate.cache=ERROR, HIBERNATECONSOLE
#---------------------------------------------
log4j.logger.net.sf.ehcache=ERROR
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm:ss} [%t] %-5p %m%n
# AXISCONSOLE is set to be a ConsoleAppender for Axis using a PatternLayout.
log4j.appender.AXISCONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.AXISCONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.AXISCONSOLE.layout.ConversionPattern=%d [%t] AXIS %-5p %c - %m%n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# HibernateConsole is set to be a ColsoleAppender for Hibernate message using a PatternLayout.
log4j.appender.HIBERNATECONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.HIBERNATECONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.HIBERNATECONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm:ss} [%t] HIBERNATE %-5p - %m%n%n
log4j.appender.frontAppender =org.apache.log4j.RollingFileAppender
log4j.appender.frontAppender.File=D:/frontTT.log
log4j.appender.frontAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.frontAppender.layout.ConversionPattern=%-5p %c %d - %m%n
log4j.appender.frontAppender.MaxFileSize=1024KB
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.SMTPHost=smtp.mysite.fr
log4j.appender.mail.Subject=DEV Message erreur CF9
log4j.appender.mail.From=erreur@mysite.fr
log4j.appender.mail.To=erreur@mysite.fr
log4j.appender.mail.BufferSize=10
log4j.appender.mail.Threshold=INFO
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%-5p %c %d{ISO8601} - %m%n
Here the code that use log4j (I try to use the ignoreTCL option in the call ) :
<cfset
parameters = structnew()>
<cfset
parameters.category="frontPHS">
<cfset
parameters.message="#randRange(1000, 100000)# Test Error">
<cfscript>
System =
createObject("Java", "java.lang.System");
System.setProperty(
"log4j.ignoreTCL", true);
configurator =
CreateObject("java", "org.apache.log4j.PropertyConfigurator");
category =
CreateObject("java", "org.apache.log4j.Category");
logger = category.getInstance(parameters.category);
logger.error(parameters.message);
</cfscript>
I've got the same error (see in codufsion runtime log folder in C:\ColdFusion9\runtime\logs)
Copy link to clipboard
Copied
I did not see your response until just now. Anyway, I tried a number of things and only two configurations seemed to work due to the whole dance of the dueling class loaders thing...
1) Adding the appenders to the main {cfroot}\lib\log4j.properties file _and_ creating the category with the javaLoader.
OR
2) Modifying the jrun.properties** file in the WEB-INF\lib\cfmx_bootstrap.jar and moving the log4j package from the loadByAppServer list to the jdk 1.5 exceptions list. In other words, forcing it to be loaded by the bootstrap classloader instead of the app class loader.
** Testing with built in web server
Option #1 Code
CF Code
<cfscript>
// only need to modify this setting once on load (or use jvm args flag) ....
sys = createObject("java", "java.lang.System").getProperties();
sys.setProperty("log4j.ignoreTCL", true);
// in real code, only initialize loader once in onApplicationStart to avoid memory leaks
paths = [ ExpandPath("com/cflog4j/log4j-1.2.13.jar") ];
loader = createObject("component", "javaLoader.javaLoader").init(paths, true);
category = loader.create("org.apache.log4j.Category");
logger = category.getInstance( "frontPHS" );
logger.error( randRange(1000, 100000) &" Test Error Message" );
</cfscript>
Done at <cfoutput>#now()#</cfoutput>
{cfroot}\lib\log4j.properties
# FOR DEBUGGING .... Disable when finished
log4j.debug = true
# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=INFO, CONSOLE, mail
#log4j.rootCategory=INFO, CONSOLE
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
log4j.category.frontPHS=INFO, frontAppender, mail
### Setup Axis Log
log4j.logger.org.apache.axis=WARN, AXISCONSOLE
log4j.additivity.org.apache.axis=false
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, AXISCONSOLE
###--------------- Hibernate Log Settings ------
### Set Hibernate log
log4j.logger.org.hibernate=ERROR, HIBERNATECONSOLE
### log just the SQL
#log4j.logger.org.hibernate.SQL=DEBUG, HIBERNATECONSOLE
#log4j.additivity.org.hibernate.SQL=false
### Also log the parameter binding to the prepared statements.
#log4j.logger.org.hibernate.type=DEBUG
### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=ERROR
### log cache activity ###
log4j.logger.org.hibernate.cache=ERROR, HIBERNATECONSOLE
#---------------------------------------------
log4j.logger.net.sf.ehcache=ERROR
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm:ss} [%t] %-5p %m%n
# AXISCONSOLE is set to be a ConsoleAppender for Axis using a PatternLayout.
log4j.appender.AXISCONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.AXISCONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.AXISCONSOLE.layout.ConversionPattern=%d [%t] AXIS %-5p %c - %m%n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# HibernateConsole is set to be a ColsoleAppender for Hibernate message using a PatternLayout.
log4j.appender.HIBERNATECONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.HIBERNATECONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.HIBERNATECONSOLE.layout.ConversionPattern=%d{MM/dd HH:mm:ss} [%t] HIBERNATE %-5p - %m%n%n
#TEST LOG APPENDER
log4j.appender.frontAppender =org.apache.log4j.RollingFileAppender
log4j.appender.frontAppender.File=c:/frontTT.log
log4j.appender.frontAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.frontAppender.layout.ConversionPattern=%-5p %c %d - %m%n
log4j.appender.frontAppender.MaxFileSize=1024KB
#TEST MAIL APPENDER
log4j.appender.mail=DEBUG
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.SMTPHost=127.0.0.1
log4j.appender.mail.Subject=Error Message
log4j.appender.mail.From=mailtest@mydomain.com
log4j.appender.mail.To=mailtest@mydomain.com
log4j.appender.mail.BufferSize=10
log4j.appender.mail.Threshold=debug
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%-5p %c %d{ISO8601} - %m%n
Message was edited by: -==cfSearching==-
Copy link to clipboard
Copied
We had a similar problem with sending java-based email from a coldfusion page. The problem is that mail.jar and activation.jar in the ../WEB-INF/cfusion/lib directory contain mail-related classes, while /JRun4/lib/jrun.jar already contains them too.
So we just removed the two jars from the ../WEB-INF/cfusion/lib directory, and now Java works and CFMAIL still works too.
It sounds like Adobe made a configuration mistake.
Copy link to clipboard
Copied
It sounds like Adobe made a configuration mistake.
Thanks for the follow up. Interesting, I knew there were duplicate libraries, but was not adventurous enough to mess with the paths. You might consider filing a bug report . So if it is a mistake it could be fixed in future versions. If not at least we would find out why it was included and what it impacts
http://cfbugs.adobe.com/

