• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 544
  • Last Modified:

Serialization and EJB in JBOSS problem!

      Hi experts!
I've invoked a session bean method deployed in JBoss 3.2.7, this method return an object. But it got this exception :

java.lang.reflect.UndeclaredThrowableException
      at $Proxy29.exportContactCSV(Unknown Source)
      at be.belga.belgadirect.unitest.business.myaccount.PersonalContactTest.testExportContactCSV(PersonalContactTest.java:241)
      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.reflect.Method.invoke(Method.java:585)
      at junit.framework.TestCase.runTest(TestCase.java:154)
      at junit.framework.TestCase.runBare(TestCase.java:127)
      at junit.framework.TestResult$1.protect(TestResult.java:106)
      at junit.framework.TestResult.runProtected(TestResult.java:124)
      at junit.framework.TestResult.run(TestResult.java:109)
      at junit.framework.TestCase.run(TestCase.java:118)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.io.NotSerializableException: esp.database.csv.Csv
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1054)
      at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
      at java.rmi.MarshalledObject.<init>(MarshalledObject.java:92)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:364)
      at sun.reflect.GeneratedMethodAccessor99.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
      at sun.rmi.transport.Transport$1.run(Transport.java:148)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
      at java.lang.Thread.run(Thread.java:534)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
      at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
      at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source)
      at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:135)
      at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:163)
      at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:103)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:55)
      at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:86)
      ... 15 more
The java.io.NotSerializableException is only thrown when the return object is not serializable, my return object is serializable! I've successfully written it to a file with the the method writeObject of an instance of ObjectOutputStream class. This mean that my object is serializable. Do I need to do anything to make this object serializable in JBoss?
Thank you very much.
0
novicer
Asked:
novicer
  • 4
  • 3
2 Solutions
 
Mayank SAssociate Director - Product EngineeringCommented:
>> java.io.NotSerializableException: esp.database.csv.Csv

Well, somehow, this class is not serializable, or it contains a data-member which is not serializable. What is the structure of this class?
0
 
mrigankCommented:
Does your class have Lists or Maps.
Maybe objects added to these Collection types at runtime are not Serializble.
Just a thought.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Yes but it should not have got serialized to the file.... are you sure you serialized that very object to the file? Can you post the code for this Cvs class?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mrigankCommented:
Try one more thing

In your SessionBean method testExportContactCSV()

Just before returning the CSV object, call the writeObject method on it and see if it gets Serialized.
0
 
mrigankCommented:
(PersonalContactTest.java:241)

What does this line number do exactly ?
0
 
novicerAuthor Commented:
>Just before returning the CSV object, call the writeObject method on it and see if it gets Serialized.
I've did a test this morning, it got Serialized, I can write it and then read it back, call a method of it too.
Sorry if this post is too long, here is the source code of Csv class and related classes.
The Csv.java:
package esp.database.csv;



import java.io.*;

import java.net.*;

import java.util.*;



public class Csv implements Serializable{

      /**

       *

       */

      private static final long serialVersionUID = 4712904207499439149L;

      Vector records;

      Vector fields;

      int cursor=-1;

      transient Object source=null;

      

      /*****************************************************

       *  Create a new empty Csv table

       *

       *****************************************************/

      public Csv(){

            records=new Vector();

            fields=new Vector();            

      }



      /*****************************************************

       * Create a CSV table from the given instance of

       * java.io.InputStream by wrapping

       * an instance of  java.io.Reader around it.

       *

       *****************************************************/

      public Csv(InputStream is) throws IOException{

            this(new InputStreamReader(is));

      }



      /*****************************************************

       * Create a CSV table from the given instance of

       * java.io.Reader

       *

       *****************************************************/

