Why is log4j not behaving as expected? - configuration

I have a co-worker who is trying to get log4j to behave as follows:
Log to Stdout
By default, disable most output
Show only messages from java.sql.PrepareStatement at level debug and up
He's getting caught up in the 'level' vs 'priority'. Here is his config file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "D:/Java/apache-log4j-1.2.15/src/main/resources/org/apache/log4j/xml/log4j.dtd" >
<log4j:configuration>
<!-- Appenders -->
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%5p %d{ISO8601} [%t][%x] %c - %m%n" />
</layout>
</appender>
<!-- Loggers for ibatus and JDBC database -->
<logger name="java.sql.PreparedStatement">
<level value="debug"/>
</logger>
<!-- The Root Logger -->
<root>
<level value="error"/>
<appender-ref ref="stdout"/>
</root>
</log4j:configuration>
Simpler configuration as shown (Root Log Level = ERROR):
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [java.sql.PreparedStatement] additivity to [true].
log4j: Level value for java.sql.PreparedStatement is [debug].
log4j: java.sql.PreparedStatement level set to DEBUG
log4j: Level value for root is [error].
log4j: root level set to ERROR
log4j: Class name: [org.apache.log4j.ConsoleAppender]
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%5p %d{ISO8601} [%t][%x] %c - %m%n].
log4j: Adding appender named [stdout] to category [root].
Configuration with Root Log Level changed to debug (replace queries with …)
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [java.sql.PreparedStatement] additivity to [true].
log4j: Level value for java.sql.PreparedStatement is [debug].
log4j: java.sql.PreparedStatement level set to DEBUG
log4j: Level value for root is [debug].
log4j: root level set to DEBUG
log4j: Class name: [org.apache.log4j.ConsoleAppender]
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%5p %d{ISO8601} [%t][%x] %c - %m%n].
log4j: Adding appender named [stdout] to category [root].
DEBUG 2010-03-19 12:59:58,256 [main][] com.ibatis.common.jdbc.SimpleDataSource - Created connection 1309601.
DEBUG 2010-03-19 12:59:58,256 [main][] java.sql.Connection - {conn-100000} Connection
DEBUG 2010-03-19 12:59:58,256 [main][] java.sql.Connection - {conn-100000} Preparing Statement: …
DEBUG 2010-03-19 12:59:58,287 [main][] java.sql.PreparedStatement - {pstm-100001} Executing Statement: …
DEBUG 2010-03-19 12:59:58,287 [main][] java.sql.PreparedStatement - {pstm-100001} Parameters: [%ATL]
DEBUG 2010-03-19 12:59:58,287 [main][] java.sql.PreparedStatement - {pstm-100001} Types: [java.lang.String]
DEBUG 2010-03-19 12:59:58,366 [main][] java.sql.ResultSet - {rset-100002} ResultSet
DEBUG 2010-03-19 12:59:58,381 [main][] java.sql.ResultSet - {rset-100002} Header: …
DEBUG 2010-03-19 12:59:58,381 [main][] java.sql.ResultSet - {rset-100002} Result: …
DEBUG 2010-03-19 12:59:58,381 [main][] java.sql.ResultSet - {rset-100002} Result: …
DEBUG 2010-03-19 12:59:58,381 [main][] java.sql.ResultSet - {rset-100002} Result: …
DEBUG 2010-03-19 12:59:58,397 [main][] com.ibatis.common.jdbc.SimpleDataSource - Returned connection 1309601 to pool.
How does he need to change his log4j.xml config file to make it behave as he's expecting?

I looked at the source code for mybatis, shown below. You have to enable DEBUG on java.sql.Connection in order for it execute the logging for java.sql.PreparedStatement. I struggled with this all day!
private Connection wrapConnection(Connection connection) {
if (log.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection);
} else {
return connection;
}
}

