Search in sources :

Example 1 with DataSerializer

use of org.apache.geode.DataSerializer in project geode by apache.

the class InternalDataSerializer method writeUserObject.

/**
   * Data serializes an instance of a "user class" (that is, a class that can be handled by a
   * registered {@code DataSerializer}) to the given {@code DataOutput}.
   *
   * @return {@code true} if {@code o} was written to {@code out}.
   */
private static boolean writeUserObject(Object o, DataOutput out, boolean ensurePdxCompatibility) throws IOException {
    final Class<?> c = o.getClass();
    final DataSerializer serializer = InternalDataSerializer.getSerializer(c);
    if (serializer != null) {
        int id = serializer.getId();
        if (id != 0) {
            checkPdxCompatible(o, ensurePdxCompatibility);
            // id will be 0 if it is a WellKnowDS
            if (id <= Byte.MAX_VALUE && id >= Byte.MIN_VALUE) {
                out.writeByte(USER_CLASS);
                out.writeByte((byte) id);
            } else if (id <= Short.MAX_VALUE && id >= Short.MIN_VALUE) {
                out.writeByte(USER_CLASS_2);
                out.writeShort(id);
            } else {
                out.writeByte(USER_CLASS_4);
                out.writeInt(id);
            }
        } else {
            if (ensurePdxCompatibility) {
                if (!(serializer instanceof WellKnownPdxDS)) {
                    checkPdxCompatible(o, ensurePdxCompatibility);
                }
            }
        }
        boolean toDataResult;
        try {
            toDataResult = serializer.toData(o, out);
        } catch (IOException io) {
            if (serializer instanceof WellKnownDS) {
                // see bug 44659
                throw io;
            } else {
                // with the plugin code.
                throw new ToDataException("toData failed on DataSerializer with id=" + id + " for class " + c, io);
            }
        } catch (CancelException | ToDataException | GemFireRethrowable ex) {
            // Serializing a PDX can result in a cache closed exception. Just rethrow
            throw ex;
        } catch (VirtualMachineError err) {
            SystemFailure.initiateFailure(err);
            // now, so don't let this thread continue.
            throw err;
        } catch (Throwable t) {
            // Whenever you catch Error or Throwable, you must also
            // catch VirtualMachineError (see above). However, there is
            // _still_ a possibility that you are dealing with a cascading
            // error condition, so you also need to check to see if the JVM
            // is still usable:
            SystemFailure.checkFailure();
            throw new ToDataException("toData failed on DataSerializer with id=" + id + " for class " + c, t);
        }
        if (toDataResult) {
            return true;
        } else {
            throw new ToDataException(LocalizedStrings.DataSerializer_SERIALIZER_0_A_1_SAID_THAT_IT_COULD_SERIALIZE_AN_INSTANCE_OF_2_BUT_ITS_TODATA_METHOD_RETURNED_FALSE.toLocalizedString(serializer.getId(), serializer.getClass().getName(), o.getClass().getName()));
        }
    // Do byte[][] and Object[] here to fix bug 44060
    } else if (o instanceof byte[][]) {
        byte[][] byteArrays = (byte[][]) o;
        out.writeByte(ARRAY_OF_BYTE_ARRAYS);
        writeArrayOfByteArrays(byteArrays, out);
        return true;
    } else if (o instanceof Object[]) {
        Object[] array = (Object[]) o;
        out.writeByte(OBJECT_ARRAY);
        writeObjectArray(array, out, ensurePdxCompatibility);
        return true;
    } else if (is662SerializationEnabled() && (o.getClass().isEnum() || /* for bug 52271 */
    (o.getClass().getSuperclass() != null && o.getClass().getSuperclass().isEnum()))) {
        if (isPdxSerializationInProgress()) {
            writePdxEnum((Enum<?>) o, out);
        } else {
            checkPdxCompatible(o, ensurePdxCompatibility);
            writeGemFireEnum((Enum<?>) o, out);
        }
        return true;
    } else {
        PdxSerializer pdxSerializer = TypeRegistry.getPdxSerializer();
        return pdxSerializer != null && writePdx(out, null, o, pdxSerializer);
    }
}
Also used : PdxInstanceEnum(org.apache.geode.pdx.internal.PdxInstanceEnum) PdxSerializer(org.apache.geode.pdx.PdxSerializer) IOException(java.io.IOException) GemFireIOException(org.apache.geode.GemFireIOException) GemFireRethrowable(org.apache.geode.GemFireRethrowable) ToDataException(org.apache.geode.ToDataException) CancelException(org.apache.geode.CancelException) DataSerializer(org.apache.geode.DataSerializer)

