Is it me, or are the MongoDb drivers and Spring-Shell deeply incompatible? To start, I'm not talking about the Spring-Data-Mongo stuff, I'm talking about the actual java client that the MongoDb folks put out.
My Pom is as follows:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>3.11.0</version>
</dependency>
</dependencies>
If I try to use the MongoDb client from the Spring shell, I consistenty get noclassdeffound errors all over the place. A simplified bare bones shell method is as follows:
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import java.util.Date;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
@ShellComponent
public class AuditCommands {
@ShellMethod("Just testing here")
public int cube(int number)
{
return number*number*number;
}
@ShellMethod("Sends a test document to mongo")
public void mgo()
{
System.out.println("Hello there. Doing some mongo stuff");
//MongoClient mongoClient = MongoClients.create();
MongoClient mongoClient = MongoClients.create("mongodb://whateversite:12345");
// New up a registry to automatically handle pojos
CodecRegistry pojoCodecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
fromProviders(PojoCodecProvider.builder().automatic(true).build()));
// Grep database instance
MongoDatabase database = mongoClient.getDatabase("MyDb");
database = database.withCodecRegistry(pojoCodecRegistry);
MongoCollection<Audit> collection = database.getCollection("MyCollection", Audit.class);
Audit audit = new Audit();
audit.setAuditId(1);
audit.setAuditTypeId(5);
audit.setCreatedOn(new Date());
audit.setMessage("Making mongo great again..");
collection.insertOne(audit);
System.out.println("Done..!!..");
}
}
I receive the following error if I try to execute the "mgo" ShellMethod in my example I get the following error.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-09-02 18:10:54.634 ERROR 18848 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
com.mongodb.client.internal.MongoClientImpl.<init>(MongoClientImpl.java:67)
The following method did not exist:
com.mongodb.MongoClientSettings.getAutoEncryptionSettings()Lcom/mongodb/AutoEncryptionSettings;
The method's class, com.mongodb.MongoClientSettings, is available from the following locations:
jar:file:/C:/Users/xxxxx/.m2/repository/org/mongodb/mongodb-driver-core/3.8.2/mongodb-driver-core-3.8.2.jar!/com/mongodb/MongoClientSettings.class
It was loaded from the following location:
file:/C:/Users/xxxxx/.m2/repository/org/mongodb/mongodb-driver-core/3.8.2/mongodb-driver-core-3.8.2.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of com.mongodb.MongoClientSettings
Process finished with exit code 1
If I remove Spring-Shell and Spring-Boot, that MongoDb code works fine.
So what gives here? Am I missing some essential point here or is this stuff essentially broken? I'm not a Java/Spring native, so I'm sure it won't come as a surprise when I say that connecting to Mongo and throwing a couple of documents around comes off muuuuuuch cleaner in C#, Python, and node. (And yes I know I can use spring-data-mongo, but that just seems like a really opinionated API for someone coming from a different language background)