      public Csv(Reader r) throws IOException{

            this();

            BufferedReader br=new BufferedReader(r);

            String line=br.readLine();

            if(line==null){

                  throw new IOException("Empty Data Source");

            }

            StringTokenizer st=new StringTokenizer(line,",");

            while(st.hasMoreTokens()){

                  fields.addElement(CsvValue.parseField(st.nextToken()));

            }

            while((line=br.readLine())!=null){

                  boolean setVal=false;

                  Hashtable record=new Hashtable();

                  int fieldNo=0;

                  st=new StringTokenizer(line,",",true);

                  while(st.hasMoreTokens()){

                        CsvValue field=(CsvValue)fields.elementAt(fieldNo);

                        if(record.get(field)==null){

                              record.put(field,field.clone());

                        }

                        String val=st.nextToken();

                        if(val.equals(",")){

                              if(!setVal){

                                    ((CsvValue)record.get(field)).setRaw(null);

                              }

                              fieldNo++;

                              setVal=false;

                              continue;

                        }

                        if(val.startsWith("\"")){

                              if(val.length()==1)

                                    val+=st.nextToken();

                              while(!val.endsWith("\"")){

                                    val+=st.nextToken();

                              }

                        }

                        ((CsvValue)record.get(field)).setRaw(val);

                        setVal=true;

                  }

                  records.addElement(record);

            }

            r.close();

      }



      /*****************************************************

       * Convience function for reading a cvs file from the

       * given location which can be either a file path or

       * a url.

       *

       *****************************************************/

      public static Csv fromString(String location) throws IOException{

            Object source;

            Csv ret=new Csv();

            try{

                  URL src=new URL(location);

                  if(src.getProtocol().equalsIgnoreCase("file")){

                        source=new File(src.getFile());

                  }

                  else{

                        source=src;

                  }

                  ret=new Csv(src.openStream());

            }

            catch(MalformedURLException e){

                  source=new File(location);

                  ret=new Csv(new FileReader((File)source));

            }

            ret.source=source;

            System.out.println(source);

            return ret;

      }



      /*****************************************************

       * Get the record that is at the current cursor

       * position

       *

       *****************************************************/

      public Hashtable getRecord(){

            return (Hashtable)records.elementAt(cursor);

      }



      /*****************************************************

       * Get the raw value of the data field named field

       * in the current record.

       *

       *****************************************************/

      public Object getRaw(Object field){

            Hashtable record=getRecord();

            return record.get(field);

      }



      /*****************************************************

       * Advance the cursor to the next record

       *

       *****************************************************/

      public boolean next(){

            if(cursor<records.size()-1){

                  cursor++;

                  return true;

            }

            return false;

      }



      /*****************************************************

       * move the cursor to the previous record

       *

       *****************************************************/

      public boolean prev(){

            if(cursor>0 && records.size()>0){

                  cursor--;

                  return true;

            }

            return false;

      }



      /*****************************************************

       * move the cursor to the first record

       *

       *****************************************************/

      public boolean first(){

            if(records.size()>0){

                  cursor=0;

                  return true;

            }

            return false;

      }



      /*****************************************************

       * move the cursor to the first record

       *

       *****************************************************/

      public boolean reset(){

            return first();

      }



      /*****************************************************

       * move the cursor to the last record

       *

       *****************************************************/

      public boolean last(){

            if(records.size()>0){

                  cursor=records.size()-1;

                  return true;

            }

            return false;

      }



      /*****************************************************

       * move the cursor to the record specified by index

       *

       *****************************************************/

      public boolean moveTo(int index){

            if(index<records.size()){

                  cursor=index;

                  return true;

            }

            return false;

      }



      /*****************************************************

       * return the number of records in the table

       *

       *****************************************************/

      public int countRecords(){

            return records.size();

      }



      /*****************************************************

       * return the field names of the table as an

       * enumeration.

       *****************************************************/

      public Enumeration getFields(){

            return fields.elements();

      }



      /*****************************************************

       * Rename field named oldname to name.

       *

       *****************************************************/

      public void renameField(String oldname, String name){

            renameField(fields.indexOf(getByName(oldname)),name);

      }



