简体   繁体   中英

Spring MVC Could not initialize class com.mongodb.MongoClient

A java.lang.NoClassDefFoundError arises when trying to create the MongoFactory bean. It would compile and run without the MongoDbFactory bean.

import com.mongodb.MongoClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.fiddle.spring")
public class AppConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }


    @Bean
    public MongoDbFactory mongoDbFactory() throws Exception {
        MongoClient nmc = new MongoClient("127.0.0.1", 27017);
        final String dbName = "dbname";
        return new SimpleMongoDbFactory(nmc, dbName);
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {

        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());

        return mongoTemplate;

    }
}

The bottom of the stack is

root cause

java.lang.NoClassDefFoundError: Could not initialize class com.mongodb.MongoClient
    com.fiddle.spring.config.AppConfig.mongoDbFactory(AppConfig.java:48)
    com.fiddle.spring.config.AppConfig$$EnhancerBySpringCGLIB$$69146fb3.CGLIB$mongoDbFactory$2(<generated>)
    com.fiddle.spring.config.AppConfig$$EnhancerBySpringCGLIB$$69146fb3$$FastClassBySpringCGLIB$$fe0e5588.invoke(<generated>)
    org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
    com.fiddle.spring.config.AppConfig$$EnhancerBySpringCGLIB$$69146fb3.mongoDbFactory(<generated>)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:754)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)

The logic of the bean creation is from https://www.mkyong.com/mongodb/spring-data-mongodb-hello-world-example/

Even though it is not done for spring web mvc, the logic should integrate correctly, right? I am still very new to spring.

Here is the 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>deleted</groupId>
    <artifactId>deleted</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <name>deleted</name>
    <url>http://maven.apache.org</url>
    <properties>
        <java-version>1.8</java-version>
        <org.springframework-version>4.3.4.RELEASE</org.springframework-version>
        <javax.servlet-version>3.1.0</javax.servlet-version>
        <javax.servlet-jstl-version>1.2</javax.servlet-jstl-version>
        <java-mongo-driver-version>3.4.0</java-mongo-driver-version>
        <spring-mongo-version>1.9.5.RELEASE</spring-mongo-version>
        <maven-plugin-compiler-version>3.6.0</maven-plugin-compiler-version>
        <maven-plugin-war-version>3.0.0</maven-plugin-war-version>
        <logger-slf4j-version>1.7.21</logger-slf4j-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>${spring-mongo-version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax.servlet-version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${javax.servlet-jstl-version}</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver</artifactId>
            <version>${java-mongo-driver-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${logger-slf4j-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${logger-slf4j-version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>deleted</finalName>

        <pluginManagement>

            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven-plugin-compiler-version}</version>
                    <configuration>
                        <source>${java-version}</source>
                        <target>${java-version}</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>${maven-plugin-war-version}</version>
                    <configuration>
                        <warSourceDirectory>src/main/webapp</warSourceDirectory>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
            </plugins>

        </pluginManagement>

    </build>
</project>

The error you are getting is because of conflicting mongodb driver version. One provided by you and the other spring data mongo db is packaged with. You can address this problem in couple of ways.

You can exclude the mongodb driver dependency from spring data mongodb dependency.

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-mongodb</artifactId>
  <version>${spring-mongo-version}</version>
  <exclusions>
    <exclusion>
       <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Or remove the mongodb driver dependency so spring can use the mongodb driver dependency it is packaged with.

<dependency>
  <groupId>org.mongodb</groupId>
  <artifactId>mongodb-driver</artifactId>
  <version>${java-mongo-driver-version}</version>
</dependency>

As a side note its not advisable to upgrade mongodb driver to version other than what spring supports as the changes may not be fully backward compatible. So you are better off using option 2 for now which is removing the mongodb driver dependency and wait for new spring mongo data version where you've support for mongodb driver 3.x versions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM