logfellow/logstash-logback-encoder

Getting "Unable to get public no-arg constructor" When Using "logstash LogstashEncoder"

pfconrey opened this issue · 2 comments

Describe the bug
Spring Boot application fails with com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module Unable to get public no-arg constructor. This appears to be a logstash incompatibility with jackson-datatype-hibernate5.

To Reproduce
Steps to reproduce the behavior:

  1. Usin this logback.xml configuration:
<configuration>
  <appender name="json" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
  </appender>

  <root level="INFO">
    <appender-ref ref="json" />
  </root>
</configuration>
  1. With Spring-boot-starter 2.7.4. Sample 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.4</version>
    <relativePath />
  </parent>

  <groupId>com.peterconrey.poc</groupId>
  <artifactId>logging-error-poc</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>logging-error-poc</name>
  <description>Error POC</description>

  <properties>
    <java.version>11</java.version>
    <lombok.version>1.18.24</lombok.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>net.logstash.logback</groupId>
      <artifactId>logstash-logback-encoder</artifactId>
      <version>7.2</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-hibernate5</artifactId>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Expected behavior
Application should start and respond with "Hello" when navigating in a browser to http://localhost:8080/. If I remove the jackson-datatype-hibernate5 dependency, the application functions as expected.

  • logstash-logback-encoder version: 7.3
  • logback version: 1.2.11
  • jackson version 2.13.4
  • java version OpenJDK Runtime Environment Temurin-11.0.14.1+1 (build 11.0.14.1+1)

The exception happens when LLE creates its first ObjectMapper. During this process Jackson finds the jackson-datatype-hibernate5 module but fails to initialise it with the following exception:

17:24:47,908 |-ERROR in net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder@773f7880 - Error occurred while dynamically loading jackson modules java.util.ServiceConfigurationError: com.fasterxml.jackson.databind.Module: com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module Unable to get public no-arg constructor
	at java.util.ServiceConfigurationError: com.fasterxml.jackson.databind.Module: com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module Unable to get public no-arg constructor
	at 	at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:582)
	at 	at java.base/java.util.ServiceLoader.getConstructor(ServiceLoader.java:673)
	at 	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1233)
	at 	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1265)
	at 	at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1300)
	at 	at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1385)
	at 	at com.fasterxml.jackson.databind.ObjectMapper.findModules(ObjectMapper.java:1105)
...
Caused by: java.lang.NoClassDefFoundError: org/hibernate/engine/spi/Mapping
	at 	at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
	at 	at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3137)
...
Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.spi.Mapping
	at 	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at 	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
...

As you can see, the module failed to initialise because it doesn't find the required Hibernate classes on the classpath. After reading your pom dependencies it looks like that Hibernate is simply not included... May be you should add it explicitly or transitively through spring data spa for instance:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

The issue is more with your dependencies being incomplete rather than an LLE issue.
Hope this helps.

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.