      /*****************************************************

       * Delete the record at position index.

       *

       *****************************************************/

      public void delete(int index){

            if(index>=records.size()){

                  return;

            }

            records.removeElementAt(index);

      }



      /*****************************************************

       * Append a new record to the end of the csv.

       *

       *****************************************************/

      public void append(){

            Hashtable record=new Hashtable();

            Enumeration e=getFields();

            while(e.hasMoreElements()){

                  CsvValue field=(CsvValue)e.nextElement();

                  CsvValue val=(CsvValue)field.clone();

                  val.setRaw(null);

                  record.put(field,val);

            }

            records.addElement(record);

            cursor=records.size()-1;

      }



      /*****************************************************

       * Set the value of field in the current record

       *

       *****************************************************/

      public void setValue(String field,String value){

            setValue(cursor,getByName(field),value);

      }



      /*****************************************************

       * Remove field name from all records.

       *

       *****************************************************/

      public void delField(Object name){

            int indx=fields.indexOf(name);

            if(indx<0){

                  return;

            }

            fields.removeElementAt(indx);

      }



      /*****************************************************

       * Add the new field name to all records and set the

       * value to null.

       *

       *****************************************************/

      public void addField(String name) throws Exception{

            CsvValue field=CsvValue.parseField(name);

            if(getByName(field.toString())!=null){

                  throw new Exception("Field "+field+" already exists in this table");

            }

            fields.addElement(field);

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

                  Hashtable record=(Hashtable)records.elementAt(i);

                  record.put(field,field.clone());

                  setValue(i,field,null);

            }

      }



      /*****************************************************

       * retrieve all the records from the csv that match

       * criteria in the form of fieldname=value and return

       * them as a new instalce of csv.

       *

       *****************************************************/

      public Csv getRecords(String criteria){

            StringTokenizer st=new StringTokenizer(criteria,"=");

            if(st.countTokens()!=2){

                  return null;

            }

            CsvValue field=getByName(st.nextToken());

            criteria=st.nextToken();

            Csv ret=new Csv();

            ret.fields=fields;

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

                  Hashtable record=(Hashtable)records.elementAt(i);

                  if(record.get(field).toString().equals(criteria)){

                        ret.records.addElement(records.elementAt(i));

                  }

            }

            return ret;

      }



      /*****************************************************

       * Save the csv file to the file it was created from.

       *****************************************************/

      public void save() throws IOException{

            if(source==null){

                  throw new IOException("CVS source is not set");

            }

            else if(source instanceof URL){

                  throw new IOException("Cannot save to URL "+source);

            }

            else{

                  write(new FileWriter((File)source));

            }

      }

      /*****************************************************

       * Write the csv to the given java.io.OutputStream

       * by wrapping an instance of java.io.Writer around

       * it and calling write(Writer).

       *

       *****************************************************/



      public void write(OutputStream os) throws IOException{

            write(new OutputStreamWriter(os));

      }



      /*****************************************************

       * Write the cvs to the given instance of

       * java.io.Writer.

       *

       *****************************************************/

      public void write(Writer ow) throws IOException{

            PrintWriter bw=new PrintWriter(ow);

            Enumeration e=getFields();

            while(e.hasMoreElements()){

                  bw.print(((CsvValue)e.nextElement()).toHeaderString());

                  if(e.hasMoreElements()){

                        bw.print(",");

                  }

            }

            bw.println();

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

                  Hashtable rec=(Hashtable)records.elementAt(i);

                  e=getFields();

                  while(e.hasMoreElements()){

                        CsvValue val=(CsvValue)rec.get(e.nextElement());

                        if(val !=null){

                              bw.print(val.saveFormat());

                        }

                        if(e.hasMoreElements()){

                              bw.print(",");

                        }

                  }

                  bw.println();

            }

            bw.close();

      }



      CsvValue getByName(String name){

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

                  if(fields.elementAt(i).toString().equals(name)){

                        return (CsvValue)fields.elementAt(i);

                  }

            }

            return null;

      }



      void renameField(int id, String name){

            ((CsvValue)fields.elementAt(id)).setString(name);

      }



      void headToRecord(){

            Hashtable record=new Hashtable();

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

                  record.put(

                        fields.elementAt(i),

                        ((CsvValue)fields.elementAt(i)).clone()

                  );

            }

            records.addElement(record);

      }



      void setValue(int rec, CsvValue field,String value){

            Hashtable record=(Hashtable)records.elementAt(rec);

            ((CsvValue)record.get(field)).setRaw(value);

      }



}

