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:
ItemRec.ice:
I see differences in the generated constructor for ItemRec between the Java and python code.
From ItemRec_ice.py for python:
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:
This ends up leaving the 'key' as null, if it is not explicitly initialized.
The __write method for ItemRec is implemented as:
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:
Thanks,
Shankar
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
0
Comments
-
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.0