Codes with Hammer
Codes with Hammer

Reputation: 828

Logger.getLogger generates Index Out Of Bounds exception

I'm using Log4j2 with the 1.2 APIs. I just upgraded ActiveMQ from 5.16 to 5.18 and resolved issues with the individual JAR files. Before the upgrade, logging worked properly.

(In reply to comment: The app had been using activemq-all 5.16.3 and I upgraded it to use activemq-client-5.18.6 and jakarta.jms-api 2.0.3. The logging uses log4j=core 2.17.1, log4j-api, and log4j-1.2-api)

My app configuration uses the line log4j.configuration=${CFG_DIR}/log4j.properties, where ${CFG_DIR} is the app's config file directory. This hasn't changed.

The contents of log4j.properties which is not a Log4j 2 file:

log4j.rootLogger=WARN,defaultAppender
log4j.appender.defaultAppender=org.apache.log4j.RollingFileAppender
log4j.appender.defaultAppender.MaxFileSize=20MB
log4j.appender.defaultAppender.MaxBackupIndex=25
log4j.appender.defaultAppenderlayout=org.apache.log4j.PatternLayout
log4j.appender.defaultAppender.layout.ConversionPattern=[%d{yy-MM-dd HH:mm:ss.SSS}] %20C{3}:%L [%-6.6p] => %m%n
log4j.appender.defaultAppender.append=true

When the app starts it generates an error almost identical to this unanswered question: https://community.splunk.com/t5/Splunk-Dev/logging-configuration-generates-index-out-of-bounds-error/m-p/681421 -- I have copied the identical part here for reference, and confirmed that this portion exactly matches my stack trace:

java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 9
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
at org.apache.logging.log4j.util.PropertiesUtil.partitionOnCommonPrefixes(PropertiesUtil.java:555)
at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationBuilder.build(PropertiesConfigurationBuilder.java:156)
at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory.getConfiguration(PropertiesConfigurationFactory.java:56)
at org.apache.logging.log4j.core.config.properties.PropertiesConfigurationFactory.getConfiguration(PropertiesConfigurationFactory.java:35)
at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:557)
at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:481)
at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:323)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:695)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:716)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:270)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:155)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:47)

And then my call stack continues:

at org.apache.logging.log4j.LogManager.getContext(LogManager.java:309)
at org.apache.log4j.Logger$PrivateManager.getContext(Logger.java:59)
at org.apache.log4j.Logger.getLogger(Logger.java:59)
at com.foo.main.Bar.<init>(Bar.java:100)
at com.foo.main.Bar.main(Bar.java:24601)

The relevant line in my file Bar.java is:

private Logger logger = Logger.getLogger(Bar.class);

I have tried passing the class name as a hard-coded string, but that got the exact same exception.

Thought on edit in reply to comment: It's possible the ActiveMQ library is still trying to load its log4j.properties file instead of the app's file. But since I'm no longer using activemq-all that default-ish file isn't found.

Upvotes: 0

Views: 54

Answers (1)

plongueira
plongueira

Reputation: 11

The error you're seeing is caused by the incompatibility between Log4j 1.2 configurations and Log4j 2, especially when using the Logger class from Log4j 1.2 while you're using Log4j 2 in your application. Possible cause:

Log4j 2 is not fully compatible with Log4j 1.x configurations (like the one in your log4j.properties file). When you're using Logger.getLogger(Bar.class), which belongs to Log4j 1.x, Log4j 2 may be trying to read the Log4j 1.x configuration but cannot handle the syntax of the log4j.properties file for Log4j 1.2 correctly, leading to the StringIndexOutOfBoundsException error. Possible solutions:

  • Ensure all dependencies are aligned: Since you mentioned upgrading from activemq-all to activemq-client and using log4j-api, log4j-core, and log4j-1.2-api, it's crucial to make sure the versions are compatible. In your case, you're using Log4j 2.17.1 and Log4j 1.2 API, which might not be handling the configuration properly.

  • Configure the log4j2.xml or log4j2.properties file: If you want to continue using Log4j 2, you need to use a configuration compatible with Log4j 2 (for example, log4j2.xml or log4j2.properties) instead of log4j.properties. Here's an example of a log4j2.xml configuration:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <RollingFile name="File" fileName="${CFG_DIR}/app.log"
                     filePattern="${CFG_DIR}/app-%d{MM-dd-yyyy}.log">
            <PatternLayout pattern="[%d{yy-MM-dd HH:mm:ss.SSS}] %20C{3}:%L [%-6.6p] => %m%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="warn">
            <AppenderRef ref="File"/>
        </Root>
    </Loggers>
    </Configuration>
  • This replaces your log4j.properties file with a fully compatible Log4j 2 configuration.
  • Disable the bridge between Log4j 1.x and Log4j 2 (if not necessary): If you're not using Log4j 1.x and want to switch fully to Log4j 2, remove the log4j-1.2-api dependency from your pom.xml or build.gradle file (depending on your build system). This will make Log4j 2 handle all logging without trying to bridge with Log4j 1.x.
  • Check the configuration loading: As you mentioned, it's possible that ActiveMQ is still trying to load its own log4j.properties file instead of your app's file. Make sure that the Log4j 2 configuration is being loaded correctly and that ActiveMQ isn't overriding this configuration. You can do this by ensuring that the Log4j 1.x log4j.properties file isn't in the classpath of your application.
  • Check ActiveMQ library compatibility with Log4j 2: Although you upgraded ActiveMQ to version 5.18.6, it's possible that some internal configuration of ActiveMQ is still trying to use Log4j 1.x instead of Log4j 2. Make sure that any references to log4j in ActiveMQ dependencies are aligned with the version you're using (Log4j 2).

Summary:

  • Change the configuration file to one compatible with Log4j 2 (log4j2.xml or log4j2.properties)
  • Make sure all dependencies are compatible with Log4j 2 and not Log4j 1.x.
  • Check if ActiveMQ is causing conflicts by loading its own log4j.properties file.
  • Consider removing the Log4j 1.x bridge if you're only using Log4j 2.

With these actions, you should be able to resolve the issue you're facing

Upvotes: 0

Related Questions