DataSerializable with enum

739 views
Skip to first unread message

John Childress

unread,
Sep 16, 2013, 4:50:28 PM9/16/13
to haze...@googlegroups.com
I recently switch from 2.6.3 to 3.0.2 and ran into an issue with querying with a enum.

The issue seems to be when the ClassLoaderUtil attempts to call the constructor for the enum

Caused by: java.lang.NoSuchMethodException: com.bobs.fun.common.entity.ISO.<init>()
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getDeclaredConstructor(Class.java:2043)
at com.hazelcast.nio.ClassLoaderUtil.newInstance(ClassLoaderUtil.java:54)
at com.hazelcast.nio.ClassLoaderUtil.newInstance(ClassLoaderUtil.java:50)
at com.hazelcast.nio.serialization.DataSerializer.read(DataSerializer.java:104)
... 41 more


Here is how I'm running the predicate...

            AuctionTypePredicate auctionTypePredicate;
            EntryObject entryObject;
            Predicate predicate;
            IMap map;

            entryObject = new PredicateBuilder().getEntryObject();

            map = this.client.getMap(AvaxDirectory.getAuctionMapName(iso));
            auctionTypePredicate = new AuctionTypePredicate(auctionType);
            predicate = Predicates.and(auctionTypePredicate, entryObject.get("iSO").equal(iso).and(entryObject.get("open").between(start, end)));

            return new ArrayList(map.values(predicate));

Serialization seems to work fine on 3 other than this part... any thoughts?  

John





Emin Demirci

unread,
Sep 17, 2013, 5:22:48 AM9/17/13
to haze...@googlegroups.com
Could you provide me a test code to reproduce this problem ? 

Currently I can query map by object's enum fields with predicate.

-- 
Emin Demirci
Hazelcast | Open source in-memory data grid
--
You received this message because you are subscribed to the Google Groups "Hazelcast" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hazelcast+...@googlegroups.com.
To post to this group, send email to haze...@googlegroups.com.
Visit this group at http://groups.google.com/group/hazelcast.
For more options, visit https://groups.google.com/groups/opt_out.

Peter Veentjer

unread,
Sep 17, 2013, 5:45:33 AM9/17/13
to haze...@googlegroups.com
Can you also post the code of the ISO class?

John Childress

unread,
Sep 17, 2013, 9:02:04 AM9/17/13
to haze...@googlegroups.com
ISO Class is easy...  I don't know if I can get a test case out today.  I know that sound lame, but today is super busy.  I'll get one late tonight or early tomorrow morning.
-------------------
package com.bobs.fun.common.entity;

import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.DataSerializable;

import java.io.IOException;

public enum ISO implements DataSerializable {
    CAISO("CAISO", "C"),
    ERCOT("ERCOT", "E"),
    IESO("IESO", "O"),
    MISO("MISO", "M"),
    NEISO("NEISO", "NE"),
    NYISO("NYISO", "NY"),
    PJMISO("PJMISO", "P"),
    SPP("SPP", "S");

    private String name;
    private String abbr;

    private ISO(String name, String abbr) {
        this.name = name;
        this.abbr = abbr;
    }

    public String getName() {
        return name;
    }

    public String getAbbr() {
        return abbr;
    }

    @Override
    public String toString() {
        return this.name;
    }

    public static ISO valueOfAbbr(String abbr) {
        switch (abbr) {
            case "C":
                return ISO.CAISO;
            case "E":
                return ISO.ERCOT;
            case "O":
                return ISO.IESO;
            case "M":
                return ISO.MISO;
            case "NE":
                return ISO.NEISO;
            case "NY":
                return ISO.NYISO;
            case "P":
                return ISO.PJMISO;
            case "S":
                return ISO.SPP;
        }
        return null;
    }


    @Override
    public void writeData(ObjectDataOutput out) throws IOException {
        out.writeUTF(this.abbr);
        out.writeUTF(this.name);
    }


    @Override
    public void readData(ObjectDataInput in) throws IOException {
        this.abbr = in.readUTF();
        this.name = in.readUTF();
    }
}

-------------------

Peter Veentjer

unread,
Sep 17, 2013, 9:14:48 AM9/17/13
to haze...@googlegroups.com
I don't think you need a testcase.

The problem is that the enum doesn't have a no arg constructor and therefor ISO can't be deserialized (that is what the exception is saying).

So you need to add a no arg constructor.

Peter Veentjer

unread,
Sep 17, 2013, 9:25:19 AM9/17/13
to haze...@googlegroups.com
I just had a quick chat with Mehmet,

the simplest thing you can do is to remove the DataSerializable from the Iso class.

and use the following approach:

class Foo implements DataSerializable{
    private Iso iso = Iso....  

   public void writeData(ObjectDataOutput out) throws IOException {
      out.writeUTF(iso.getAbrv());
   }

    public void readData(ObjectDataInput in) throws IOException {
        iso = Iso.valueOfAbbr(in.readUtf());
    } 
}


Barry Lagerweij

unread,
Sep 17, 2013, 9:36:28 AM9/17/13
to haze...@googlegroups.com
Should HZ not simply provide a default serializer for Enums ? Writing the classname and name (or ordinal) to the stream, and using Class.forName and Enum.values[ordinal] (or EnumClass.valueOf(name) ) during deserialization ?

Barry

Mehmet Dogan

unread,
Sep 17, 2013, 9:40:09 AM9/17/13
to haze...@googlegroups.com
Yes, implementing a default serializer for enums is possibile/easy. But deserializing a DataSerializable enum instance is not possible without hacks.

@mmdogan

John Childress

unread,
Sep 17, 2013, 10:13:20 AM9/17/13
to haze...@googlegroups.com
Thank you very much.  I'll test/verify this in just a few... thanks.

John

Peter Veentjer

unread,
Sep 17, 2013, 11:23:27 AM9/17/13
to haze...@googlegroups.com
Support was added for enums in the 3.1-SNAPSHOT. So it will be available in 3.1

John Childress

unread,
Sep 17, 2013, 1:29:21 PM9/17/13
to haze...@googlegroups.com
Thank you very much.  I followed your suggestion and it works fine.

Barry Lagerweij

unread,
Sep 17, 2013, 2:41:41 PM9/17/13
to haze...@googlegroups.com
Excellent, nice addition. The proposed pull-request does not seem like a hack a all ;-)

Is there any pattern in the assignment of factoryIds and typeIds ? What are the uniqueness constraints ? How can we avoid collisions in user-code with the HZ provided serializers ?

Barry

Mehmet Dogan

unread,
Sep 17, 2013, 3:40:34 PM9/17/13
to haze...@googlegroups.com

Hack is not required for enum serializer. What I mean was, if you create a custom enum which implements DataSerializable interface then a reflection hack is required, since DataSerializable creates object using class.newInstance().

Hazelcast uses negative IDs, user code is not allowed to use negative values.

@mmdogan

~Sent from mobile

Reply all
Reply to author
Forward
0 new messages