public <T> void share( byte channel, String name, T object, Class<? super T> type ) {
        
        ClassInfo typeInfo = classCache.getClassInfo(type);
        
        local.lock.writeLock().lock();
        try {
            
            // First see if we've told the remote end about this class
            // before
            if( local.classes.put(typeInfo.getId(), typeInfo) == null ) {
                // It's new
                rpc.callAsync(defaultChannel, rmiId, NEW_CLASS, typeInfo);
                
                // Because type info IDs are global to the class cache,
                // we could in theory keep a global index that we broadcast
                // on first connection setup... we need only prepopulate
                // the index in that case.
            }
 
            // See if we already shared an object under that name           
            SharedObject existing = local.byName.remove(name);
            if( existing != null ) {
                local.byId.remove(existing.objectId);
                rpc.removeHandler(existing.objectId, rmiHandler);
            
                // Need to delete the old one from the remote end
                rpc.callAsync(defaultChannel, rmiId, REMOVE_OBJECT, existing.objectId);
                
                // We don't reuse the ID because it's kind of dangerous.
                // Churning through a new ID is our safety net for accidents.                
            }
            
            SharedObject newShare = new SharedObject(name, object, type, typeInfo);
            local.byName.put(name, newShare);
            local.byId.put(newShare.objectId, newShare);
            
            // Make sure we are set up to receive the remote method calls through
            // the RPC service
            rpc.registerHandler(newShare.objectId, rmiHandler);
            
            // Let the other end know
            rpc.callAsync(defaultChannel, rmiId, ADD_OBJECT, channel, newShare.objectId, name, typeInfo.getId()); 
 
            // We send the ADD_OBJECT to the other end before releasing the
            // lock to avoid a potential inconsistency if two threads try to
            // jam the same name at the same time.  Otherwise, if the timing were
            // right, the remove for one object could get there before its add.
        
        } finally {
            local.lock.writeLock().unlock();
        }   
    }
Exposes, through a specific connection channel, the specified object to 
 the other end of the connection as the specified interface type and associates 
 it with the specified name.  
 The object can be looked up by the associated name on the other end of
 the connection.
 The specified channel will be used for all network communication
 specific to this object.
jme3-networking/src/main/java/com/jme3/network/service/rmi/RmiRegistry.java