1

I am creating a demo stock exchange distributed program in Java using jgroups as middleware. My Stock class has a priority queue which has a comparator, and results in Stock$1.class and Stock$2.class along with Stock.class. Jgroups can send only serializable data but from what I understand $1.class and $2.class result from inner classes that are inferred because of comparator's and are not serializable thus causing exceptions with JGroups, can someone help me as to how to make them serializable too or some other tweek to not to make it look like inner classes.

import java.io.*;
import java.util.*;
import java.io.Serializable;

public class Stock implements Serializable
{
    public String name;
    public String symbol;
    public int shares = 10000;
    public int price = 100;

    public PriorityQueue<Order> sellList = new PriorityQueue<Order>(100, new Comparator<Order>()
    {
        public int compare(Order oldOrder, Order newOrder)
        {
            int i = oldOrder.price;
            int j = newOrder.price;
            if(i > j)
                return 1;
            else if(i < j)
                return -1;
            else
                return 0;
        }
    }
    );

    public PriorityQueue<Order> buyList = new PriorityQueue<Order>(100, new Comparator<Order>()
            {
                public int compare(Order oldOrder, Order newOrder)
                {
                    int i = oldOrder.price;
                    int j = newOrder.price;
                    if(i > j)
                        return -1;
                    else if(i < j)
                        return 1;
                    else
                        return 0;
                }
            }
        );
}
corsiKa
  • 81,495
  • 25
  • 153
  • 204
Yogesh
  • 11
  • 2
  • Stack-> java.io.NotSerializableException: Stock$2 at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518) at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:422) at java.util.PriorityQueue.writeObject(PriorityQueue.java:686) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang – Yogesh Apr 22 '11 at 20:57

1 Answers1

3

Your anonymous inner classes only implement Comparator. In order to implement Comparator and Serializable, you should convert them to static nested classes, e.g.

public class Stock implements Serializable {

    private static class OrderComparator implements Comparator, Serializable {
        public int compare(Order oldOrder, Order newOrder) {
            int i = oldOrder.price;
            int j = newOrder.price;
            if(i > j) {
                return 1;
            } else if (i < j)
                return -1;
            } else {
                return 0;
            }
        }
    }

    private PriorityQueue<Order> sellList = new PriorityQueue<Order>(100, new OrderComparator());
}

Not only will this fix your immediate problem, it arguable also makes the code more readable.

Incidentally, the above comparator can be rewritten much more succinctly:

        public int compare(Order oldOrder, Order newOrder) {
            return oldOrder.price - newOrder.price;
        }
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • +1 I should point out that the two Comparators are not the same. The `-1` and `1` are reversed in the top and bottom in the OP. However, the same concept can still be applied, and the readability (and reusability) of extracting into a private static class are still gained. – corsiKa Apr 22 '11 at 21:03
  • I also would like to point out that I would advise against using subtraction in the comparison. Consider an Order with a refund. If you have `-2000000000` for oldOrder, and `1000000000` for newOrder, yours would have `old-new = -3000000000` but would overflow into positive territory, when the result really should be negative. – corsiKa Apr 22 '11 at 21:06
  • @glowcoder: Fair point. I always get comparators the wrong way around :) – skaffman Apr 22 '11 at 21:13
  • I'm tempted to say "If you know the input will never be negative, or in a range that can cause such an overflow it's okay" but then I think... man if I had a dollar for every time the requirements said "The input will never be _____" and it turned out they were, then I wouldn't need my day job :-) – corsiKa Apr 22 '11 at 21:15