Insert the following addition into your log4j.xml:
<!-- *******************************************************
WARNING: iBatus 2.3.3 (only ver. tested) is a little weird.
YOU MUST SET
java.sql.Connection to debug to get any
java.sql.PreparedStatement debug logs.
************************************************************** -->
<logger name="java.sql.Connection" additivity="false">
<level value="debug"/>
</logger>
DEBUG 2010-03-19 14:27:08,425 [main][][java.sql.PreparedStatement] - {pstm-100001} Executing Statement:
...

I think the reason there are no log messages is that code you want to see logs from, doesn't use java.sql.PrepareStatement logger, but different loggers. Loggers are usually (although not necessarilly) named after classes that use them. I.e. com.ibatis.SomeClass would typically not use java.sql.PrepareStatement logger.
Set your root logger to DEBUG, and check out names of loggers that give you messages you want. Then configure these loggers with DEBUG and let root log at ERROR level only.
Btw, it's Prepare_d_Statement, it is interface (i.e. no logging code there), and it definitely doesn't use log4j since it is in JDK.

Related

How to silence the logger from a specific library

I am using a library in my code which has the following logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date - %-5p %t %-25logger{0} %F:%L %m%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
I have no control over this .xml file because the library author owns this file and I just use her library as a jar file.
Now when I use the library as a jar, I see lots of "INFO" statements in my output. I want to shut the output of the logger just from this library.
I don't want to globally switch off (or raise severity of logs) for my application. I just want to silence the logs from this library.
How can I do that?
You can specify the location of your logback.xml as a system property, then you can change it.
As the logback document says:
Specifying the location of the default configuration file as a system property
You may specify the location of the default configuration file with a system property named "logback.configurationFile". The value of this property can be a URL, a resource on the class path or a path to a file external to the application.
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
Note that the file extension must be ".xml" or ".groovy". Other extensions are ignored. Explicitly registering a status listener may help debugging issues locating the configuration file.
UPDATE
To suppress logs from a specified package, you can define a logger in the logback.xml.
E.g. To suppress logs from "io.netty" package, add <logger name="io.netty" level="WARN"/> to your logback.xml.
I was able to solve the problem. I am listing my solution here for others.
So the problem is that we have multiple libraries and each has its own logger. we want the output from some and not from others. We can easily simulate this by the example below
package com.abhi
import org.slf4j.LoggerFactory
object Program extends App {
val f = new Foo()
val b = new Bar()
f.sayHello("Test1")
b.sayHello("Test2")
}
class Foo {
val logger = LoggerFactory.getLogger(classOf[Foo])
def sayHello(name: String) : String = {
logger.debug(s"++++++++++++ came inside Foo sayHello(${name}) +++++++++++++++++++++")
"Hello " + name
}
}
class Bar {
val logger = LoggerFactory.getLogger(classOf[Bar])
def sayHello(name: String) : String = {
logger.debug(s"++++++++++++ came inside Bar sayHello(${name}) +++++++++++++++++++++")
"Hello " + name
}
}
Now let's say we want to keep the output from Foo logger but don't want the output from Bar logger.
We will adjust our logback.xml like
<configuration debug="true">
<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>
<logger name="com.abhi.Foo" level="TRACE">
<appender-ref ref="STDOUT" />
</logger>
<root level="off" />
</configuration>
Here we are setting a logger explicitly for foo and setting its level to trace and setting the root to off. All people who don't have specific loggers will go to root and will not be able to log anything.

Log4J2 Programmatic Configuration from XML byte stream

