Java vs php ---- Unknown flags value -- cannot decode value

Hello,

Versions: 3.0.0
Java: https://dl.dropboxusercontent.com/u/10007675/Couchbase-Java-Client-2.0.1-SNAPSHOT-b0921ce.zip
PHP libcouchbase: git clone git://github.com/couchbase/libcouchbase.git
PHP couchbase: git php-couchbase
Bucket type: couchbase

Java insert:

CouchbaseCluster cluster = CouchbaseCluster.create(IP);
Bucket bucket = cluster.openBucket();
JsonObject json = JsonObject.create();
json.put("testkey","testvalue");
JsonDocument doc = JsonDocument.create( "test2" , json);
bucket.upsert(doc);
JsonDocument res2 = bucket.get("test2");
System.out.println(res2);
JsonDocument{id='test2', cas=2777834602030747, expiry=0, content={"testkey":"testvalue"}}

Reading from another jvm works as well.


The web interface can get the document as well with this flag:

{
   "id": "test2",
   "rev": "1-0009de6d04b2e69b0000000002000000",
   "expiration": 0,
   "flags": 33554432
}

This code:

$cb = new CouchbaseCluster(IP);
$db = $cb->openBucket('default');

try {
    $res = $db->get('test2');
} catch (Exception $e) {
    echo "ERROR: $e\n";
}

Drops

exception 'CouchbaseException' with message 'Unknown flags value -- cannot decode value' in CouchbaseNative:374
Stack trace:

0 CouchbaseNative(443): couchbase_basic_decoder_v1('{"testkey":"tes...', 33554432, 0, Array)
1 [internal function]: couchbase_default_decoder('{"testkey":"tes...', 33554432, 0)
2 CouchbaseNative(1121): _CouchbaseBucket->get('test2', Array)
3 /path/index.php(8): CouchbaseBucket->get('test2')
4 {main}

If i put an “enter” to the data on the web interface, and save it,

{
   "id": "test2",
   "rev": "2-0009df27d6b123f80000000000000000",
   "expiration": 0,
   "flags": 0
}

Then the php code works as well.

===========================================================================

PHP insert:

$db->upsert('test3', json_encode(array('name'=>'hehe')));

The backends shows:

{
  "name": "hehe"
}

The meta infos ( flags 0x4) :

{
   "id": "test3",
   "rev": "3-0009df8196ebfd930000000000000004",
   "expiration": 0,
   "flags": 4
}

JAVA reading:

com.couchbase.client.java.error.TranscodingException: Flags (0x4) indicate non-JSON document for id test3, could not decode.
        at com.couchbase.client.java.transcoder.JsonTranscoder.doDecode(JsonTranscoder.java:60)
        at com.couchbase.client.java.transcoder.JsonTranscoder.doDecode(JsonTranscoder.java:40)

After i save it on the backend,

{
   "id": "test3",
   "rev": "4-0009dfb7ef321c630000000000000000",
   "expiration": 0,
   "flags": 0
}

the JAVA can read it:

JsonDocument{id='test3', cas=2779255875443811, expiry=0, content={"name":"hehe2"}}

Upserting:

$db->upsert('test5', json_encode(array('name'=>'hehe')));
$db->upsert('test6', array('name'=>'hehe'));

Reading with PHP

$res5 = $db->get('test5');
$res6 = $db->get('test6');
Notice: unserialize(): Error at offset 0 of 15 bytes in CouchbaseNative on line 397
CouchbaseMetaDoc Object
(
    [error] =>
    [value] =>
    [flags] => 4
    [cas] => Resource id #4
)
CouchbaseMetaDoc Object
(
    [error] =>
    [value] => stdClass Object
        (
            [name] => hehe
        )

    [flags] => 6
    [cas] => Resource id #5
)

Reading with Java

com.couchbase.client.java.error.TranscodingException: Flags (0x4) indicate non-JSON document for id test5, could not decode.

com.couchbase.client.java.error.TranscodingException: Flags (0x6) indicate non-JSON document for id test6, could not decode.

Thank you very much!
Huhh

At least in this case you have to pass just PHP object instead of encoding it manually:

$db->upsert('test3', array('name'=>'hehe'));

Yes, I think @avsej is right. When you save it through PHP and it has the flag 4 it indicates a non JSON string, you could try reading it with the StringDocument from Java but that’s not what you want.
If you save it from the UI it applies the proper flags to be readable as such.

Try storing the doc without the json_encode as @avsej described. Let us know how it goes

Hello Avsej, Daschl!

Firstly, thank you the answers!


I had investigation to think out how it is working, and i did make these test codes:

JAVA: http://pastebin.com/cJuqThFJ
PHP : http://pastebin.com/Uip2mE0b


Seems:

  • the PHP testphpjson, testphpstring writes, and JAVA LegacyDocument reads works.
  • the JAVA LegacyDocument javalegacy writes, and PHP reads works.

BUT
The PHP can read JUST the testphparray,
and not the testphpjson,
and not the testphpstring.


Finally i had not found a way where i can read+write with PHP+JAVA.


Have you got any idea, how can i do it?

Thank you very much!
Huhh

Hey!

Keep in mind that both your testphpjson and testphpstring are both encoding strings as you are performing json_encode before passing the data to the Couchbase library, whereas your testphparray is properly passing the array directly to the SDK for encoding and generation of the flags.

That being said, the 2.0.0 version of the PHP SDK exhibits a bug that causes string encoding to fail to be decoded appropriately. This will be fixed in the version 2.0.1 which is scheduled to be released tomorrow.

Cheers, Brett

Hello Brett,

So, if i understand as well,
the PHP SDK does not convert the string to json,
but the UI does it, and the Server tries(?) it.

For example, from the UI:

ID	 	Сontent	 	 	 	 	 	 	 
testphpstring	"c3RyaW5n"
testphpjson	{ "type": "json" }

And i could make a view to select as JSON:

if ( doc.type=='json') emit(meta.id, doc);

It will shows the testphpjson

Thank you very much!
Huhh

Hey,
The difference is in how the various SDKs and the server detect JSON. All of the most recently client SDKs use a common meta-data field to encode the underlying format of the byte data representing your document. This means that we rely on this data to know the type to decode to. In the case of the PHP SDK, we decode string values to strings, and json values as PHP objects or arrays. This is opposed to the management UI and view query api, where a heuristic is used to determine if a value is JSON or not.

Cheers, Brett

Thanks Brett the clarification!
Cheers, Huhh

I have also had this problem when a .net client writes a json document, and the java client refuses to decode it because they are not using the same flags.

@cpeterson can you shoot over a simple example we can reproduce - and tell us which versions you are using? That should give us a sense pretty quickly if its a bug or used the wrong way
Thanks!