javamavenjarlog4j2

Log4j2 No inject constructor error when launching through java.exe


I have a program in java made through maven and packaged with assembly into a single jar with all the dependencies. I need to run this in docker so I need to be able to launch it with java.exe. The issue is that log4j2 throws and error. I have found a post with the same error as me and there is an answer. Unfortunately I do not understand what the answer is trying to say and I don't have the reputation to add a comment and ask for clarification.

No default constructor found; nested exception is java.lang.NoSuchMethodException with Log4J?

This is the error:

PS C:\Users\pholub\eclipse testing\image-resizing-tool\rescaler> C:\DEV_HOME\TOOLS\java\1.17.0_5\bin\java.exe -jar .\target\rescaler-1.0.0-jar-with-dependencies.jar                                         
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: org.apache.logging.log4j.plugins.di.NotInjectableException: No @Inject constructor or default constructor found for chain Key[type: org.apache.logging.log4j.core.lookup.InterpolatorFactory] -> Key[type: java.util.Map<java.lang.String, java.util.function.Supplier<org.apache.logging.log4j.core.lookup.StrLookup>>; namespace: Lookup]
        at org.apache.logging.log4j.plugins.di.DefaultInstanceFactory.createDefaultFactory(DefaultInstanceFactory.java:133)
        at org.apache.logging.log4j.plugins.di.DefaultInstanceFactory.lambda$getFactory$3(DefaultInstanceFactory.java:111)
        at java.base/java.util.Optional.orElseGet(Optional.java:364)
        at org.apache.logging.log4j.plugins.di.DefaultInstanceFactory.getFactory(DefaultInstanceFactory.java:111)
        at org.apache.logging.log4j.plugins.di.InstanceFactory.getInstance(InstanceFactory.java:126)
        at org.apache.logging.log4j.plugins.di.DefaultInstanceFactory.lambda$getArgumentFactory$9(DefaultInstanceFactory.java:211)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
        at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
        at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
        at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
        at org.apache.logging.log4j.plugins.di.DefaultInstanceFactory.lambda$registerBundleMethod$13(DefaultInstanceFactory.java:293)
        at org.apache.logging.log4j.plugins.di.InstanceFactory.getInstance(InstanceFactory.java:115)
        at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:185)
        at org.apache.logging.log4j.core.config.DefaultConfiguration.<init>(DefaultConfiguration.java:41)
        at org.apache.logging.log4j.core.LoggerContext.<init>(LoggerContext.java:89)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(ClassLoaderContextSelector.java:289)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector.java:240)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:148)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:131)
        at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:125)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:156)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:49)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:127)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:554)
        at gk.tools.rescaler.App.<clinit>(App.java:55)

This is my pom.xml:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>gk.tools.rescaler</groupId>
  <artifactId>rescaler</artifactId>
  <version>1.0.0</version>

  <name>rescaler</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>3.0.0-beta2</version>
    </dependency>


    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>3.0.0-beta2</version>
    </dependency>


    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.14.0</version>
    </dependency>


    <dependency>
      <groupId>com.beust</groupId>
      <artifactId>jcommander</artifactId>
      <version>1.82</version>
    </dependency>


    <dependency>
      <groupId>com.github.downgoon</groupId>
      <artifactId>marvin</artifactId>
      <version>1.5.5</version>
      <type>pom</type>
    </dependency>


    <dependency>
      <groupId>com.github.downgoon</groupId>
      <artifactId>MarvinFramework</artifactId>
      <version>1.5.5</version>
    </dependency>


    <dependency>
      <groupId>com.github.downgoon</groupId>
      <artifactId>MarvinPlugins</artifactId>
      <version>1.5.5</version>
    </dependency>


    <dependency>
      <groupId>net.coobird</groupId>
      <artifactId>thumbnailator</artifactId>
      <version>0.4.20</version>
    </dependency>


    <dependency>
      <groupId>org.imgscalr</groupId>
      <artifactId>imgscalr-lib</artifactId>
      <version>4.2</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
            <archive>
              <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>gk.tools.rescaler.App</mainClass>
              </manifest>
            </archive>
          </configuration>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
              <archive>
                <manifest>
                  <mainClass>gk.tools.rescaler.App</mainClass>
                </manifest>
              </archive>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id> <!-- this is used for inheritance merges -->
                <phase>package</phase> <!-- bind to the packaging phase -->
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

And the error is on line with this code:

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

edit: also including my log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <appenders>

    <File name="ConciseLog" fileName="logs/app.log">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      <Filters>
        <ThresholdFilter level="info"/>
      </Filters>
    </File>

    <File name="DebugLog" fileName="logs/app-debug.log">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      <Filters>
        <ThresholdFilter level="debug"/>
      </Filters>
    </File>

    <File name="TraceLog" fileName="logs/app-trace.log" append="false">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>

    <Console name="ErrorConsole" target="SYSTEM_OUT"> 
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      <Filters>
        <ThresholdFilter level="error"/>
      </Filters>
    </Console>
  </appenders>

  <loggers>
    <root level="trace">
      <appender-ref ref="DebugLog"/>
      <appender-ref ref="ConciseLog"/>
      <appender-ref ref="ErrorConsole"/>
      <appender-ref ref="TraceLog"/>
    </root>
  </loggers>

</configuration>

Sorry if this is considered duplication, but I'm not able to figure this out. From what I can understand I need to add something into the classpath, but I can't find what exactly is needed to be added. I have found that log4j2 ignores the classpath command line argument, but I don't know what to do with that information. I think I get the fact that I need to add external jar files into classpath, but everything should be included.


Solution

  • Because I have tested log4j2.xml and the dependent log4j version, the test results seem to be OK.

    Then the possible problem may be the encapsulated jar file.

    Since I don't have the complete project content, the easiest way is to test it without encapsulating it into an Uber Jar in the following way.

    package

    mvn clean package

    download dependencies jar files to target/libs

    mvn dependency:copy-dependencies -DoutputDirectory=target/libs

    Run App

    For Windows

    java -cp "target\libs\*;target\rescaler-1.0.0.jar" gk.tools.rescaler.App