I am at the end of my tether with Log4J2, hopefully somebody can help. I have the following code to initialize Log4J2, pretty soon after startup:
try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes("UTF-8"))) {
ConfigurationSource configurationSource = new ConfigurationSource(configStream);
Configurator.initialize(null, configurationSource);
}
Where writer is a StringWriter and toString() produces the following config (which I have validated is correct through other means):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="C" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS z} %-5p %m%n"/>
</Console>
<RollingFile name="R" fileName="C:\temp\logfile.log" filePattern="C:\temp\logfile.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS z} %-5p [%t] %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="somename" level="debug">
<appender-ref ref="R"/>
</Logger>
<Root level="debug" additivity="false">
<appender-ref ref="C" level="info"/>
</Root>
</Loggers>
</Configuration>
As you may have guessed, this does not work and I get no error message other than the expected:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
The reason I say this is expected is because I am configuring Log4J2 manually and have not suppressed this message yet.
Unfortunately, I cannot read the config from a file, for legacy reasons.
UPDATE 1 :
After taking Remko's advice, I added the following block before invoking the initialize method:
System.setProperty("log4j2.disable.jmx", "true");
StatusLogger status = StatusLogger.getLogger();
status.clear(); // remove old listeners that may prevent status output
status.setLevel(Level.TRACE);
status.reset(); // I could not see any trace info until I called this
status.trace("Status -- TRACE"); // I added this to prove that trace level logging was working
This gave me the following output:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
TRACE StatusLogger Status -- TRACE
DEBUG StatusLogger Stopping LoggerContext[name=sun.misc.Launcher$AppClassLoader#647e05, org.apache.logging.log4j.core.LoggerContext#a3defe]
DEBUG StatusLogger Stopping LoggerContext[name=sun.misc.Launcher$AppClassLoader#647e05, org.apache.logging.log4j.core.LoggerContext#a3defe]...
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader#647e05
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader#647e05,component=StatusLogger
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader#647e05,component=ContextSelector
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader#647e05,component=Appenders,name=Console
TRACE StatusLogger Stopping org.apache.logging.log4j.core.config.DefaultConfiguration#1a1440e...
TRACE StatusLogger AbstractConfiguration stopped 0 AsyncLoggerConfigs.
TRACE StatusLogger AbstractConfiguration stopped 0 AsyncAppenders.
DEBUG StatusLogger Shutting down OutputStreamManager SYSTEM_OUT
TRACE StatusLogger AbstractConfiguration stopped 1 Appenders.
TRACE StatusLogger AbstractConfiguration stopped 0 Loggers.
DEBUG StatusLogger Stopped org.apache.logging.log4j.core.config.DefaultConfiguration#9a6398 OK
DEBUG StatusLogger Stopped LoggerContext[name=sun.misc.Launcher$AppClassLoader#647e05, org.apache.logging.log4j.core.LoggerContext#9a6398]...
UPDATE 2 :
I decided to figure out a way to work with a file rather than a ByteArrayInputStream and got it working. FWIW, I think there is a bug in the Log4J2 code, when attempting to initialize using an InputStream, my theory:
In Log4jContextFactory the following method:
public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Object externalContext,
final boolean currentContext, final ConfigurationSource source)
Has the following if statement, which always evaluates to false, which means the default config is always returned...
if (ctx.getState() == LifeCycle.State.INITIALIZED) {
if (source != null) {
ContextAnchor.THREAD_CONTEXT.set(ctx);
final Configuration config = ConfigurationFactory.getInstance().getConfiguration(source);
LOGGER.debug("Starting LoggerContext[name={}] from configuration {}", ctx.getName(), source);
ctx.start(config);
ContextAnchor.THREAD_CONTEXT.remove();
} else {
ctx.start();
}
}
At first glance I don't see why your configuration does not work. (You could try using forward slashes in the paths to make absolutely sure, but chances are that the slashes are not the problem.)
Can you try the following to generate more log4j2 debug output to see where the configuration goes wrong? Please post the result in your question.
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusLogger;
// In an XML configuration you can just use <Configuration status="TRACE"...
// Here we use less elegant code to switch on status logging
// since we're not sure where things break down.
System.setProperty("log4j2.disable.jmx", "true");
StatusLogger status = StatusLogger.getLogger();
status.clear(); // remove old listeners that may prevent status output
status.setLevel(Level.TRACE);
// now configure log4j2...
// This should generate trace-level debug output to the console.
try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes())) {
ConfigurationSource configurationSource = new ConfigurationSource(configStream);
Configurator.initialize(null, configurationSource);
}

Why does a mule rollback exception propagate to the flow that called it?

