3

Using Logback's conditional processing to compare two Strings in a Logback XML configuration file as follows ...

<if condition="'test'.equals('test')">
    <then>
        <include resource="logback.local.xml"/>
    </then>
</if>

... results in the following exception.

14:22:08,315 |-ERROR in ch.qos.logback.core.joran.conditional.IfAction - Failed to parse condition ['test'.equals('test')] org.codehaus.commons.compiler.CompileException: Line 1, Column 38: Closing single quote missing
    at org.codehaus.commons.compiler.CompileException: Line 1, Column 38: Closing single quote missing
    at  at org.codehaus.janino.Scanner.scan(Scanner.java:359)
    at  at org.codehaus.janino.Scanner.produce(Scanner.java:267)
    at  at org.codehaus.janino.TokenStreamImpl.produceToken(TokenStreamImpl.java:62)
    at  at org.codehaus.janino.TokenStreamImpl.peek(TokenStreamImpl.java:104)
    at  at org.codehaus.janino.TokenStreamImpl.peek(TokenStreamImpl.java:134)
    at  at org.codehaus.janino.Parser.peek(Parser.java:3145)
    at  at org.codehaus.janino.Parser.parseReturnStatement(Parser.java:2048)
    at  at org.codehaus.janino.Parser.parseStatement(Parser.java:1659)
    at  at org.codehaus.janino.Parser.parseBlockStatement(Parser.java:1512)
    at  at org.codehaus.janino.Parser.parseBlockStatements(Parser.java:1474)
    at  at org.codehaus.janino.Parser.parseMethodDeclarationRest(Parser.java:1313)
    at  at org.codehaus.janino.Parser.parseClassBodyDeclaration(Parser.java:894)
    at  at org.codehaus.janino.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:231)
    at  at org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:200)
    at  at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:76)
    at  at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:71)
    at  at ch.qos.logback.core.joran.conditional.PropertyEvalScriptBuilder.build(PropertyEvalScriptBuilder.java:47)
    at  at ch.qos.logback.core.joran.conditional.IfAction.begin(IfAction.java:65)
    at  at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(Interpreter.java:269)
    at  at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:145)
    at  at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:128)
    at  at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:50)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:155)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:142)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:103)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:53)
    at  at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)
    at  at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:150)
    at  at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
    at  at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
    at  at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
    at  at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
    at  at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
    at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
    at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
    at  at com.labcorp.ncp.provider.abn.service.impl.AbnServiceImpl.<clinit>(AbnServiceImpl.java:34)
    at  at sun.reflect.GeneratedSerializationConstructorAccessor5.newInstance(Unknown Source)
    at  at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at  at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
    at  at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59)
    at  at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
    at  at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
    at  at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at  at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at  at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at  at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at  at org.mockito.Mockito.mock(Mockito.java:1243)
    at  at org.mockito.Mockito.mock(Mockito.java:1120)
    at  at com.labcorp.ncp.provider.abn.service.AbnServiceTest.invalidDxCode(AbnServiceTest.java:61)
    at  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at  at java.lang.reflect.Method.invoke(Method.java:606)
    at  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at  at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at  at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:367)
    at  at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:274)
    at  at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
    at  at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:161)
    at  at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
    at  at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
    at  at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
14:22:08,316 |-ERROR in ch.qos.logback.core.joran.conditional.IfAction - Failed to determine "if then else" result
14:22:08,316 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
14:22:08,318 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
14:22:08,324 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
14:22:08,365 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
glytching
  • 35,192
  • 8
  • 84
  • 96
Kumar
  • 41
  • 5

1 Answers1

2

Utlimately the condition you define is executed as a Groovy script by Janino. Something like this:

  String script = "public boolean evaluate() { return \"test\".equals(\"test\"); }";

  ClassBodyEvaluator classBodyEvaluator = new ClassBodyEvaluator();
  classBodyEvaluator.setImplementedInterfaces(new Class[] { Condition.class });
  classBodyEvaluator.setExtendedClass(PropertyWrapperForScripts.class);
  classBodyEvaluator.setParentClassLoader(ClassBodyEvaluator.class.getClassLoader());

  StringReader sr = new StringReader(script);
  classBodyEvaluator.cook(null, sr);
  Class clazz = classBodyEvaluator.getClazz();
  Condition instance = (Condition) clazz.newInstance();

So, you just need to ensure that the value of the condition (which is substituted into the script) has quoted strings i.e. "...". But since you are defining the condition in XML you must escape the quotes, like so:

<if condition="&quot;test&quot;.equals(&quot;test&quot;)">

This will produce a script:

public boolean evaluate() { return "test".equals("test"); }

... for execution by ch.qos.logback.core.joran.conditional.PropertyEvalScriptBuilder.

I have verified this as follows ...

<if condition="&quot;test&quot;.equals(&quot;test&quot;)">
    <then>
        <property name="conditionalValue" value="Conditional value is true"/>
    </then>
    <else>
        <property name="conditionalValue" value="Conditional value is false"/>
    </else>
</if>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>
            %d|%-5p|%t|${conditionalValue}%n
        </pattern>
    </encoder>
</appender>

... and a log event written by this appender looks like:

2017-08-09 09:07:02,699|INFO |main|Conditional value is true
glytching
  • 35,192
  • 8
  • 84
  • 96