0

I am upgrading my web application from log4j 1.2 to log4j 2.

My legacy code uses commons-logging 1.2 API to create a 'log' (logger) for each class. Using the log4j2 logger is a huge work to replace in our classes.

Following is the example code, which I have created as starting point :

package com.example.testwebapp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.*;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;

public class Log4j2ConfigBuilder {

  private static final Logger logger = LogManager.getLogger(Log4j2ConfigBuilder.class);


  public static void main(String[] args) {
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
    AppenderComponentBuilder console = builder.newAppender("stdout", "Console");
    builder.add(console);

    AppenderComponentBuilder file = builder.newAppender("log", "File");
    file.addAttribute("fileName", "c://soap//logging2.log");

    AppenderComponentBuilder rollingFile
        = builder.newAppender("rolling", "RollingFile");
    rollingFile.addAttribute("fileName", "c://soap//rolling.log");
    rollingFile.addAttribute("filePattern", "rolling-%d{MM-dd-yy}.log.gz");

    LayoutComponentBuilder standard = builder.newLayout("PatternLayout");
    standard.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable");

    console.add(standard);
    file.add(standard);
    rollingFile.add(standard);

//    builder.add(rollingFile);

    builder.add(console);
    builder.add(file);

    RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);
    rootLogger.add(builder.newAppenderRef("stdout"));
    rootLogger.add(builder.newAppenderRef("log"));
    builder.add(rootLogger);

    System.out.println("builder.toXmlConfiguration() = \n " + builder.toXmlConfiguration());
    Configurator.initialize(builder.build());

    getLog().debug("DEBUG log entryc 11111 ");
    getLog().info("INFO log entry ");
    getLog().error("ERROR log entry ");
    getLog().warn("#############  WAR log entry ");

    logger.debug("this is debug message work");
    logger.info("this is info message work");
    logger.warn("$$$$$$$$$$  this is warn message works");
    logger.error("#######  this is error message works");

  }

I am finding that the log messages from the common-logging api , do no go into the FileAppender .

I started with the following maven file :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>TestWebApp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>TestWebApp</name>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.7.1</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

I then added the following in my dependency,

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jcl</artifactId>
    <version>2.7</version>
</dependency>

I am getting the following exception :

2021-12-27 18:27:16,640 main DEBUG Registering MBean org.apache.logging.log4j2:type=1d44bcfa,component=Appenders,name=LogToFile
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/util/ReflectionUtil
    at org.apache.logging.log4j.jcl.LogAdapter.getContext(LogAdapter.java:39)
    at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:47)
    at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:40)
    at org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(LogFactoryImpl.java:55)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
    at vish.Log4jDelegate.getLog(Log4jDelegate.java:58)
    at vish.Log4jDelegate.main(Log4jDelegate.java:49)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.util.ReflectionUtil
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
    ... 7 more

Any help will be highly appreciated.

Progman
  • 14,690
  • 4
  • 32
  • 46
  • 3
    Does this answer your question? [I'm getting "NoClassDefFoundError: org/apache/logging/log4j/util/ReflectionUtil"](https://stackoverflow.com/questions/52700803/im-getting-noclassdeffounderror-org-apache-logging-log4j-util-reflectionutil) (which is (one of the) first link(s) on [Google](https://www.google.com/search?q=java.lang.NoClassDefFoundError%3A+org%2Fapache%2Flogging%2Flog4j%2Futil%2FReflectionUtil)) – Luuk Dec 27 '21 at 13:42
  • 2
    typo: `2.7` -> `2.17`?(!) Welcome! :-) – xerx593 Dec 27 '21 at 13:44
  • whenever you use `x.y.z` (version) twice or more (in your pom(s)), introduce a `property` and manage (as possible) only that ;) – xerx593 Dec 27 '21 at 13:51
  • thanks for all your valuable suggestion.. – Vishwanath Washimkar Dec 27 '21 at 15:46

0 Answers0