I have a mule project where a flow with a rollback exception is causing an exception to be thrown in the flow that references it. Is this normal behaviour?
Here is the code:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file"xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.5.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">
<file:connector name="File" autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>
<flow name="rollbacktestFlow2" doc:name="rollbacktestFlow2">
<file:inbound-endpoint path="C:\RollbackTEst\In" responseTimeout="10000" doc:name="File" connector-ref="File"/>
<logger message="File Rx" level="INFO" doc:name="FileRx"/>
<flow-ref name="rollbacktestFlow1" doc:name="Flow Reference"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="Rollbacktestflow 2" level="INFO" doc:name="Rollbacktestflow2"/>
</catch-exception-strategy>
</flow>
<flow name="rollbacktestFlow1" doc:name="rollbacktestFlow1" >
<logger message="Rollback trigger" level="INFO" doc:name="RollbackTrigger"/>
<expression-component doc:name="Expression"><![CDATA[forceException]]></expression-component>
<rollback-exception-strategy maxRedeliveryAttempts="4" doc:name="Rollback Exception Strategy">
<logger message="retry" level="INFO" doc:name="retry"/>
<expression-component doc:name="Copy_of_Expression"><![CDATA[forceException]]></expression-component>
<on-redelivery-attempts-exceeded doc:name="Redelivery exhausted">
<logger message="exhausted" level="INFO" doc:name="exhausted"/>
</on-redelivery-attempts-exceeded>
</rollback-exception-strategy>
</flow>
Should the rollback section of the exception not be executed 4 times and then the redelivery exhausted exception be thrown?
Here is the log:
INFO 2014-11-12 15:36:40,529 [main] org.mule.module.launcher.MuleDeploymentService:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Started app 'rollbacktest' +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO 2014-11-12 15:36:40,544 [main] org.mule.module.launcher.DeploymentDirectoryWatcher:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Mule is up and kicking (every 5000ms) +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INFO 2014-11-12 15:37:18,031 [[rollbacktest].File.receiver.01] org.mule.transport.file.FileMessageReceiver: Lock obtained on file: C:\RollbackTEst\In\New Text Document.txt
INFO 2014-11-12 15:37:18,048 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: File Rx
INFO 2014-11-12 15:37:18,048 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: Rollback trigger
ERROR 2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.RollbackMessagingExceptionStrategy:
********************************************************************************
Message : Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
^
[Line: 1, Column: 1] (org.mule.mvel2.PropertyAccessException)
org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer:692 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/mvel2/PropertyAccessException.html)
2. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException)
org.mule.el.mvel.MVELExpressionLanguage:202 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
^
[Line: 1, Column: 1]
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: retry
ERROR 2014-11-12 15:37:18,079 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.RollbackMessagingExceptionStrategy: Failed to dispatch message to error queue after it failed to process. This may cause message loss.Logging Message here:
org.mule.DefaultMuleMessage
{
id=c8cf45f1-6a81-11e4-887d-005056b6086b
payload=[B
correlationId=<not set>
correlationGroup=-1
correlationSeq=-1
encoding=UTF-8
exceptionPayload=org.mule.message.DefaultExceptionPayload#1975a694
Message properties:
INVOCATION scoped properties:
originalFilename=New Text Document.txt
INBOUND scoped properties:
MULE_ORIGINATING_ENDPOINT=endpoint..C.Users.mik119.Desktop.RollbackTEst.In
directory=C:\RollbackTEst\In
fileSize=0
originalFilename=New Text Document.txt
timestamp=1415806637595
OUTBOUND scoped properties:
MULE_ENCODING=UTF-8
SESSION scoped properties:
}
org.mule.api.MessagingException: Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:32)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:94)
at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
at org.mule.processor.chain.InterceptingChainLifecycleWrapper.doProcess(InterceptingChainLifecycleWrapper.java:50)
at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
at org.mule.processor.chain.InterceptingChainLifecycleWrapper.access$001(InterceptingChainLifecycleWrapper.java:22)
at org.mule.processor.chain.InterceptingChainLifecycleWrapper$1.process(InterceptingChainLifecycleWrapper.java:66)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at org.mule.processor.chain.InterceptingChainLifecycleWrapper.process(InterceptingChainLifecycleWrapper.java:61)
at org.mule.exception.TemplateMessagingExceptionStrategy.route(TemplateMessagingExceptionStrategy.java:139)
at org.mule.exception.RollbackMessagingExceptionStrategy.route(RollbackMessagingExceptionStrategy.java:104)
at org.mule.exception.TemplateMessagingExceptionStrategy.handleException(TemplateMessagingExceptionStrategy.java:45)
at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:37)
at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:14)
at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:54)
at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:50)
at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:28)
at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:13)
at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:59)
at org.mule.execution.ErrorHandlingExecutionTemplate.execute(ErrorHandlingExecutionTemplate.java:30)
at org.mule.construct.Flow.process(Flow.java:76)
at org.mule.config.spring.factories.FlowRefFactoryBean$2.process(FlowRefFactoryBean.java:145)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:58)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:94)
at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:67)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:44)
at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:102)
at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:51)
at org.mule.processor.AsyncInterceptingMessageProcessor.processNextTimed(AsyncInterceptingMessageProcessor.java:118)
at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:189)
at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:182)
at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:16)
at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:30)
at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:14)
at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:54)
at org.mule.execution.ResolvePreviousTransactionInterceptor.execute(ResolvePreviousTransactionInterceptor.java:44)
at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:50)
at org.mule.execution.ValidateTransactionalStateInterceptor.execute(ValidateTransactionalStateInterceptor.java:40)
at org.mule.execution.IsolateCurrentTransactionInterceptor.execute(IsolateCurrentTransactionInterceptor.java:41)
at org.mule.execution.ExternalTransactionInterceptor.execute(ExternalTransactionInterceptor.java:48)
at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:28)
at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:13)
at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:109)
at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:30)
at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker.doRun(AsyncInterceptingMessageProcessor.java:181)
at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:39)
at org.mule.work.WorkerContext.run(WorkerContext.java:286)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.mule.api.expression.ExpressionRuntimeException: Execution of the expression "forceException" failed.
at org.mule.el.mvel.MVELExpressionLanguage.evaluateInternal(MVELExpressionLanguage.java:202)
at org.mule.el.mvel.MVELExpressionLanguage.evaluate(MVELExpressionLanguage.java:154)
at org.mule.el.mvel.MVELExpressionLanguage.evaluate(MVELExpressionLanguage.java:133)
at org.mule.el.ExpressionLanguageComponent.process(ExpressionLanguageComponent.java:51)
at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:24)
... 56 more
Caused by: [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
^
[Line: 1, Column: 1]
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
at org.mule.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
at org.mule.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
at org.mule.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
at org.mule.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mule.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mule.mvel2.MVEL.executeExpression(MVEL.java:943)
at org.mule.el.mvel.MVELExpressionExecutor.execute(MVELExpressionExecutor.java:72)
at org.mule.el.mvel.MVELExpressionLanguage.evaluateInternal(MVELExpressionLanguage.java:198)
... 60 more
ERROR 2014-11-12 15:37:18,095 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.exception.CatchMessagingExceptionStrategy:
********************************************************************************
Message : Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
^
[Line: 1, Column: 1] (org.mule.mvel2.PropertyAccessException)
org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer:692 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/mvel2/PropertyAccessException.html)
2. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException)
org.mule.el.mvel.MVELExpressionLanguage:202 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "forceException" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: unresolvable property or identifier: forceException]
[Near : {... forceException ....}]
^
[Line: 1, Column: 1]
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:692)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:337)
at org.mule.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2014-11-12 15:37:18,095 [[rollbacktest].rollbacktestFlow2.stage1.02] org.mule.api.processor.LoggerMessageProcessor: Rollbacktestflow 2
The exhausted logger is not getting called, instead the Rollbacktestflow2 logger in the initial flow is called.
Can anyone explain why? Thanks
Why the rollback-exception-strategy doesn't retry?:
The rollback-exception-strategy behaves differently depending on if the flow has a transaction or not, and on the kind of inbound connector ( transactional or reliable ).
To be able to reprocess the message, you need an inbound transport, so the rollback-exception-strategy can either rollback the transaction ( transactional transport with an open transaction ) or discard the message and try again ( reliable transport )
In your example you don't have an inbound connector on the second flow, so the rollback-exception-strategybehaves as section "Use Rollback Exception Strategy for Unhandled Exceptions" on the mule doc describes: "When the flow exchange pattern is request-response, rollback exception strategy changes the payload of a message and returns it to the client"
Although the doc is not explicit, when the flow doesn't have an inbound connector the rollback-exception-strategy doesn't retry.
If you want to implement a flow that retries, you can use a vm transport between the two flows.
Example:
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:https="http://www.mulesoft.org/schema/mule/https"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">
<file:connector name="File" autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>
<flow name="pickFiles" >
<file:inbound-endpoint path="/Users/ramiro/tmp/rollback/in" responseTimeout="10000" doc:name="File" connector-ref="File"/>
<logger message="File Rx" level="INFO" doc:name="FileRx"/>
<vm:outbound-endpoint path="buffer" exchange-pattern="one-way" doc:name="VM"/>
<catch-exception-strategy doc:name="Catch Exception Strategy">
<logger message="Rollbacktestflow 2" level="INFO" doc:name="Rollbacktestflow2"/>
</catch-exception-strategy>
</flow>
<flow name="processQueue" >
<vm:inbound-endpoint path="buffer" exchange-pattern="one-way" doc:name="VM">
<vm:transaction action="ALWAYS_BEGIN" />
</vm:inbound-endpoint>
<logger message="about to throw Exception..." level="INFO" doc:name="RollbackTrigger"/>
<scripting:component doc:name="throw Exception">
<scripting:script engine="Groovy"><![CDATA[
throw new Exception('some very bad error')
]]></scripting:script>
</scripting:component>
<!-- we never get here -->
<file:outbound-endpoint path="/Users/ramiro/tmp/rollback/success " doc:name="dlq" connector-ref="File"/>
<rollback-exception-strategy maxRedeliveryAttempts="4" doc:name="Rollback Exception Strategy">
<logger message="retry" level="INFO" doc:name="retry"/>
<on-redelivery-attempts-exceeded >
<logger message="exhausted" level="INFO" doc:name="exhausted"/>
<file:outbound-endpoint path="/Users/ramiro/tmp/rollback/dlq" doc:name="dlq" connector-ref="File"/>
</on-redelivery-attempts-exceeded>
</rollback-exception-strategy>
</flow>
</mule>
Here we get a file and send it via a vm transport. The second flow picks the message from the vm and if there's an exception ( always in the example ), will abort the transaction and try to process again the message, and if it fails 4 times then send it to a DLQ.
About until-successful
You say that you used until-successful as a workaround. In my opinion using rollback-exception-strategy is more appropriate when you have a unit of work that you need to handle as a transaction ( maybe a flow with several transformations and enrichments ), and until-successful when you just need to retry a step that may fail ( like calling a REST service that may fail because of a temporary network condition )