Example 2 with DataSerializer

use of org.apache.geode.DataSerializer in project geode by apache.

the class InternalDataSerializer method _register.

public static DataSerializer _register(DataSerializer s, boolean distribute) {
    final int id = s.getId();
    DataSerializer dsForMarkers = s;
    if (id == 0) {
        throw new IllegalArgumentException(LocalizedStrings.InternalDataSerializer_CANNOT_CREATE_A_DATASERIALIZER_WITH_ID_0.toLocalizedString());
    }
    final Class[] classes = s.getSupportedClasses();
    if (classes == null || classes.length == 0) {
        final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_0_HAS_NO_SUPPORTED_CLASSES_ITS_GETSUPPORTEDCLASSES_METHOD_MUST_RETURN_AT_LEAST_ONE_CLASS;
        throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
    }
    for (Class aClass : classes) {
        if (aClass == null) {
            final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_GETSUPPORTEDCLASSES_METHOD_FOR_0_RETURNED_AN_ARRAY_THAT_CONTAINED_A_NULL_ELEMENT;
            throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
        } else if (aClass.isArray()) {
            final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_GETSUPPORTEDCLASSES_METHOD_FOR_0_RETURNED_AN_ARRAY_THAT_CONTAINED_AN_ARRAY_CLASS_WHICH_IS_NOT_ALLOWED_SINCE_ARRAYS_HAVE_BUILTIN_SUPPORT;
            throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
        }
    }
    final Integer idx = id;
    boolean retry;
    Marker oldMarker = null;
    final Marker m = new InitMarker();
    do {
        retry = false;
        Object oldSerializer = idsToSerializers.putIfAbsent(idx, m);
        if (oldSerializer != null) {
            if (oldSerializer instanceof Marker) {
                retry = !idsToSerializers.replace(idx, oldSerializer, m);
                if (!retry) {
                    oldMarker = (Marker) oldSerializer;
                }
            } else if (oldSerializer.getClass().equals(s.getClass())) {
                // We've already got one of these registered
                if (distribute) {
                    sendRegistrationMessage(s);
                }
                return (DataSerializer) oldSerializer;
            } else {
                DataSerializer other = (DataSerializer) oldSerializer;
                throw new IllegalStateException(LocalizedStrings.InternalDataSerializer_A_DATASERIALIZER_OF_CLASS_0_IS_ALREADY_REGISTERED_WITH_ID_1_SO_THE_DATASERIALIZER_OF_CLASS_2_COULD_NOT_BE_REGISTERED.toLocalizedString(new Object[] { other.getClass().getName(), other.getId() }));
            }
        }
    } while (retry);
    try {
        for (int i = 0; i < classes.length; i++) {
            DataSerializer oldS = classesToSerializers.putIfAbsent(classes[i].getName(), s);
            if (oldS != null) {
                if (!s.equals(oldS)) {
                    // cleanup the ones we have already added
                    for (int j = 0; j < i; j++) {
                        classesToSerializers.remove(classes[j].getName(), s);
                    }
                    dsForMarkers = null;
                    String oldMsg;
                    if (oldS.getId() == 0) {
                        oldMsg = "DataSerializer has built-in support for class ";
                    } else {
                        oldMsg = "A DataSerializer of class " + oldS.getClass().getName() + " is already registered to support class ";
                    }
                    String msg = oldMsg + classes[i].getName() + " so the DataSerializer of class " + s.getClass().getName() + " could not be registered.";
                    if (oldS.getId() == 0) {
                        throw new IllegalArgumentException(msg);
                    } else {
                        throw new IllegalStateException(msg);
                    }
                }
            }
        }
    } finally {
        if (dsForMarkers == null) {
            idsToSerializers.remove(idx, m);
        } else {
            idsToSerializers.replace(idx, m, dsForMarkers);
        }
        if (oldMarker != null) {
            oldMarker.setSerializer(dsForMarkers);
        }
        m.setSerializer(dsForMarkers);
    }
    // if dataserializer is getting registered for first time
    // its EventID will be null, so generate a new event id
    // the the distributed system is connected
    InternalCache cache = GemFireCacheImpl.getInstance();
    if (cache != null && s.getEventId() == null) {
        s.setEventId(new EventID(cache.getDistributedSystem()));
    }
    if (distribute) {
        // send a message to other peers telling them about a newly-registered
        // dataserializer, it also send event id of the originator along with the
        // dataserializer
        sendRegistrationMessage(s);
        // send it to cache servers if it is a client
        sendRegistrationMessageToServers(s);
    }
    // send it to all cache clients irrelevant of distribute
    // bridge servers send it all the clients irrelevant of
    // originator VM
    sendRegistrationMessageToClients(s);
    fireNewDataSerializer(s);
    return s;
}
Also used : InternalCache(org.apache.geode.internal.cache.InternalCache) LogMarker(org.apache.geode.internal.logging.log4j.LogMarker) BigInteger(java.math.BigInteger) StringId(org.apache.geode.i18n.StringId) EventID(org.apache.geode.internal.cache.EventID) ObjectStreamClass(java.io.ObjectStreamClass) DataSerializer(org.apache.geode.DataSerializer)

