Sockets hanging when sending one class using ObjectOutputStream

I've been working on developing a networked client/server java program, and was planning on using the ObjectInput/OutputStream to wrap the streams provided by the sockets. However, every time I try to send a particular class that I wrote, the connection drops with a SocketException "Connection reset by peer: socket write error"

Any thoughts on what could be causing this?

The class causing the problem is below:

package capesvtt.game;

import capesvtt.game.clickandlocks.ClickAndLock;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

import java.io.Serializable;

import java.util.List;

import java.util.Vector;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.TableModel;

/**

*

* @author Michael

*/

publicclass CapesCharacterimplements Serializable{

privateclass DriveTableModelextends AbstractTableModel{

publicint getRowCount(){return drives.size();}

publicint getColumnCount(){return 3;}

publicboolean isCellEditable(int rowIndex,int columnIndex){

if (characterType == CapesCharacter.CharacterType.POWERED)

returntrue;

returnfalse;

}

public Object getValueAt(int rowIndex,int columnIndex){

if (columnIndex == 0)return drives.get(rowIndex).getName();

if (columnIndex == 1)return drives.get(rowIndex).getStrength();

if (columnIndex == 2)return drives.get(rowIndex).getDebt();

returnnull;

}

publicvoid setValueAt(Object aValue,int rowIndex,int columnIndex){

if (columnIndex == 0) drives.get(rowIndex).setName(aValue.toString());

if (columnIndex == 1){

try{

drives.get(rowIndex).setStrength(Integer.parseInt(aValue.toString()));

normalizeDrives(rowIndex);

}catch (NumberFormatException e){

}catch (IllegalArgumentException e){}

}

if (columnIndex == 2){

try{

drives.get(rowIndex).setDebt(Integer.parseInt(aValue.toString()));

}catch (NumberFormatException e){

}catch (IllegalArgumentException e){}

}

}

public String getColumnName(int column){

switch(column){

case 0:return"Drive";

case 1:return"Strength";

case 2:return"Debt";

}

return super.getColumnName(column);

}

}

privatevoid normalizeDrives(int driveChanged){

if (characterType != CharacterType.POWERED)return;

int driveTotal = 0;

for (Drive drive : drives) driveTotal += drive.getStrength();

int driveDiff = 9 - driveTotal;

if (driveDiff == 0)return;

for (int i = 0; i < drives.size() && driveDiff != 0; i++){

if (i == driveChanged)continue;

Drive drive = drives.get(i);

int strength = drive.getStrength();

if (driveDiff < 0){

if (strength + driveDiff >= 1){

strength = strength + driveDiff;

driveDiff = 0;

drive.setStrength(strength);

}else{

driveDiff += strength - 1;

drive.setStrength(1);

}

}else{

drive.setStrength(strength+driveDiff);

driveDiff = 0;

}

}

driveTableModel.fireTableDataChanged();

}

privateclass AbilityTableModelextends AbstractTableModel{

privateint offset = 0;

public AbilityTableModel(int col){

offset = 5 * col;

}

publicint getRowCount(){if (offset < abilities.size())return 5;elsereturn 0;}

publicint getColumnCount(){return 3;}

publicboolean isCellEditable(int rowIndex,int columnIndex){returntrue;}

public Object getValueAt(int rowIndex,int columnIndex){

if (columnIndex == 0)return abilities.get(rowIndex+offset).getName();

if (columnIndex == 1)return abilities.get(rowIndex+offset).getStrength();

if (columnIndex == 2)return abilities.get(rowIndex+offset).isPowered();

returnnull;

}

publicvoid setValueAt(Object aValue,int rowIndex,int columnIndex){

if (columnIndex == 0) abilities.get(rowIndex+offset).setName(aValue.toString());

if (columnIndex == 1){

try{

normilizeAbilities(Integer.parseInt(aValue.toString()),

abilities.get(rowIndex+offset).getStrength(),

offset,

rowIndex);

for (AbilityTableModel atm : abilityTableModels) atm.fireTableDataChanged();

}catch (NumberFormatException e){

}catch (IllegalArgumentException e){}

}

if (columnIndex == 2){abilities.get(rowIndex+offset).setPowered(Boolean.parseBoolean(aValue.toString()));}

}

public Class<?> getColumnClass(int columnIndex){

switch (columnIndex){

case 0:return String.class;

case 1:return Number.class;

case 2:return Boolean.class;

}

return String.class;

}

}

publicenum CharacterType{POWERED, UNDIFFERENTED, UNPOWERED};

private DriveTableModel driveTableModel =new DriveTableModel();

private AbilityTableModel[] abilityTableModels =new AbilityTableModel[3];

private CharacterType characterType = CharacterType.POWERED;

privatestaticlong ID_NOT_ASSIGNED = -1;

private List<Drive> drives =new Vector<Drive>();

private List<Ability> abilities =new Vector<Ability>();

private String name ="New Hero";

private String shortDescription ="Undefined";

private String longDescription ="Undefined";

privatelong id = ID_NOT_ASSIGNED;

/** Creates a new instance of CapesCharacter */

public CapesCharacter(){

this.id = 0;

setCharacterType(CharacterType.POWERED);

for (int i = 0; i < 15; i++){

int value = 5 - (i % 5 + i / 5);

if (value < 0) value = 0;

if (i < 8){

abilities.add(new Ability("Undefined", value,true));

}else{

abilities.add(new Ability("Undefined", value,false));

}

}

for (int i = 0; i < 3; i++){

abilityTableModels[i] =new AbilityTableModel(i);

}

}

public TableModel getDriveTableModel(){

return driveTableModel;

}

public TableModel[] getAbilityTableModels(){

return abilityTableModels;

}

public String getName(){

return name;

}

publicvoid setName(String name){

this.name = name;

}

public String getShortDescription(){

return shortDescription;

}

publicvoid setShortDescription(String shortDescription){

this.shortDescription = shortDescription;

}

public String getLongDescription(){

return longDescription;

}

publicvoid setLongDescription(String longDescription){

this.longDescription = longDescription;

}

public String toString(){

return name +", " + shortDescription;

}

publicvoid setClickOrLock(ClickAndLock clickAndLock){

List<String> names = clickAndLock.getItems();

int offset;

if (clickAndLock.isAbility()) offset = 0;else offset = 8;

for (int i = 0; i < names.size(); i++){

abilities.get(i+offset).setName(names.get(i));

}

for (AbilityTableModel atm : abilityTableModels) atm.fireTableDataChanged();

}

publicvoid setCharacterType(CharacterType newType){

characterType = newType;

switch (newType){

case POWERED:

drives.clear();

drives.add(new Drive("Justice", 1));

drives.add(new Drive("Truth", 1));

drives.add(new Drive("Love", 1));

drives.add(new Drive("Hope", 1));

drives.add(new Drive("Duty", 5));

break;

case UNDIFFERENTED:

drives.clear();

drives.add(new Drive("Undifferentiated", 5));

break;

case UNPOWERED:

drives.clear();

break;

}

driveTableModel.fireTableDataChanged();

}

publicboolean equals(Object obj){

if (!(objinstanceof CapesCharacter))returnfalse;

return (this.id == ((CapesCharacter)obj).id) && (id != ID_NOT_ASSIGNED);

}

privatevoid normilizeAbilities(int newValue,int oldValue,int offset,int row){

int maxAbility = getMaxAbility(offset);

if (newValue == 0 && oldValue != 0){

if (maxAbility == 3)return;

modAbilities(offset, -1);

do{

offset += 5;

if (offset == 15) offset = 0;

}while (getMaxAbility(offset) == 5);

modAbilities(offset,1);

return;

}

if (newValue == 1 && oldValue == 0){

modAbilitiesUp(offset, row);

do{

offset += 5;

if (offset == 15) offset = 0;

}while (getMaxAbility(offset) == 3);

modAbilities(offset,-1);

return;

}

if (newValue > maxAbility){

modAbilities(offset,1);

do{

offset += 5;

if (offset == 15) offset = 0;

}while (getMaxAbility(offset) == 3);

modAbilities(offset,-1);

return;

}

for (int i = 0; i < 5; i++){

int strength = abilities.get(i+offset).getStrength();

if (strength == newValue) abilities.get(i+offset).setStrength(oldValue);

if (strength == oldValue) abilities.get(i+offset).setStrength(newValue);

}

}

privateint getMaxAbility(int offset){

int returnValue = 0;

for (int i = 0; i < 5; i++){

int strength = abilities.get(i+offset).getStrength();

if (strength > returnValue) returnValue = strength;

}

return returnValue;

}

privatevoid modAbilities(int offset,int mod){

boolean[] used ={false, false, false, false,false};

for (int i = 0; i < 5; i++){

int strength = abilities.get(i+offset).getStrength() + mod;

if (strength >= 0 && strength <= 5){

if (strength <= 0){

abilities.get(i+offset).setStrength(0);

}elseif (!used[strength-1]){

used[strength-1] =true;

abilities.get(i+offset).setStrength(strength);

}

}

}

}

privatevoid modAbilitiesUp(int offset,int row){

for (int i = 0; i < 5; i++){

if (row == i){

abilities.get(i+offset).setStrength(1);

}else{

int strength = abilities.get(i+offset).getStrength();

if (strength != 0) abilities.get(i+offset).setStrength(strength+1);

}

}

}

}

[24113 byte] By [Kai_Lorda] at [2007-10-3 4:10:55]
# 1

Dropping a connection isn't what I would call a 'hang'.

That exception usually means that you're writing to a connection which has been closed by the peer: IOW it is an application protocol error.

As you don't show the writing code, or the reading code at the other end, it's impossible to say more.

ejpa at 2007-7-14 22:11:17 > top of Java-index,Core,Core APIs...
# 2
I found the problem. I needed to mark the the AbilityTableModel and DriveTableModel fields transient, and then recreate them in the readObject method. It was not a networking problem after all. Sorry to have bothered you.Message was edited by: Kai_Lord
Kai_Lorda at 2007-7-14 22:11:17 > top of Java-index,Core,Core APIs...