Buggy code:
private transient boolean sessionMetadataDirty ; private transient boolean sessionAttributesDirty ; private transient final AtomicLong timestamp = new AtomicLong ( 0 ) ; private volatile transient DistributableSessionMetadata metadata = new DistributableSessionMetadata ( ) ; private volatile transient long outdatedTime ; private final AtomicInteger version = new AtomicInteger ( 0 ) ; private transient String realId ; private volatile transient long lastReplicated ; private transient long maxUnreplicatedInterval ; private transient boolean alwaysReplicateTimestamp = true ; private transient Boolean hasActivationListener ; private transient boolean firstAccess ; private transient ClusteredSessionNotificationPolicy notificationPolicy ; private transient ClusteredSessionManagementStatus clusterStatus ; private transient boolean needsPostReplicateActivation ; private transient boolean fullReplicationRequired = true ; private transient long fullReplicationWindow = - 1 ; private transient Lock ownershipLock = new ReentrantLock ( ) ; protected ClusteredSession ( ClusteredSessionManager < O > manager ) { } @ Override public String getAuthType ( ) { } @ Override public void setAuthType ( String authType ) { } @ Override public long getCreationTime ( ) { } @ Override public void setCreationTime ( long time ) { } @ Override public String getId ( ) { } @ Override public String getIdInternal ( ) { } @ Override public void setId ( String id ) { } @ Override public long getLastAccessedTime ( ) { } @ Override public long getLastAccessedTimeInternal ( ) { } @ Override public Manager getManager ( ) { } @ Override public void setManager ( Manager manager ) { } @ Override public int getMaxInactiveInterval ( ) { } @ Override public void setMaxInactiveInterval ( int interval ) { } @ Override public Principal getPrincipal ( ) { } @ Override public void setPrincipal ( Principal principal ) { } @ Override public void access ( ) { } private void acquireSessionOwnership ( ) throws TimeoutException { } private boolean needNewLock ( ) { } @ Override public void endAccess ( ) { } private void relinquishSessionOwnership ( boolean remove ) { } @ Override public boolean isNew ( ) { } @ Override public void setNew ( boolean isNew ) { } @ Override public boolean isValid ( ) { } @ Override public void setValid ( boolean isValid ) { } @ Override public void invalidate ( ) { } @ Override public void expire ( ) { } @ Override public void recycle ( ) { } @ Override public void addSessionListener ( SessionListener listener ) { } @ Override public void removeSessionListener ( SessionListener listener ) { } @ Override public Object getNote ( String name ) { } @ Override public Iterator < String > getNoteNames ( ) { } @ Override public void setNote ( String name , Object value ) { } @ Override public void removeNote ( String name ) { } @ Override public HttpSession getSession ( ) { } @ Override public ServletContext getServletContext ( ) { } @ Override public Object getAttribute ( String name ) { } @ Override @ SuppressWarnings ( "unchecked" ) public Enumeration < String > getAttributeNames ( ) { } @ Override public void setAttribute ( String name , Object value ) { if ( name == null ) throw WebMessages . MESSAGES . expiredSession ( ) ; if ( value == null ) { removeAttribute ( name ) ; return ; } if ( ! ( isValidInternal ( ) ) ) { throw WebMessages . MESSAGES . expiredSession ( ) ; } if ( ( canAttributeBeReplicated ( value ) ) == false ) { <START_BUG> throw WebMessages . MESSAGES . failToReplicateAttribute ( ) ; <END_BUG> } HttpSessionBindingEvent event = null ; if ( ( value instanceof HttpSessionBindingListener ) && ( notificationPolicy . isHttpSessionBindingListenerInvocationAllowed ( this . clusterStatus , MODIFY , name , true ) ) ) { event = new HttpSessionBindingEvent ( getSession ( ) , name , value ) ; try { ( ( HttpSessionBindingListener ) ( value ) ) . valueBound ( event ) ; } catch ( Throwable t ) { manager . getContainer ( ) . getLogger ( ) . error ( WebMessages . MESSAGES . errorValueBoundEvent ( t ) ) ; } } if ( value instanceof HttpSessionActivationListener ) hasActivationListener = Boolean . TRUE ; Object unbound = setAttributeInternal ( name , value ) ; if ( ( ( ( unbound != null ) && ( unbound != value ) ) && ( unbound instanceof HttpSessionBindingListener ) ) && ( notificationPolicy . isHttpSessionBindingListenerInvocationAllowed ( this . clusterStatus , MODIFY , name , true ) ) ) { try { ( ( HttpSessionBindingListener ) ( unbound ) ) . valueUnbound ( new HttpSessionBindingEvent ( getSession ( ) , name ) ) ; } catch ( Throwable t ) { manager . getContainer ( ) . getLogger ( ) . error ( WebMessages . MESSAGES . errorValueUnboundEvent ( t ) ) ; } } if ( notificationPolicy . isHttpSessionAttributeListenerInvocationAllowed ( this . clusterStatus , MODIFY , name , true ) ) { Context context = ( ( Context ) ( manager . getContainer ( ) ) ) ; Object [ ] lifecycleListeners = context . getApplicationEventListeners ( ) ; if ( lifecycleListeners == null ) return ; for ( int i = 0 ; i < ( lifecycleListeners . length ) ; i ++ ) { if ( ! ( ( lifecycleListeners [ i ] ) instanceof HttpSessionAttributeListener ) ) continue ; HttpSessionAttributeListener listener = ( ( HttpSessionAttributeListener ) ( lifecycleListeners [ i ] ) ) ; try { if ( unbound != null ) { fireContainerEvent ( context , "beforeSessionAttributeReplaced" , listener ) ; if ( event == null ) { event = new HttpSessionBindingEvent ( getSession ( ) , name , unbound ) ; } listener . attributeReplaced ( event ) ; fireContainerEvent ( context , "afterSessionAttributeReplaced" , listener ) ; } else { fireContainerEvent ( context , "beforeSessionAttributeAdded" , listener ) ; if ( event == null ) { event = new HttpSessionBindingEvent ( getSession ( ) , name , value ) ; }

Fix:
throw WebMessages . MESSAGES . failToReplicateAttribute ( name , value . getClass ( ) . getCanonicalName ( ) ) ;