The CsvValue.java:
package esp.database.csv;



import java.util.*;

import java.io.Serializable;

import java.text.*;



public class CsvValue implements Cloneable, Serializable{

      /**

       *

       */

      private static final long serialVersionUID = -6139567364674162856L;

      static final char integer='i';

      static final char string='s';

      static final char bool='b';

      static final char date='D';

      static final char time='t';

      static final char doub='d';

      static final char undef='u';

      static final char auto='a';

      AutoNumber an;

      SimplisticDateFormat format=new SimplisticDateFormat();



      transient private Object _value;

      char _type=undef;

      private boolean autoIncrement=false;



      public void setType(char type){

            if((type != integer) && autoIncrement){

                  autoIncrement=false;

            }

            _type=type;

      }

      public char getType(){

            return _type;

      }

      public void setRaw(Object value){

            if(value==null && autoIncrement){

                  _value=new Integer(an.getNext());

            }

            else if(value instanceof String){

                  switch(_type){

                        case integer:

                              setInt(Integer.parseInt((String)value));

                              break;

                        case doub:

                              setDouble(Double.parseDouble((String)value));

                              break;

                        case bool:

                              setBoolean(Boolean.getBoolean((String)value));

                              break;

                        case date:

                        case time:

//                              try{

                                    setDate(format.parse((String)value));

//                              }

//                              catch(ParseException pe){

//                                    setString("");

//                              }

                              break;

                        default:

                              setString((String)value);

                  }

            }

            else{

                  _value=value;

            }

      }

      public Object getRaw(){

            return _value;

      }

      String unescape(String value){

            String esc[]={"\\r","\\n","\\t"};

            String rep[]={"\r","\n","\t"};

            for(int i=0;i<esc.length;i++){

                  int indx=value.indexOf(esc[i]);

                  while(indx>-1){

                        value=value.substring(0,indx)+rep[i]+

                        value.substring(indx+esc[i].length());

                        indx=value.indexOf(esc[i]);

                  }

            }

            return value;

      }

      String escape(String value){

            String rep[]={"\\r","\\n","\\t"};

            String esc[]={"\r","\n","\t"};

            for(int i=0;i<esc.length;i++){

                  int indx=value.indexOf(esc[i]);

                  while(indx>-1){

                        value=value.substring(0,indx)+rep[i]+

                        value.substring(indx+esc[i].length());

                        indx=value.indexOf(esc[i]);

                  }

            }

            return value;

      }

      public void setString(String value){

            _value=unescape(value);

      }

      public String getString(){

            return _value.toString();

      }

      public void setInt(int value){

            _value=new Integer(value);

      }

      public int getInt(){

            if(_value instanceof Integer){

                  return ((Integer)_value).intValue();

            }

            return 0;

      }

      public void setDouble(double value){

            _value=new Double(value);

      }

      public double getDouble(){

            if(_value instanceof Double){

                  return ((Double)_value).doubleValue();

            }

            return 0;

      }

      public void setDate(Date value){

            _value=value;

      }

      public Date getDate(){

            if(_value instanceof Date){

                  return (Date)_value;

            }

            return null;

      }

      public void setBoolean(boolean value){

            _value=new Boolean(value);

      }

