[JAVA-835] db.eval() all broken : com.mongodb.MongoException: not talking to master and retries used up Created: 28/May/13  Updated: 30/Jul/13  Resolved: 30/Jul/13

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: 2.11.1
Fix Version/s: None

Type: Bug Priority: Blocker - P1
Reporter: Alan Williamson Assignee: Jeffrey Yemin
Resolution: Done Votes: 0
Labels: driver
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Java Driver.

Server
{
"host" : "slavemdb211",
"version" : "2.4.3",
"process" : "mongod",
"pid" : 1369,
"uptime" : 612253,
"uptimeMillis" : NumberLong(612252406),
"uptimeEstimate" : 603124,
"localTime" : ISODate("2013-05-28T17:59:43.384Z"),
}



 Description   

When we talk to a given Mongo server, through the JavaAPI, with a eval(), it always fails.

Here is a quick and dirty Java program that demonstrates the issue. If we go onto the console of the server and run the same command [eval("db.serverStatus()")] it works as expected.

Bar.java

import com.mongodb.DB;
import com.mongodb.MongoClient;
 
public class doNotUse {
 
 public static void main(String[] args) throws Exception {
    MongoClient mc = new MongoClient( "192.168.26.240", 49140 );
    DB db = mc.getDB("log");
    Object o = db.eval( "db.serverStatus()", (Object[])null );
    System.out.println(o);
  }
 
}

Fails with:

Bar.java

Exception in thread "main" com.mongodb.MongoException: not talking to master and retries used up
	at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:314)
	at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:316)
	at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:316)
	at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:257)
	at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:310)
	at com.mongodb.DB.command(DB.java:274)
	at com.mongodb.DB.command(DB.java:256)
	at com.mongodb.DB.command(DB.java:313)
	at com.mongodb.DB.command(DB.java:211)
	at com.mongodb.DB.doEval(DB.java:353)
	at com.mongodb.DB.eval(DB.java:370)
	at org.doNotUse.main(doNotUse.java:21)

The server we are talking to is a slave to another master.



 Comments   
Comment by Jeffrey Yemin [ 30/Jul/13 ]

Alan,

Re-opened and then closed this as Worked as Designed, but I can re-open again if you disagree. And apologies for the mis-understanding about eval vs. db.eval.

Comment by Jeffrey Yemin [ 30/Jul/13 ]

You can run Javascript on a slave using mapReduce and the $where clause of a query, but not using eval. See http://docs.mongodb.org/manual/core/server-side-javascript/ for more info on server-side Javascript.

Comment by Alan Williamson [ 30/Jul/13 ]

aaah so db.eval() has been disabled on the server. So does that mean you can't run javascript against a slave database?

Comment by Jeffrey Yemin [ 29/Jul/13 ]

Alan,

I see the issue now. In the shell you're using the built-in JavaScript "eval" function. The equivalent to what you're attempting from Java in the shell is db.eval(...). If you try that, it fails as well:

repl0:SECONDARY> db.eval("db.serverStatus()")
Mon Jul 29 19:35:36.039 JavaScript execution failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" } at src/mongo/shell/db.js:L567

Comment by Alan Williamson [ 29/Jul/13 ]

@Jeff any comment on this? Can you reopen this please?

thanks

Comment by Alan Williamson [ 20/Jul/13 ]

Jeff sorry to report that this issue is NOT fixed.

I am using the 3.0 latest driver from Github. Running the exact same code from the first comment, here is the output:

NFO: Monitor thread successfully connected to server with description ServerDescription{address=ServerAddress{host='127.0.0.1', port=49140}, type=StandAlone, hosts=[], passives=[], arbiters=[], primary='null', maxDocumentSize=16777216, maxMessageSize=48000000, tags={}, setName='null', averagePingTimeNanos=2500369, ok=true, state=Connected, version=ServerVersion{versionList=[2, 4, 3]}}
Exception in thread "main" com.mongodb.CommandFailureException: Command failed with response { "note" : "from execCommand", "ok" : 0.0, "errmsg" : "not master" } on server ServerAddress{host='127.0.0.1', port=49140}
	at com.mongodb.MongoExceptions.mapException(MongoExceptions.java:47)
	at com.mongodb.DB.executeCommand(DB.java:464)
	at com.mongodb.DB.doEval(DB.java:343)
	at com.mongodb.DB.eval(DB.java:348)
	at org.doNotUse.main(doNotUse.java:20)

Comment by Alan Williamson [ 18/Jul/13 ]

