Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] inter-type declaration of a field variable is not serialized

Ok, found a solution, it is a bit complicated so if anyone knows something simpler, please post.

To serialize correctly, I've created the following classes/aspect. They use the Externalizable interface to perform serialization. It works fine with tomcat (objects on the session are serialized correctly i.e. when you reload a web app).

Note: all IPersist+ classes must have a default constructor.

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

package org.aris;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class PersistUtils
{
public static void writeExternalizable(ObjectOutput out, Object o) throws IllegalArgumentException, IllegalAccessException, IOException
   {
       List<Field> fields = getFields(o.getClass());
       for (Field f : fields)
       {
           if (isModifiersOk(f))
           {
               f.setAccessible(true);
               Object value = f.get(o);
System.out.println("--> Writing : " + f.getName() + " of value : " + value);
               out.writeObject(value);
           }
       }
   }

   public static boolean isModifiersOk(Field f)
   {
       int modifiers = f.getModifiers();
return !(Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) || f.getName().indexOf("$interField$") > -1;
   }

   public static List<Field> getFields(Class c)
   {
       ArrayList<Field> l = new ArrayList<Field>();
       l.addAll(Arrays.asList(c.getDeclaredFields()));
       Class sc = c.getSuperclass();
       if (sc != null)
       {
           List<Field> fields = getFields(sc);
           l.addAll(fields);
       }
       return l;
   }

public static void readExternalizable(ObjectInput in, Object o) throws IllegalArgumentException, IllegalAccessException, IOException, ClassNotFoundException
   {
       List<Field> fields = getFields(o.getClass());
       for (Field f : fields)
       {
           if (isModifiersOk(f))
           {
               Object value = in.readObject();
               f.setAccessible(true);
               f.set(o, value);
// System.out.println("--> Read : " + f.getName() + " of value : " + value);
           }
       }
   }
}

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

I have a marker interface. Any class that implements it is serializable.

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

package org.aris.model.markers;

import java.io.Externalizable;

public interface IPersist extends Externalizable
{
   public static final long serialVersionUID = 5341735380765534993L;

}

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

The following aspect makes sure IPersist+ classes are serialized :

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

package org.aris.model.aspects;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.aris.model.markers.*;
import org.aris.PersistUtils;

public aspect Persist
{
   public void IPersist.writeExternal(ObjectOutput out) throws IOException
   {
//        System.out.println("writeExternal");
       try
       {
           PersistUtils.writeExternalizable(out,this);
       } catch (IllegalArgumentException e)
       {
           e.printStackTrace();
       } catch (IllegalAccessException e)
       {
           e.printStackTrace();
       }
   }

public void IPersist.readExternal(ObjectInput in) throws IOException, ClassNotFoundException
   {
//        System.out.println("readExternal");
       try
       {
           PersistUtils.readExternalizable(in,this);
       } catch (IllegalArgumentException e)
       {
           e.printStackTrace();
       } catch (IllegalAccessException e)
       {
           e.printStackTrace();
       }
   }

}

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

Regards,

Kostas


Konstantinos Kougios wrote:
I've noticed the following:

   public long ISimpleC.id=-1;
// declares the id on ISimpleC interface. Id is not serialized correctly for all classes that implement ISimpleC. Eclipse debugger shows the field like been nested within inner classes. Reflection tools can't read the value of id

   public long SimpleC.id=-1;
// declares the id on SimpleC class Id is serialized correctly. Eclipse debugger shows the id as a field of the class and reflection tools read the value of the id

So, if you introduce the id straight away on the class as a public member, it works. My problem is that I was to introduce it to a set of classes, all of them implementing an interface (or even if I could introduce it to a set of classes belonging to a package).

Regards,

Kostas



Konstantinos Kougios wrote:
Hi,

I've a serialization problem and I tried to search on google or this emailing list, but I couldn't find a solution. So, here it is:

I am introducing i.e. a boolean variable in some classes using an aspect:

...
   private boolean IUpdatable.isDirty=false;
...

IUpdatable is an interface and it "extend Serializable".

I now got this class:

public class Path implements IUpdatable
{
  private String name;
  ...
}


While name is serialized correctly, the isDirty is not serialized. I tried various alternatives, like making the aspect serializable or pethis() but it didn't solve my problem. I know that the isDirty in fact is stored inside the aspect and not in the Path class, but how can I make it serialize correctly?

Thanks,

Kostas
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users





Back to the top