Example 3 with DataSerializer

use of org.apache.geode.DataSerializer in project geode by apache.

the class InternalDataSerializer method getSerializersForDistribution.

/**
   * Returns all the data serializers in this vm. This method, unlike {@link #getSerializers()},
   * does not force loading of the data serializers which were not loaded in the vm earlier.
   * 
   * @return Array of {@link SerializerAttributesHolder}
   */
public static SerializerAttributesHolder[] getSerializersForDistribution() {
    final int size = idsToSerializers.size() + dsClassesToHolders.size();
    Collection<SerializerAttributesHolder> coll = new ArrayList<>(size);
    for (Object v : idsToSerializers.values()) {
        if (v instanceof InitMarker) {
            v = ((Marker) v).getSerializer();
        }
        if (v instanceof DataSerializer) {
            DataSerializer s = (DataSerializer) v;
            coll.add(new SerializerAttributesHolder(s.getClass().getName(), (EventID) s.getEventId(), (ClientProxyMembershipID) s.getContext(), s.getId()));
        }
    }
    for (final Entry<String, SerializerAttributesHolder> stringSerializerAttributesHolderEntry : dsClassesToHolders.entrySet()) {
        SerializerAttributesHolder v = stringSerializerAttributesHolderEntry.getValue();
        coll.add(v);
    }
    return coll.toArray(new SerializerAttributesHolder[coll.size()]);
}
Also used : ClientProxyMembershipID(org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID) ArrayList(java.util.ArrayList) EventID(org.apache.geode.internal.cache.EventID) DataSerializer(org.apache.geode.DataSerializer)

Example 4 with DataSerializer

use of org.apache.geode.DataSerializer in project geode by apache.

the class CacheClientNotifier method writeMessage.

