JW.ZG JW.ZG - 2 months ago 5
Java Question

Unable to connect with MongoDB using Java Driver on Heroku

I am building a web application with Java and MongoDB on Heroku. I learnt this project from here. I have been kept trying for two days.

I use

3.2.2 mongo-java-driver
and
3.5.1 maven-compiler-plugin


This is in my
Main
class:

public static void main(String[] args) throws MongoException, UnknownHostException, Exception {
MongoClientURI uri = new MongoClientURI(System.getenv("MONGOHQ_URL"));
MongoClient mongoClient = new MongoClient(uri);

String dbname = uri.getDatabase();

//mongoClient.setWriteConcern(WriteConcern.JOURNALED);
DB db = mongoClient.getDB(dbname);

staticFileLocation("/public");
new TodoResource(new TodoService(db));

MongoCredential credential = MongoCredential.createCredential(uri.getUsername(),dbname,uri.getPassword());
MongoClientOptions mongoClientOptions = MongoClientOptions.builder().build();
}


And I got this error:

1:38:42 AM web.1 | Exception in thread "main"
1:38:42 AM web.1 | java.lang.NullPointerException
1:38:42 AM web.1 | at com.mongodb.MongoClientURI.<init> (MongoClientURI.java:174…
1:38:42 AM web.1 | at com.mongodb.MongoClientURI.<init> (MongoClientURI.java:159…
1:38:42 AM web.1 | at Main.main(Main.java:32)


It's NullPointerException, so I tried to replace
MONGOHQ_URL
by
mongodb://user:passwd@host1:port1,host2:port2/dbname
, and I also tried to use mLab MongoDB on Heroku, but the same error:

11:17:05 AM web.1 | SLF4J: Class path contains multiple SLF4J bindings.
11:17:05 AM web.1 | SLF4J: Found binding in [jar:file:/Users/zhugejunwei/full-sta…
11:17:05 AM web.1 | SLF4J: Found binding in [jar:file:/Users/zhugejunwei/full-sta…
11:17:05 AM web.1 | SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings …
11:17:05 AM web.1 | SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerF…
11:17:05 AM web.1 | Exception in thread "main" java.lang.NullPointerException
11:17:05 AM web.1 | at com.mongodb.ConnectionString.<init>(ConnectionString.java…
11:17:05 AM web.1 | at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:176…
11:17:05 AM web.1 | at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:158…
11:17:05 AM web.1 | at Main.main(Main.java:28)


From the original version to my current version, I really tried a lot, and I just want to make it runnable on Heroku to learn this project in another way.

When I learnt another tutorial, the code below is ok, but I don't know why it doesn't work in this project.

MongoURI mongoURI = new MongoURI(System.getenv("MONGOHQ_URL"));
//get connected
DB db = mongoURI.connectDB();
mongoURI.getPassword());
MongoCredential credential = MongoCredential.createCredential(mongoURI.getUsername(), mongoURI.getDatabase(), mongoURI.getPassword());
MongoClient mongoClient = new MongoClient(new ServerAddress(), Arrays.asList(credential));


I also opened an issue on github and on jira

Please help me with this issue. Thanks in advance.

Answer

I tried for more than 40 hours, and finally get it worked.

I changed a lot. Here are something I think is important:

First, it seems I cannot use DB db = mongoURI.connectDB();, maybe because of the 3.2.2 java-driver version or because of the MongoDB version on Heroku. When I use "MongoDatabase" instead of "DB", some errors disappeared, but still cannot run the project. Because I have to changed a lot in my project wherever used "DB", and this is very difficult to change from DB to MongoDatabase.

I realized that I can use DB in 2.7.2, so I changed all the syntaxes related to the mongo-java-driver version. But again, errors disappeared, I cannot run the project. However, at this time, it seems most errors disappeared. One more error showed that another process is running on the same port. I killed that process. Now all errors gone. When I run it, I cannot open it on Heroku, but on port 4567. This is weird, because the default port for Heroku is 5000, and 4567 is the default port for Jetty, which is a embedded server for Java application. I added this piece of code, and it finally worked.

port(Integer.valueOf(System.getenv("PORT")));

Thanks to my professor and thanks to all the people that helped me.