/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.marshall; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; /** * One of the key aspects of Infinispan is that it often needs to marshall or * unmarshall objects in order to provide some of its functionality. For * example, if it needs to store objects in a write-through or write-behind * cache store, the objects stored need marshalling. If a cluster of * Infinispan nodes is formed, objects shipped around need marshalling. Even * if you enable storing as binary, objects need to marshalled so that they * can be lazily unmarshalled with the correct classloader. * * Using standard JDK serialization is slow and produces payloads that are too * big and can affect bandwidth usage. On top of that, JDK serialization does * not work well with objects that are supposed to be immutable. In order to * avoid these issues, Infinispan uses JBoss Marshalling for * marshalling/unmarshalling objects. JBoss Marshalling is fast, provides * very space efficient payloads, and on top of that, allows users to * construct objects themselves during unmarshalling, hence allowing objects * to carry on being immutable. * * Starting with 5.0, users of Infinispan can now benefit from this marshalling * framework as well. In the simplest possible form, users just need to * provide an {@link Externalizer} implementation for the type that they want * to marshall/unmarshall, and then annotate the marshalled type class with * {@link SerializeWith} indicating the externalizer class to use and that's * all about it. At runtime JBoss Marshaller will inspect the object and * discover that's marshallable thanks to the annotation and so marshall it * using the externalizer class passed. * * It's common practice to include externalizer implementations within the * classes that they marshall/unmarshall as <code>public static classes</code>. * To make externalizer implementations easier to code and more typesafe, make * sure you define type <T> as the type of object that's being * marshalled/unmarshalled. * * Even though this way of defining externalizers is very user friendly, it has * some disadvantages: * * <ul> * <li>Due to several constraints of the model, such as support different * versions of the same class or the need to marshall the Externalizer * class, the payload sizes generated via this method are not the most * efficient.</li> * <li>This model requires for the marshalled class to be annoated with * {@link SerializeWith} but a user might need to provide an Externalizer * for a class for which source code is not available, or for any other * constraints, it cannot be modified.</li> * <li>The use of annotations by this model might be limiting for framework * developers or service providers that try to abstract lower level * details, such as the marshalling layer, away from the user.</li> * </ul> * * If you're affected by any of these disadvantages, an alternative mechanism * to provide externalizers is available via {@link AdvancedExternalizer}. * More details can be found in this interface's javadoc. * * @author Galder ZamarreƱo * @since 5.0 */ public interface Externalizer<T> extends Serializable { /** * Write the object reference to the stream. * * @param output the object output to write to * @param object the object reference to write * @throws IOException if an I/O error occurs */ void writeObject(ObjectOutput output, T object) throws IOException; /** * Read an instance from the stream. The instance will have been written by the * {@link #writeObject(ObjectOutput, Object)} method. Implementations are free * to create instances of the object read from the stream in any way that they * feel like. This could be via constructor, factory or reflection. * * @param input the object input to read from * @return the object instance * @throws IOException if an I/O error occurs * @throws ClassNotFoundException if a class could not be found */ T readObject(ObjectInput input) throws IOException, ClassNotFoundException; }