Reputation: 1047
Background: I am implementing a game which needs to serialize model objects (events) to be able to send them over the network to clients playing the game.
Problem: One of my model classes is EventShowCards
, which subclasses Event
(declared to be serializable).
public class EventShowCards extends Event {
private final Player player;
private final List<ItemCard> cards;
public EventShowCards(Player player, List<ItemCard> cards) {
super();
this.player = player;
this.cards = cards;
}
public Player getPlayer() {
return player;
}
public List<ItemCard> getCards() {
return cards;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
However, when I serialize the object and send it to the client, the client receives the object and list of ItemCard
s is empty. No exceptions are thrown.
Event as shown by the server (before serialization):
Event as shown by the client (after serialization):
In order to serialize/deserialize I am using a standard ObjectOutputStream/ObjectInputStream
Anyone has any idea of what could be happening here? Thanks.
EDIT
As request I am posting the code of the ItemCard (and Card):
ItemCard.java
public abstract class ItemCard extends Card {
/**
* By default a card ca be played independently from the game state, subclasses that have more complicated rules
* must override this method.
*/
public boolean canBePlayed(GameStateTurn gameState) {
return true;
}
protected void emitEventCardPlayed(Player cardPlayer, GameState gameState) {
notifyObservers(new EventCardPlayed(cardPlayer, this));
}
}
Card.java
public abstract class Card extends ConcreteObservable<Event> implements CardBehavior, Serializable {
protected Deck<? extends Card> deck; // The deck to which this card belongs
public Card() {
super();
}
public void setDeck(Deck<? extends Card> deck) {
this.deck = deck;
}
public void discard() {
deck.discard(this);
}
@Override
public void preEffect(Player cardPlayer, GameState gameState) {
// By default cards have no preEffects
}
@Override
public void postEffect(Player cardPlayer, GameState gameState) {
// By default after a card is played it is discarded
discard();
}
@Override
public String toString() {
String className = this.getClass().getSimpleName();
return cardNameFromClassName(className);
}
private String cardNameFromClassName(String className) {
StringBuilder sb = new StringBuilder();
for (Character c: className.toCharArray()) {
if (Character.isUpperCase(c)) {
sb.append(" ").append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return "\"" + sb.substring(1) + "\"";
}
}
EDIT 2
And Deck.java
public class Deck<T extends Card>
extends ConcreteObservable<Event>
implements Observer<Event>, Serializable {...}
EDIT 3
The List of item cards used to initialize the EventShowCards was an already created list from another model object of my application, passed as-is. Creating another ArrayList (copying that object) somehow solved my problem.
Upvotes: 1
Views: 4455
Reputation: 8230
The List can contain unlimited number of object types.
As you have your EventShowCards
serialized (through Event
class), you need also to force your ItemCard
class to be serializable in order to be marshalled and unmarshalled when needed correctly.
java.util.List
doesn't implement Serializable, this is why your list is not serialized.
use other collections which are serializable like ArrayList
Upvotes: 1