      public boolean getBoolean(){

            if(_value instanceof Boolean){

                  return ((Boolean)_value).booleanValue();

            }

            return false;

      }

      public void setCurrency(double value){

            _value=new Double(value);

      }

      public double getCurrency(){

            return getDouble();

      }

      public Object clone(){

            CsvValue cln=new CsvValue();

            cln.setRaw(_value);

            cln.setType(_type);

            cln.autoIncrement=autoIncrement;

            cln.an=an;

            cln.format=format;

            return cln;

      }

      String saveFormat(){

            if(_type==string){

                  return escape((String)_value);

            }

            return toString();

      }

      public String toString(){

            if(_value==null){

                  return "";

            }

            if(_value instanceof Date){

                  return format.format((Date)_value,_type);

            }

            return _value.toString();

      }

      public String toHeaderString(){

            String ret=_value.toString();

            ret+="^"+_type;

            if(autoIncrement){

                  ret+="^a"+an.getCurrent();

            }

            return ret;

      }

      public static CsvValue parseField(String info){

            CsvValue field=new CsvValue();

            StringTokenizer st=new StringTokenizer(info,"^");

            field.setString(st.nextToken());

            while(st.hasMoreTokens()){

                  String stMod=st.nextToken();

                  char mod=stMod.charAt(0);

                  switch(mod){

                        case date:

                        case time:

//                              field.format=new SimpleDateFormat(stMod.substring(1));

                        case integer:

                        case string:

                        case bool:

                        case doub:

                              field.setType(mod);

                              continue;

                        case auto:

                              field.autoIncrement=true;

                              field.an=new AutoNumber(Integer.parseInt(stMod.substring(1)));

                        default: continue;

                  }

            }

            return field;

      }

}

The AutoNumber.java:
package esp.database.csv;



import java.io.Serializable;



public class AutoNumber implements Serializable{

      /**

       *

       */

      private static final long serialVersionUID = 6381204585235437000L;

      int value;



      public AutoNumber(int initial){

            value=initial;

      }

      public int getNext(){

            int current=value;

            value++;

            return current;

      }

      public int getCurrent(){

            return value;

      }

}

And last the SimplisticDateFormat.java:
package esp.database.csv;



import java.io.Serializable;

import java.util.*;



public class SimplisticDateFormat implements Serializable{

      /**

       *

       */

      private static final long serialVersionUID = 8293029711136612096L;

      public Date parse(String in){

            Date ret=new Date();

            StringTokenizer st=new StringTokenizer(in,"-/");

            if(st.countTokens()==3){

                  ret.setMonth(Integer.parseInt(st.nextToken()));

                  ret.setDate(Integer.parseInt(st.nextToken()));

                  ret.setYear(Integer.parseInt(st.nextToken()));

            }

            else{

                  int hourmod=0;

                  if(in.toUpperCase().endsWith("PM")){

                        hourmod=12;

                  }

                  in=in.substring(0,in.length()-2);

                  st=new StringTokenizer(in,":");

                  ret.setHours(Integer.parseInt(st.nextToken())+hourmod);

                  ret.setMinutes(Integer.parseInt(st.nextToken()));

            }

            return ret;

      }

      public String format(Date d, char type){

            String ret="";

            if(type=='D'){

                  ret+=d.getMonth()+"/";

                  ret+=d.getDate()+"/";

                  ret+=d.getYear();

            }

            else if(type=='t'){

                  boolean pm=false;

                  if(d.getHours()>12){

                        ret+=d.getHours()-12;

                        pm=true;

                  }

                  else{

                        ret+=d.getHours();

                  }

                  ret+=":"+d.getMinutes();

                  if(pm){

                        ret +="PM";

                  }

                  else{

                        ret+="AM";

                  }

            }

            return ret;

      }

}

Hope this may help:
0
 
Mayank SAssociate Director - Product EngineeringCommented:
My guess is that the hashtable or the vector contain something which is not serializable.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
So what was the not serializable object inside the collection?
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now