在比较 XML 中的字符串时缺少右单引号,以便与 Janino 进行登录



使用Logback的条件处理来比较Logback XML配置文件中的两个字符串,如下所示...

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

。导致以下异常。

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]

实际上,您定义的条件由 Janino 作为 Groovy 脚本执行。像这样:

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();

因此,您只需要确保条件的值(替换到脚本中(具有引号字符串,即"...".但是,由于您在 XML 中定义条件,因此必须转义引号,如下所示:

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

这将生成一个脚本:

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

。由ch.qos.logback.core.joran.conditional.PropertyEvalScriptBuilder执行。

我已经验证了这一点,如下所示...

<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>

。此追加器编写的日志事件如下所示:

2017-08-09 09:07:02,699|INFO |main|Conditional value is true

最新更新