How to start spring-boot app without depending on Database?

I am using "Spring-boot + Hibernate4 + mysql" for my application. As part of which I have a requirement where my sprint-boot app should be able to start even when database is down. Currently it gives the below exception when I try to start my spring boot app without DB being up.
I researched a lot and found out that this exception has to do with hibernate.temp.use_jdbc_metadata_defaults property.
I tried setting this in "application.yml" of spring boot but this property's value is not being reflected at runtime.
Exception Stack Trace:
2014-05-25 04:09:43.193 INFO 59755 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
2014-05-25 04:09:43.250 WARN 59755 --- [ main] o.h.e.jdbc.internal.JdbcServicesImpl : HHH000342: Could not obtain connection to query metadata : Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2014-05-25 04:09:43.263 INFO 59755 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat
Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:750)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
at admin.Application.main(Application.java:36)
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:104)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:71)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:205)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:150)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 15 more
application.yml:
spring:
jpa:
show-sql: true
hibernate:
ddl-auto: none
naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
temp:
use_jdbc_metadata_defaults: false
It was indeed a tough nut to crack.
After lot and lot of research and actually debugging the spring-boot, spring, hibernate, tomcat pool, etc to get it done.
I do think that it will save lot of time for people trying to achieve this type of requirement.
Below are the settings required to achieve the following requirement
Spring boot apps will start fine even if DB is down or there is no DB.
Apps will pick up the connections on the fly as DB comes up which means there is no need to restart the web server or redeploy the apps.
There is no need to start the tomcat or redeploy the apps, if DB goes down from running state and comes up again.
application.yml :
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/schema
username: root
password: root
continueOnError: true
initialize: false
initialSize: 0
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 5000
minIdle: 0
jpa:
show-sql: true
hibernate:
ddl-auto: none
naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
hbm2ddl:
auto: none
temp:
use_jdbc_metadata_defaults: false
I am answering here and will close the issue that you have cross-posted
Any "native" property of the JPA implementation (Hibernate) can be set using the spring.jpa.properties prefix as explained here
I haven't looked much further in the actual issue here but to answer this particular question, you can set that hibernate key as follows
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults
Adding this alone worked for me:
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.Oracle10gDialect
Just replace the last part with your database dialect.
The solution is really useful for me. Thanks
i used file "application.properties" includes following lines:
app.sqlhost=192.168.10.11
app.sqlport=3306
app.sqldatabase=logs
spring.main.web-application-type=none
# Datasource
spring.datasource.url=jdbc:mysql://${app.sqlhost}:${app.sqlport}/${app.sqldatabase}
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.hbm2dll.auto = none
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.datasource.continue-on-error=true
spring.datasource.initialization-mode=never
spring.datasource.hikari.connection-timeout=5000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.initialization-fail-timeout= -1
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.output.ansi.enabled=always
But, you can not use #Transactional annotation at class level
#Service
//#Transactional //do not use to touch the Repository
#EnableAsync
#Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class LogService {
.... }
#Async
#Transactional // you can use at function level
public void deleteLogs(){
logRepository.deleteAllBy ...
}
Add following config should be work:
spring.jpa.database-platform: org.hibernate.dialect.MySQL5Dialect

