问题
I'm super stuck o_0
While trying to authenticate via Java driver, there is an issue with catching exception. As you may see even Throwable
class doesn't work
private MongoClient mongoClient;
private MongoDatabase mongoDatabase;
public MongoConnection(String login, String password) {
try {
mongoClient = new MongoClient(asList(new ServerAddress("localhost"), new ServerAddress("localhost:27017")),
singletonList(MongoCredential.createCredential(login,
"cookbook",
password.toCharArray())));
this.mongoDatabase = mongoClient.getDatabase("cookbook");
} catch (Throwable e) {
System.out.println("exception");
}
}
still doesn't catch exception
INFO: Adding discovered server localhost:27017 to client view of cluster
Jan 29, 2016 7:46:27 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='asdasdasdasd', source='cookbook', password=<hidden>, mechanismProperties={}}
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:61)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.mongodb.MongoCommandException: Command failed with error 18: 'Authentication failed.' on server localhost:27017. The full response is { "ok" : 0.0, "code" : 18, "errmsg" : "Authentication failed." }
at com.mongodb.connection.CommandHelper.createCommandFailureException(CommandHelper.java:170)
at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123)
at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
at com.mongodb.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:95)
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:45)
回答1:
Recent versions of the MongoDB java API throw connection exceptions in within a separate daemon monitor thread, which is why you cannot catch it- the runner is here in your stack trace: com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run
To monitor the MongoDB client for exceptions, you can add a listener that will allow you to act on any exceptions that may occur and check the connection status anytime you need. You still won't be able to catch these exceptions, but your application will at least be made aware of them. One thing to note is it can take some time for the connection to be established (or fail), so if you're just interested in creating a one-time use connection I'd recommend implementing a sleep loop that checks for the connection OK and failed/exception states. I wrote this solution using version 3.3 (https://api.mongodb.com/java/3.3/):
public class MongoStatusListener implements ServerListener {
private boolean available = false;
public boolean isAvailable() {
return available;
}
@Override
public void serverOpening(ServerOpeningEvent event) {}
@Override
public void serverClosed(ServerClosedEvent event) {}
@Override
public void serverDescriptionChanged(ServerDescriptionChangedEvent event) {
if (event.getNewDescription().isOk()) {
available = true;
} else if (event.getNewDescription().getException() != null) {
//System.out.println("exception: " + event.getNewDescription().getException().getMessage());
available = false;
}
}
}
public MongoClient getMongoClient(String login, String password) {
if (mongoClient != null) {
return mongoClient;
}
MongoClientOptions.Builder optionsBuilder = new MongoClientOptions.Builder();
MongoStatusListener mongoStatusListener = new MongoStatusListener();
optionsBuilder.addServerListener(mongoStatusListener);
this.mongoClient = new MongoClient(asList(new ServerAddress("localhost"), new ServerAddress("localhost:27017")),
singletonList(MongoCredential.createCredential(
login,
"cookbook",
password.toCharArray())
), optionsBuilder.build());
this.mongoDatabase = mongoClient.getDatabase("cookbook");
return mongoClient;
}
public boolean isAvailable() {
return mongoStatusListener.isAvailable();
}
来源:https://stackoverflow.com/questions/35090906/mongodb-java-driver-3-0-cant-catch-exception-when-authenticate