Tanzu Application Service application consuming Tanzu GemFire for VMs throws BeanCreationException
search cancel

Tanzu Application Service application consuming Tanzu GemFire for VMs throws BeanCreationException

book

Article ID: 293966

calendar_today

Updated On:

Products

VMware Tanzu Gemfire

Issue/Introduction

When creating a Tanzu Application Service application consuming Tanzu GemFire for VMs, it throws the following error and doesn't start up:
Error: 2020-12-24T11:18:14.311+00:00 [APP/PROC/WEB/0] [ERR] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jvmGcMetrics' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration$JvmMeterBindersConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.micrometer.core.instrument.binder.jvm.JvmGcMetrics]: Factory method 'jvmGcMetrics' threw exception; nested exception is java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

When adding the spring-boot-starter-logging dependency in the application POM, the application does start up but fails with the below error while making the connection to Tanzu GemFire for VMs:
2019-01-14T11:40:01.577+00:00 [APP/PROC/WEB/0] [OUT] 2020-12-24 11:40:01.576 ERROR 21 — [joe-8080-exe-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/logging/log4j/core/Logger] with root cause

In this scenario the developer is using spring boot but is manually adding the GemFire dependencies like shown below:
        <dependency>
            <groupId>io.pivotal.gemfire</groupId>
            <artifactId>geode-core</artifactId>
            <version>9.10.7</version>
        </dependency>

The error, "java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory", means that the slfJ logger implementation is missing. GemFire on its own requires the log4j-api-*.jar and log4j-core-*.jar to be added in the CLASSPATH.

Resolution

Your initial thought may be adding the slf4j-log4j12 artifact to the appllication POM instead of enabling the spring-boot-starter-logging dependency:

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.7.30</version>
</dependency>

However, in this case the developer will be trying to override how Maven solves the dependencies, which is not the correct way to solve the issue.

The recommended approach for a TAS app using GemFire is to use either Spring Data GemFire (SDG) or the spring-gemfire-starter dependency to handle the dependencies cleanly.

We do not recommend manually adding GemFire dependencies directly in the pom.xml as shown in the example below:

        <dependency>
            <groupId>org.springframework.geode</groupId>
            <artifactId>spring-gemfire-starter</artifactId>
            <version>1.4.0.M1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

In this example, <exclusions> are used to avoid adding the dependencies multiple times and therefore you can avoid having different artifacts pulling in different versions of the libraries. In this scenario we are letting the parent dependency pull in the only log4j-to-slf4j artifact with the initial dependency as follows:

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

For more information on the compatibility between GemFIre, Spring, and SDG, refer to Compatibility and Versions