Logback : append log message to outputstream appender

I'm using Logback framework v1.0.1 to do logging. I would like to know how to append the log message to an outputstream in java.
I wanted to format the log message into key=value pairs At the end i want to getformatted log message as an output stream. I retrieved the logger instance and log the message at debug level.
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("SplunkSearch.SplunkLogger");
logger.info( "wrap = true, setValue = false,");
logger.debug( "wrap = true, setValue = false,");
The logback.xml configuration file is as follows :
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" timeReference="contextBirth"/>
<contextName>splunksearchcontext</contextName>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name= "outputstream" class="ch.qos.logback.core.OutputStreamAppender">
<encoder>
<pattern></pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="stdout"/>
<appender-ref ref="outputstream" />
</root>
</configuration>
The output is as follows when i run.
i saw this line in the status message that is sort of error. No outputstream set.
15:07:19,399 |-ERROR in ch.qos.logback.core.OutputStreamAppender[outputstream] - No
output stream set for the appender named "outputstream".
15:07:19.414 [main] INFO SplunkSearch.SplunkLogger - wrap = true, setValue = false,
15:07:19.430 [main] DEBUG SplunkSearch.SplunkLogger - wrap = true, setValue = false,
It said "No output stream set for the appender named "outputstream"." You defined an appender, but not output stream in it. I don't know where to write the message.
logback manual said that you should not use outputstream appender directly. And from the manual, I also didn't find any way to configure the output stream into this appender.
If you really want to use it, I think the only way is that add it in your program.