google / flatbuffers

FlatBuffers: Memory Efficient Serialization Library
https://flatbuffers.dev/
Apache License 2.0
23.28k stars 3.25k forks source link

Java:FlatBuffers: object serialization must not be nested #4029

Closed LeesinYasuo closed 8 years ago

LeesinYasuo commented 8 years ago

schema : image

error: java.lang.AssertionError: FlatBuffers: object serialization must not be nested.

at com.google.flatbuffers.FlatBufferBuilder.notNested(FlatBufferBuilder.java:433)

at com.google.flatbuffers.FlatBufferBuilder.startVector(FlatBufferBuilder.java:347)

at com.tcl.statisticsdk.flatbuffers.Session.createPageInfosVector(Session.java:42)

I refer to the issue #301, depth-first (post order),but it doesn't work,could u give some advice?codes are as follows: image

ghost commented 8 years ago

If you get that assert, it means that above the code you show, there is a call to startSession / startPageInfo / startVector or similar that hasn't yet been finished with the proper "end" call.

LeesinYasuo commented 8 years ago

can u give me a example for calling to startSession / startPageInfo / startVector or similar that hasn't yet been finished with the proper "end" call. i can't understand.depth first,Session.createSession method include startSession and the proper "end" call,why there is a call to startSession / startPageInfo / startVector or similar that hasn't yet been finished with the proper "end" call.

ghost commented 8 years ago

Can you show your full FlatBuffer construction code (in text, not image)? Then I'll point it out to you.

LeesinYasuo commented 8 years ago

Here is the code,when the data is become big,it will throw that exceptions,normally ,it is ok.I got this exception by monkey test.

for (PageItem pageItem : mPageItems){ LogUtils.D("pageName:"+pageItem.getPageName()); if (pageItem.getEndTime() == -8099484176161439744L){ if (mIsExit){ pageItem.setEndTIme(mExitTime); LogUtils.I(pageItem.getPageName()+":app aborts,ready to save data"); } else { LogUtils.E(pageItem.getPageName()+":didn't call onPageEnd"); } } int pageNameOffset = mBuilder.createString(pageItem.getPageName()); int pageInfoOffset = PageInfo.createPageInfo(mBuilder, pageNameOffset, pageItem.getStartTime(), pageItem.getEndTime()); mCustomPageInfoList.add(pageInfoOffset); } mPageItems.clear(); if (mIsNewSession) { mSessionIDoffset = mBuilder.createString(UUID.randomUUID().toString()); mPageInfoList.clear();
mPageInfoList.addAll(mCustomPageInfoList); mCustomPageInfoList.clear(); int pageInfosOffset = Session.createPageInfosVector(mBuilder, list2intArray(mPageInfoList)); int sessionOffset = Session.createSession(mBuilder,mSessionIDoffset,mStartTime, mExitTime, pageInfosOffset);

ghost commented 8 years ago

There doesn't appear to be a nesting problem in that code, so the problem must be elsewhere. Check between where you create mBuilder and this code if you started any table or vector without ending it.

Or are you maybe reusing a FlatBufferBuilder from a previous buffer?

LeesinYasuo commented 8 years ago

reusing a FlatBufferBuildr from a previous buffer? i can't understand,can u give me a example? where i create mBuilder are as follows: private static FlatBufferBuilder mBuilder = new FlatBufferBuilder(0); another piece of code if (mBuilder.dataBuffer().capacity()>=DATA_MAX){ mIsDataMax = true; mBuilder = new FlatBufferBuilder(0);
}

seantcanavan commented 8 years ago

I'm seeing this issue as well but I'm initializing a new FlatBufferBuilder each iteration and calling start, end, and finish:

    // Now broadcast exactly 10 updates with pause
    for (int i = 0; i < 100000; i++) {
        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
        Car nextCar = Car.getRandomCar();
        CarBuffer.startCar(fbb);
        CarBuffer.addBrand(fbb, fbb.createString(nextCar.getBrand()));
        CarBuffer.addModel(fbb, fbb.createString(nextCar.getModel()));
        CarBuffer.addSold(fbb, nextCar.isSold());
        CarBuffer.addWeight(fbb, nextCar.getWeight());
        int carOffset = CarBuffer.endCar(fbb);
        CarBuffer.finishCarBuffer(fbb, carOffset);
        fbb.endObject();
        publisherSocket.send(fbb.sizedByteArray(), 0);
        Thread.sleep(1000);
    }

EDIT: Fixed my code. Not sure why it's fixed but it is:

    // Now broadcast exactly 10 updates with pause
    for (int i = 0; i < 100000; i++) {
        FlatBufferBuilder fbb = new FlatBufferBuilder(16);
        Car nextCar = Car.getRandomCar();
        int brand = fbb.createString(nextCar.getBrand());
        int model = fbb.createString(nextCar.getModel());
        CarBuffer.startCar(fbb);
        CarBuffer.addBrand(fbb, brand);
        CarBuffer.addModel(fbb, model);
        CarBuffer.addSold(fbb, nextCar.isSold());
        CarBuffer.addWeight(fbb, nextCar.getWeight());
        int carOffset = CarBuffer.endCar(fbb);
        fbb.finish(carOffset);
        byte[] result = fbb.sizedByteArray();
        publisherSocket.send(result, 0);
        Thread.sleep(1000);
    }
ghost commented 8 years ago

@seantcanavan : yes, you need to create strings and other objects outside of the table that references it, the error you got enforces that. See http://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html

LeesinYasuo commented 8 years ago

Thanks your help,the issue can be closed