Archived

This forum has been archived. Please start a new discussion on GitHub.

Ice struct generated constructor discrepancy between Python and Java generated code.

Hi,

I am using Ice 3.5.0 on Linux, Windows and Mac OSX. C++ on the server with Python, Java and C++ clients.

For a simple slice file example as below:

ItemKey.ice:
#ifndef _EXAMPLE_ITEMKEY_ICE_
#define _EXAMPLE_ITEMKEY_ICE_

module example {

struct ItemKey {

    string name; 
};

};

#endif

ItemRec.ice:
#ifndef _EXAMPLE_ITEMREC_ICE_
#define _EXAMPLE_ITEMREC_ICE_

#include <ItemKey.ice>

module example {

struct ItemRec {

    int  priority = 7;
    bool active;

    ItemKey key;

    string  description = "foo";
};

};
#endif

I see differences in the generated constructor for ItemRec between the Java and python code.

From ItemRec_ice.py for python:
     class ItemRec(object):
        def __init__(self, priority=7, active=False, key=Ice._struct_marker, description="foo"):
            self.priority = priority
            self.active = active
            if key is Ice._struct_marker:
                self.key = _M_example.ItemKey()
            else:
                self.key = key
            self.description = description

Here, even if the 'key' field is not populated, the python code automatically constructs a default ItemKey and uses it.

From ItemRec.java for java, the default constructor only initializes fields that have a default value in the ice file:
    public ItemRec()
    {
        priority = 7;
        description = "foo";
    }

This ends up leaving the 'key' as null, if it is not explicitly initialized.

The __write method for ItemRec is implemented as:
    public void
    __write(IceInternal.BasicStream __os)
    {
        __os.writeInt(priority);
        __os.writeBool(active);
        key.__write(__os);
        __os.writeString(description);
    }

When __write(..) gets invoked, a NullPointerException gets thrown if the key is null. This problem does not happen when using python on the client side as a default ItemKey is constructed for 'key'.

Why is there this difference? Is there any slice option (or fix) to make the generated Java default constructor initialize all the fields of a struct/class similar to the generated python code?

What I am expecting would be something like:
    public ItemRec()
    {
        priority = 7;
        active = false;
        key = new ItemKey();
        description = "foo";
    }

Thanks,
Shankar

Comments

  • benoit
    benoit Rennes, France
    Hi Shankar,

    Yes, Java/C# mappings are different from Python/Ruby mappings here.

    In Python and Ruby, generated structs have a single constructor which provides default values for struct/enum/string members.

    In Java and C#, generated structs have 2 constructors. The default constructor (no parameters) initializes members to their default value (which is "null" for reference types). The "one-shot" constructor allows you to pass the values to assign to the members.

    So, you need to assign the struct data members in Java even when using the default constructor.

    Note that for Slice class members, Python and Java behave the same way: the class member is set to "None" in Python and to "null" in Java by default.

    Cheers,
    Benoit.