I'm trying to use MongoDB in a Java Web Service.
As suggested in Mongo tutorial I should have a MongoClient, let it be dbInstance, connection pool and call dbinstance to get a connection to the database, which is in localhost.
So this is what I have:
private static MongoClient dbInstance = null;
public static DB getDBInstance() {
if (dbInstance == null) {
try {
dbInstance = new MongoClient();
registerShutdownHook();
}
catch (Exception exc) {
System.out.println("Exception");
}
}
return dbInstance.getDB("SAED");
}
What I don't understand is how I can understand if I'm connected to the DB, because, also il mongo isn't working (by starting mongod service) it doesn't throw exceptions.
And another question, I have multiple thread calling Class.getDBInstance, should I synchronize it, and if yes, how can I do that?
You will be thrown an exception when the mongo is not running while you try to connect.
When you do the MongoClient(), it will always look for in the localhost for port 27017 to connect. You can also parameterize this to connect to a different machine and/or port.
You can read more in depth details about this at Mongo Documentation.
MongoClient mongoClient = new MongoClient();
// or
MongoClient mongoClient = new MongoClient( "localhost" );
// or
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
Regarding your synchronization question,
Yes, you can synchronize at a block level to make it better instead of at the method level.
Related
sorry for my broken english, not a native speaker :)
Here is my problem:
I try to connect via JDBC to a DB hosted on a MySQL server (Version: 5.6.37). I don't host the server and can't change any server configs.
When I try to connect using SQuirreL everything works as expected. I get access to the DB.
When I try to connect via self-written app via my IDE (eclipse) I get an Caused by: java.sql.SQLException: Access denied for user ... (using password: YES)
I'm using HikariCP to manage the connections. Tried also non connection pool aproach via DriverManager.getConnection. Both times the same.
The driver I'm using is mysql-connector-java-5.1.44-bin.jar
// DriverManager approach
private static final Properties dbProps = new Properties();
static {
dbProps.put("password", dbPass);
dbProps.put("user", dbUser);
dbProps.put("autoReconnect", "true");
dbProps.put("failOverReadOnly", "false");
dbProps.put("maxReconnects", "1");
}
...
public static Connection getConnection() {
Connection con = null;
try {
con = DriverManager.getConnection(connectionString, dbProps);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
...
// HakiriCP approach
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;
private static final Properties dbProps = new Properties();
static {
PropertyLoader.loadPropertiesFromFile(dbProps); // read properties from external source
config.setJdbcUrl(String.format("jdbc:mysql://%s:%s/%s", dbProps.getProperty("db.server"),
dbProps.getProperty("db.port"), dbProps.getProperty("db.database")));
config.setUsername(dbProps.getProperty("db.user"));
config.setPassword(dbProps.getProperty("db.pass"));
config.addDataSourceProperty("cachePrepStmts", dbProps.getProperty("db.cachePrepStmts", "true"));
config.addDataSourceProperty("prepStmtCacheSize", dbProps.getProperty("db.prepStmtCacheSize", "250"));
config.addDataSourceProperty("prepStmtCacheSqlLimit", dbProps.getProperty("db.prepStmtCacheSqlLimit", "2048"));
ds = new HikariDataSource(config);
}
...
public static Connection getConnection() {
Connection con = null;
try {
con = ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
...
EDIT - when I wireshark the connection tries, I see different encoded passwords (SQuirreL vs App). But when I print the password to the console it is exactly the one that work with SQuirreL.
EDIT - The connecttion handling is done in one single class. When I test it all alone without any of the other logic (it is a old swing app) everything works fine. But when I make the exact same call from the swing application it fails '(sends different password string).
What am I doing wrong?
I'm thankful for every help.
Cheers!
I found the solution. For all the project I have UTF-8 encoding. But eclipse decided to use UTF-16 when running or debugging code.
Option can be found here: Run Configurations -> Common -> Encoding
Ok, eclipse made some joke with me.
Thanks to wireshark givin me the hint that something is wrong with the encoding.
Thanks to you guys to trying to help (inluding the ones giving me -1, they don't know it better ;))
Cheers!
Things I Have tried:
InetAddress address = InetAddress.getByName("MyPCName");
MongoClientOptions.Builder builder = MongoClientOptions.builder().connectTimeout(3000);
MongoClient mongo = new MongoClient(new ServerAddress(address.getHostAddress(), 3001), builder.build());
try {
mongo.getAddress();
} catch (Exception e) {
System.out.println("Mongo is down");
mongo.close();
}
Second try:
InetAddress address = InetAddress.getByName("MyPCName");
MongoClientURI uri = new MongoClientURI( "mongodb://"+address.getHostAddress()+":27017/"+TEST_SKETCH_APP );
MongoClient instance = MongoDatabaseConnection.getInstance(uri);
try {
instance .getAddress();
} catch (Exception e) {
System.out.println("Mongo is down");
instance .close();
}
FireWall configured properly :
netsh advfirewall firewall add rule name="Allowing mongod" dir=in action=allow program=" C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe"
But Still when I try to connect to do an insert operation I get this error message :
Timed out after 3000 ms while waiting to connect. Client view of cluster state is {type=Unknown, servers=[{address=192.168.138.1:3001, type=Unknown, state=Connecting}]
I am doing the save operation in an AsyncTask. My mongo db server is running in the "MyPCName" computer. My Mongodb config has bind ip commented too. And I have also tried the bind Ip to keep this bind_ip = 127.0.0.1,***.***.***.*,0.0.0.0
The '*' mark is the ip address which I get when I do a address.getHostAddress().
I am now stuck here.
Try this code:
MongoClientURI mongoUri = new MongoClientURI("mongodb://Dbuser:dbpass#ds047692.mongolab.com:47692");
MongoClient mongoClient = new MongoClient(mongoUri);
DB db = mongoClient.getDB("testdb");
Set<String> collectionNames = db.getCollectionNames();
In addition, you should check this answer: https://stackoverflow.com/a/21555200/4810206.
I have a cron-job running at a Linux machine running after every 5 minutes. The job executes a Java class.
private MongoClient createConnection(int retry,List<ServerAddress> host){
try {
System.out.println("Retrying----------"+retry);
MongoClient client = new MongoClient(host, MongoClientOptions.builder()
.connectionsPerHost(10)
.threadsAllowedToBlockForConnectionMultiplier(5)
.connectTimeout(5000).writeConcern(WriteConcern.NORMAL).build());
client.getDB("admin").command("ping").throwOnError();
retry = 0;
return client;
} catch (Exception e) {
retry++;
if (retry < retryLimit) {
createConnection(retry,host);
} else {
System.out.println("Connection could not be established to host-"+host);
}
return null;
}
}
retry is the integer value denoting how many times client creation can be tried in case host is unreachable.
The host list that i am passing is -
public static List<ServerAddress> HOST_SCRIPT = new ArrayList<ServerAddress>() {
private static final long serialVersionUID = 1L;
{
try {
add(new ServerAddress("PrimaryHost23", 27017));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
};
Code is Stuck when i MongoClient is being created. It does not happen always. Code works fine and NEVER hangs when i run on my local machine. There is no exception thrown.
I recently upgraded Linux machine OS (from CentOS 5 to CentOS 6). Can this be responsible for this because this script was working fine earlier.
Please help.
Regards,
Vibhav
The thing what you can do is you can throw mongo exception try out that of mongo client is stuck you will get to know try out this https://api.mongodb.org/java/2.6/com/mongodb/MongoException.html
Yes of course, actually i was creating crawler in java which fetch all the links of any particular website and validate the css and html structure Using the Jsoup and jcabi api but when i used to store links to the database it was not throwing any exception and even not storing the data also. so i did this
catch (MongoException e){
System.err.print(e.getClass().getName()+": "+e.getMessage());
}
Have you checked the compatibility like of jar that you have uploaded for your project like before it was like Mongo mongo = new Mongo(host,port); but That is deprecated. Try to check that and even your MongoDb jar.
My simple program to connect to mongodb 2.6.3 using 3.0.0 driver fails with
"Command failed with error 59: 'no such cmd: saslStart' on server ...."
Any insight is much appreciated.
public static void main(String[] args) {
MongoCredential credential = MongoCredential.createCredential(MY_TEST_DATABASE_USER, MY_TEST_DATABASE, MY_TEST_DATABASE_PWD);
// MongoCredential credential = MongoCredential.createScramSha1Credential(MY_TEST_DATABASE_USER, MY_TEST_DATABASE, MY_TEST_DATABASE_PWD); // this failed as well
try (MongoClient mongoClient = new MongoClient(new ServerAddress(DB_SERVER_2_6_3, DB_PORT), Arrays.asList(credential))) {
MongoDatabase mdb = mongoClient.getDatabase(MY_TEST_DATABASE);
MongoCollection<Document> coll = mdb.getCollection(MY_TEST_COLLECTION);
if (coll != null) {
System.out.println(coll.find().first());
}
}
}
Figured out by trial and error. (disappointed with mongo online support/docs on this issue)
Used "admin" database when creating credentials. Figured this out by looking at the connection settings in my Robomongo client.
MongoCredential credential = MongoCredential.createCredential(MY_TEST_DATABASE_USER, "admin", MY_TEST_DATABASE_PWD);
I'm looking for best way to check connection to Mongo DB.
Situation: client makes request (api) to server. And server returns status of all databases.
What the best way to do it?
I use this:
Builder o = MongoClientOptions.builder().connectTimeout(3000);
MongoClient mongo = new MongoClient(new ServerAddress("192.168.0.1", 3001), o.build());
try {
mongo.getAddress();
} catch (Exception e) {
System.out.println("Mongo is down");
mongo.close();
return;
}
In Java MongoDriver 3.3.0 use ServerMonitorListener to determine whether server is up and connected or not.
Here is the example code,
public class ServerConnection implements ServerMonitorListener {
private MongoClient client;
public ServerConnection(){
try {
MongoClientOptions clientOptions = new MongoClientOptions.Builder()
.addServerMonitorListener(this)
.build();
client = new MongoClient(new ServerAddress("localhost", 27017), clientOptions);
} catch (Exception ex) {
}
}
#Override
public void serverHearbeatStarted(ServerHeartbeatStartedEvent serverHeartbeatStartedEvent) {
// Ping Started
}
#Override
public void serverHeartbeatSucceeded(ServerHeartbeatSucceededEvent serverHeartbeatSucceededEvent) {
// Ping Succeed, Connected to server
}
#Override
public void serverHeartbeatFailed(ServerHeartbeatFailedEvent serverHeartbeatFailedEvent) {
// Ping failed, server down or connection lost
}
}
The ping command is a no-op used to test whether a server is responding to commands. This command will return immediately even if the server is write-locked:
try{
DBObject ping = new BasicDBObject("ping", "1");
mongoTemplate.getDb().getMongo().getDB("DATABASE NAME"").command(ping);
} catch (Exception exp){
// MongoDb is down..
}
Use MongoClient for Java, all the info you need is here...
http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/
If I understand your question correctly you want to get state returned via a web service call. You can write a function that invokes db.serverStatus() and have it return the data. Check out the documentation here:
Monitoring for MongoDB