OpenDDS / OpenDDS

OpenDDS is an open source C++ implementation of the Object Management Group (OMG) Data Distribution Service (DDS). OpenDDS also supports Java bindings through JNI.
http://www.opendds.org
Other
1.29k stars 465 forks source link

CPP to Java / Java to CPP #3347

Closed SafdarSikander closed 2 years ago

SafdarSikander commented 2 years ago

I have configured two DDS Versions (3.19), one in CPP and other one in Java. I wanted to test the cross language support. it does support if the struct has primitive types (long, string, boolean) it works fine but when I use sequence it doesn't invoke on_data_available method.

mitza-oci commented 2 years ago

Are you using the same IDL for both applications? Please share your code and we can take a look. Sequences are the same on the wire (CDR encoding) no matter which language writes them.

SafdarSikander commented 2 years ago

@mitza-oci Yes I am using the same IDL on both sides.

module Service {

    enum OS {
        UNKNOWN,
        ANDROID,
        IOS
    };

    struct Paramters {
        string param;
    };

    typedef sequence<Paramters> seqParamters;
    struct Device {
        string id;
        string ip;
        OS mOS;
        seqParamters params;
        boolean allow;
    };

    typedef sequence<Device> SeqDeviceList;
    @topic 
    struct DeviceList {
        @key string  id;
        SeqDeviceList mDeviceList;
    };

};

Here is the IDL that I am using.

SafdarSikander commented 2 years ago
@Override
    public void on_data_available(DataReader dataReader) {
        DeviceListDataReader mdr = DeviceListDataReaderHelper.narrow(dataReader);
        if (mdr == null) {
            System.err.println("ERROR: read: narrow failed.");
            return;
        }
        DeviceList list=  new DeviceList();
        list.deviceList = new DeviceList.SeqDeviceList [0];
        DeviceListHolder mh = new DeviceListHolder(list);
        SampleInfoHolder sih = new SampleInfoHolder(new SampleInfo(0, 0, 0, new DDS.Time_t(), 0, 0, 0, 0, 0, 0, 0, false, 0));
        int status = mdr.take_next_sample(mh, sih);
        if (status == RETCODE_OK.value) {
            System.out.println("id -> " + list.id);
        } else if (status == RETCODE_NO_DATA.value) {
            System.err.println("ERROR: reader received DDS::RETCODE_NO_DATA!");
        } else {
            System.err.println("ERROR: read Message: Error: " + status);
        }
    }

This is my subscriber, when I publish from the CPP side on data available not get called, but when I publish from java on data available gets called.

mitza-oci commented 2 years ago

This IDL doesn't compile:

Error - tao_idl: "Service.idl", line 17: identifier spellings differ only in case: "OS" and "os"
Error - tao_idl: "Service.idl", line 27: identifier spellings differ only in case: "deviceList" and "DeviceList"
SafdarSikander commented 2 years ago

@mitza-oci Sorry for inconvenience. I update some variables name for sharing the IDL. I have updated the IDL. You can compile it without error now.

mitza-oci commented 2 years ago

@mitza-oci Sorry for inconvenience. I update some variables name for sharing the IDL. I have updated the IDL. You can compile it without error now.

Thanks, I was able to generate C++ and Java code from the IDL. I'll try the Java application.

SafdarSikander commented 2 years ago

@mitza-oci I figure it out today that if we do not intialize sequence with 0 JVM crashes.

list.deviceList = new DeviceList.SeqDeviceList [0];
mitza-oci commented 2 years ago

Yes, see the java/FAQ file in the repository "I'm seeing a null pointer exception or a JVM crash in an OpenDDS native method. What should I check first?"

SafdarSikander commented 2 years ago

I see missed that, but it doesn't make sense to initialize an array with 0 elements?

mitza-oci commented 2 years ago

OpenDDS is trying to be as efficient as possible, which includes not doing redundant work. Arrays are not resizable, so it's up to the user to determine the array size. This follows the OMG specification for IDL-to-Java.

SafdarSikander commented 2 years ago

Make sense, but when I initialize other than 0 it crashes the JVM.

mitza-oci commented 2 years ago

When you initialize it to contain a positive number of pointers, are those pointers null?

SafdarSikander commented 2 years ago

I debug it, it shows that the array is initialized successfully, it gets the valid pointer address.

mitza-oci commented 2 years ago

This worked when I tried it. I believe the on_data_available is close to what you had, but the one I used was adapted from another project.

https://github.com/mitza-oci/OpenDDS/tree/issue-3347/examples/Issue3347