private void writeMessage(DataOutputStream dos, byte type, String p_msg, Version clientVersion, byte epType, int qSize) throws IOException {
    String msg = p_msg;
    // write the message type
    dos.writeByte(type);
    // dummy epType
    dos.writeByte(epType);
    // dummy qSize
    dos.writeInt(qSize);
    if (msg == null) {
        msg = "";
    }
    dos.writeUTF(msg);
    if (clientVersion != null && clientVersion.compareTo(Version.GFE_61) >= 0) {
        // get all the instantiators.
        Instantiator[] instantiators = InternalInstantiator.getInstantiators();
        HashMap instantiatorMap = new HashMap();
        if (instantiators != null && instantiators.length > 0) {
            for (Instantiator instantiator : instantiators) {
                ArrayList instantiatorAttributes = new ArrayList();
                instantiatorAttributes.add(instantiator.getClass().toString().substring(6));
                instantiatorAttributes.add(instantiator.getInstantiatedClass().toString().substring(6));
                instantiatorMap.put(instantiator.getId(), instantiatorAttributes);
            }
        }
        DataSerializer.writeHashMap(instantiatorMap, dos);
        // get all the dataserializers.
        DataSerializer[] dataSerializers = InternalDataSerializer.getSerializers();
        HashMap<Integer, ArrayList<String>> dsToSupportedClasses = new HashMap<Integer, ArrayList<String>>();
        HashMap<Integer, String> dataSerializersMap = new HashMap<Integer, String>();
        if (dataSerializers != null && dataSerializers.length > 0) {
            for (DataSerializer dataSerializer : dataSerializers) {
                dataSerializersMap.put(dataSerializer.getId(), dataSerializer.getClass().toString().substring(6));
                if (clientVersion.compareTo(Version.GFE_6516) >= 0) {
                    ArrayList<String> supportedClassNames = new ArrayList<String>();
                    for (Class clazz : dataSerializer.getSupportedClasses()) {
                        supportedClassNames.add(clazz.getName());
                    }
                    dsToSupportedClasses.put(dataSerializer.getId(), supportedClassNames);
                }
            }
        }
        DataSerializer.writeHashMap(dataSerializersMap, dos);
        if (clientVersion.compareTo(Version.GFE_6516) >= 0) {
            DataSerializer.writeHashMap(dsToSupportedClasses, dos);
        }
    }
    dos.flush();
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Instantiator(org.apache.geode.Instantiator) InternalInstantiator(org.apache.geode.internal.InternalInstantiator) DataSerializer(org.apache.geode.DataSerializer) InternalDataSerializer(org.apache.geode.internal.InternalDataSerializer)

Example 5 with DataSerializer

use of org.apache.geode.DataSerializer in project geode by apache.

the class DataSerializableJUnitTest method testSupportedClasses.

/**
   * Tests that only one serializer is invoked when a serializer specifies its supported classes.
   * Alos tests UDDS1.
   */
@Test
public void testSupportedClasses() throws Exception {
    DataSerializer ds1 = DataSerializer.register(Class_testSupportedClasses1.class);
    int id = ds1.getId();
    DataSerializer ds2 = DataSerializer.register(Class_testSupportedClasses2.class);
    int id2 = ds2.getId();
    try {
        Object o = new NonDataSerializable(new Random());
        DataSerializer.writeObject(o, getDataOutput());
        assertTrue(Class_testSupportedClasses2.wasInvoked);
        assertTrue(Class_testSupportedClasses2.toDataInvoked);
        assertFalse(Class_testSupportedClasses2.fromDataInvoked);
        Object o2 = DataSerializer.readObject(getDataInput());
        assertTrue(Class_testSupportedClasses2.fromDataInvoked);
        assertEquals(o, o2);
    } finally {
        InternalDataSerializer.unregister(id);
        InternalDataSerializer.unregister(id2);
    }
}
Also used : DataSerializer(org.apache.geode.DataSerializer) UnitTest(org.apache.geode.test.junit.categories.UnitTest) Test(org.junit.Test)

Aggregations

DataSerializer (org.apache.geode.DataSerializer)19 ObjectStreamClass (java.io.ObjectStreamClass)7 UnitTest (org.apache.geode.test.junit.categories.UnitTest)5 Test (org.junit.Test)5 InternalDataSerializer (org.apache.geode.internal.InternalDataSerializer)4 BigInteger (java.math.BigInteger)3 ArrayList (java.util.ArrayList)3 Entry (java.util.Map.Entry)2 Instantiator (org.apache.geode.Instantiator)2 StringId (org.apache.geode.i18n.StringId)2 EventID (org.apache.geode.internal.cache.EventID)2 LogMarker (org.apache.geode.internal.logging.log4j.LogMarker)2 IOException (java.io.IOException)1 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CancelException (org.apache.geode.CancelException)1 CanonicalInstantiator (org.apache.geode.CanonicalInstantiator)1