Jeff you are a gentleman and a scholar ... the "uberJar" was the trick. That produced a JAR file around the 700KB mark that had all the necessary classes in it that stopped my app from complaining of missing classes. It is quite a step from the 2.x JAR file size.

Thank you for taking the time here to aid

Comment by Jeffrey Yemin [ 17/Jul/13 ]

We are also thinking about putting the "uber jars" in Maven as well. Other projects that are split like this into modules sometimes do this.

Comment by Alan Williamson [ 17/Jul/13 ]

Thank you Jeff - let me get onto this in a few hours, will let you know.

Comment by Jeffrey Yemin [ 17/Jul/13 ]

Hi Alan,

Sorry to hear you are having problems. Let me try to address them one by one:

The jar files on Sonatype are not incomplete. They are just split into three jar files. For example, if you are using Maven, the following pom.xml will work:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mongodb.test</groupId>
    <artifactId>3.0-tests</artifactId>
    <version>1</version>
 
 
    <dependencies>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
 
    <repositories>
        <repository>
            <id>sonatype-snapshot</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        </repository>
    </repositories>
</project>

Maven will pull in the other dependencies automatically, which are:

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
 
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>bson</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>

If you want to build from source, we no longer are using Ant. We've moved to gradle. To build, you would do something like:

git clone https://github.com/mongodb/mongo-java-driver.git
cd mongo-java-driver
git checkout 3.0.x
./gradlew build

If you just want a single jar with everything, try:

./gradlew uberJar

and it will build the jar ./driver-compat/build/libs/mongo-java-driver-3.0.0-SNAPSHOT-all.jar, which has everything from all three modules.

We will update the public docs on this soon, but I wanted to get you going as quick as possible.

Comment by Alan Williamson [ 17/Jul/13 ]

Jeff I having huge problems here.

1/ the JAR files from sonatype are incomplete - they are missing class files (ObjectId for example)

2/ i pulled the source code from GitHub and done the ant build manually; a 400KB JAR file created.

3/ When I use this file; i get exceptions thrown when I simple use MongoClient() to start a connection. Everything compiles though.

Comment by Jeffrey Yemin [ 16/Jul/13 ]

Hi Alan,

So you're able to build now?

Comment by Alan Williamson [ 16/Jul/13 ]

Where has the org.bson.types.ObjectId class gone in the 3.0 build? Is that no longer there?

The project was not built since its build path is incomplete. Cannot find the class file for org.bson.types.ObjectId. Fix the build path then try building this

Note – i see we need to have bson.jar now as well as mongo.jar

Comment by Jeffrey Yemin [ 12/Jul/13 ]

You can try this out using a snapshot: https://oss.sonatype.org/content/repositories/snapshots/org/mongodb/mongo-java-driver/3.0.0-SNAPSHOT/

Comment by auto [ 30/May/13 ]

Author:

{u'username': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

Message: Implementing read preference specification for command handling. Only "obedient" commands obey the read preference. All others are silently routed to the primary. There is some discussion that instead we should throw an exception, but that has not been finalized.

This also fixes JAVA-835, in which it was discovered that we change the read preference even with a Direct connection to a secondary, which goes against the intent.
Branch: 3.0.x
https://github.com/mongodb/mongo-java-driver/commit/a72078ebe408feaef3095c0f0c7db90de194fc2f

Comment by Jeffrey Yemin [ 28/May/13 ]

3.0 is the Java version, as this is a driver bug.

I wouldn't call it an alpha yet. We should have a snapshot up on Sonatype by end of the week. I'll let you know.

Comment by Alan Williamson [ 28/May/13 ]

Thank you Jeff. Really appreciate the fast turnaround.

I can work around most of the cases.

You talk 3.0, is that the server version or the JavaAPI version? If Java version, is it in alpha I can play with now?

Comment by Jeffrey Yemin [ 28/May/13 ]

I see your point. This is a bug. Do you have any workaround for the time being (like using a different driver), or is this a blocker for you?

Comment by Alan Williamson [ 28/May/13 ]

I was only using that as an illustration of when it fails. I do not agree that this issue is closed.

Then why can I remotely connect to the slave and run the eval() from there? Surely that should fail too. It doesn't.

% mongo 192.168.26.140 49140
> eval("db.serverStatus()");

Comment by Jeffrey Yemin [ 28/May/13 ]

It's happening because eval will only run on a primary. Try this instead.

 public static void main(String[] args) throws Exception {
    MongoClient mc = new MongoClient( "192.168.26.240", 49140 );
    DB db = mc.getDB("log");
    Object o = db.command("serverStatus");
    System.out.println(o);
  }

Generated at Thu Feb 08 08:53:11 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.