Search code examples
javatomcatcluster-computinggxtgwt-rpc

Serializing exception with GXT RPCMAP


I'm heading the following issue

 SEVERE: Unable to serialize delta request for sessionid [576530C8078FEBD71743551D4417DAD5]
java.io.NotSerializableException: com.extjs.gxt.ui.client.data.RpcMap
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at java.util.ArrayList.writeObject(ArrayList.java:570)
    at sun.reflect.GeneratedMethodAccessor955.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at org.apache.catalina.ha.session.DeltaRequest$AttributeInfo.writeExternal(DeltaRequest.java:392)
    at org.apache.catalina.ha.session.DeltaRequest.writeExternal(DeltaRequest.java:285)
    at org.apache.catalina.ha.session.DeltaRequest.serialize(DeltaRequest.java:299)
    at org.apache.catalina.ha.session.DeltaManager.serializeDeltaRequest(DeltaManager.java:617)
    at org.apache.catalina.ha.session.DeltaManager.requestCompleted(DeltaManager.java:1057)
    at org.apache.catalina.ha.session.DeltaSession.expire(DeltaSession.java:436)
    at org.apache.catalina.ha.session.DeltaManager.handleSESSION_EXPIRED(DeltaManager.java:1370)
    at org.apache.catalina.ha.session.DeltaManager.messageReceived(DeltaManager.java:1276)
    at org.apache.catalina.ha.session.DeltaManager.messageDataReceived(DeltaManager.java:1005)
    at org.apache.catalina.ha.session.ClusterSessionListener.messageReceived(ClusterSessionListener.java:92)
    at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:897)
    at org.apache.catalina.ha.tcp.SimpleTcpCluster.messageReceived(SimpleTcpCluster.java:878)
    at org.apache.catalina.tribes.group.GroupChannel.messageReceived(GroupChannel.java:275)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:80)
    at org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.messageReceived(TcpFailureDetector.java:113)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:80)
    at org.apache.catalina.tribes.group.ChannelInterceptorBase.messageReceived(ChannelInterceptorBase.java:80)
    at org.apache.catalina.tribes.group.ChannelCoordinator.messageReceived(ChannelCoordinator.java:253)
    at org.apache.catalina.tribes.transport.ReceiverBase.messageDataReceived(ReceiverBase.java:271)
    at org.apache.catalina.tribes.transport.nio.NioReplicationTask.drainChannel(NioReplicationTask.java:211)
    at org.apache.catalina.tribes.transport.nio.NioReplicationTask.run(NioReplicationTask.java:100)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

when uploading a List<InfoClasifCustom> to session.

This class is the following:

public class InfoClasifCustom extends BaseModelData implements Serializable, IsSerializable, BeanModelTag, Comparable<InfoClasifCustom>{

private String idClasificacion;
private String color;
private Integer numEquiposGrupo;
private Long idGrupo;

private Boolean isEditable=false;
private static final long serialVersionUID = 8202856915683008011L;

public InfoClasificacionCustom() {

}

public void setColor(String color) {
    this.color = color;
}

public Integer getNumOrden() {
    return get("numOrden");
}

public void setNumOrden(Integer numOrden) {
    set("numOrden",numOrden);
}

So I'm using both standard attributes and the RPCMap of BaseModelData for attributes of this class, and all of them are primitive types or wrappers (thats, int or Integer).

Could there be a problem of serializing RPCMap? Maybe the List? I'm only having this issue on production, as its a Tomcat-cluster.

Anyone could help?


Solution

  • The issue is related at the RpcMap implementation. Unfortunately, the RpcMap not implement Serialization (on the old GXT release). To fix the issue, I suggest to add in your project the class "com.extjs.gxt.ui.client.data.RpcMap", that is equals the real GXT "RpcMap", but implement Serializable. In this way the compiler use your class.

    Below the code example:

    enter code here
    /*
     * Ext GWT - Ext for GWT
     * Copyright(c) 2007, 2008, Ext JS, LLC.
     * licensing@extjs.com
     * 
     * http://extjs.com/license
     */
    package com.extjs.gxt.ui.client.data;
    import java.io.Serializable;
    import java.util.Collection;
    import java.util.Date;
    
    import java.util.HashMap; import java.util.List; import
    java.util.Map; import java.util.Set;
    
    /**  * RpcMap is used to workaround a part of GWT RPC system.  *   *
    <p /> The GWT RPC rebinder generates field serializers for every type
    that is  * assignable to any type in the RPC interfaces.  *   * <p />
    If BaseModel was to use "Map&lt;String, Serializable> map" this would
    trigger  * the RPC system to generate field serializers for EVERY
    Serializable type in  * your GWT Module's class path.  *   * <p />
    Therefore BaseModel uses "Map&lt;String, RpcField> map" and relies on
    type  * erasure (cast to Map&lt;Object,Object>) to work around this. 
    *   * <p /> The only drawback is that if you have to ensure that field serializers are  * generated for any type you add to this map 
    *   * <p /> RpcMap ensures that the following types are supported Byte, Short, Integer,  * Long, Float, Double, Date, Boolean, and
    arrays of these types. As well as  * List, Set and Map  */
    @SuppressWarnings("unused") public class RpcMap implements
    Serializable{
    /**      *       */     private static final long serialVersionUID = 1L;
    private Byte _byte;   private Short _short;   private Integer
    _integer;   private Long _long;   
    private Float _float;   private Double _double;
    private Date _date;   private Boolean _boolean;
    
     private Byte[] _bytes;   private Short[] _shorts;   private
    Integer[] _integers;   private Long[] _longs;   private Float[]
    _floats;   private Double[] _doubles;   private Date[] _dates;
    private Boolean[] _booleans;
    
    private List<String> _list;   private Set<String> _set;   private
    Map<String, String> _map;
    
    private transient Map<String, Object> map = new HashMap<String,Object>();
    
     public Map<String, Object> getTransientMap() {
       return map;   }
    
     public void clear() {
       map.clear();   }
    
     public boolean containsKey(Object key) {
       return map.containsKey(key);   }
    
     public boolean containsValue(Object value) {
       return map.containsValue(value);   }
    
     public Set<Map.Entry<String, Object>> entrySet() {
       return map.entrySet();   }
    
     public boolean equals(Object o) {
       if(o instanceof RpcMap){
         return map.equals(((RpcMap)o). map);
       }
       return false;   }
    
     public Object get(Object key) {
       return map.get(key);   }
    
     public int hashCode() {
       return map.hashCode();   }
    
     public boolean isEmpty() {
       return map.isEmpty();   }
    
     public Set<String> keySet() {
       return map.keySet();   }
    
     public Object put(String key, Object value) {
       return map.put(key, value);   }
    
     public void putAll(Map<? extends String, ? extends Object> m) {
       map.putAll(m);   }
    
     public Object remove(Object key) {
       return map.remove(key);   }
    
     public int size() {
       return map.size();   }
    
     public Collection<Object> values() {
       return map.values();   }
    
     @Override   public String toString() {
       return map.toString();   }
    
    }