001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.apache.hadoop.io.serializer;
020    
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.io.ObjectInputStream;
024    import java.io.ObjectOutputStream;
025    import java.io.OutputStream;
026    import java.io.Serializable;
027    import org.apache.hadoop.classification.InterfaceAudience;
028    import org.apache.hadoop.classification.InterfaceStability;
029    
030    /**
031     * <p>
032     * An experimental {@link Serialization} for Java {@link Serializable} classes.
033     * </p>
034     * @see JavaSerializationComparator
035     */
036    @InterfaceAudience.Public
037    @InterfaceStability.Unstable
038    public class JavaSerialization implements Serialization<Serializable> {
039    
040      static class JavaSerializationDeserializer<T extends Serializable>
041        implements Deserializer<T> {
042    
043        private ObjectInputStream ois;
044    
045        @Override
046        public void open(InputStream in) throws IOException {
047          ois = new ObjectInputStream(in) {
048            @Override protected void readStreamHeader() {
049              // no header
050            }
051          };
052        }
053        
054        @Override
055        @SuppressWarnings("unchecked")
056        public T deserialize(T object) throws IOException {
057          try {
058            // ignore passed-in object
059            return (T) ois.readObject();
060          } catch (ClassNotFoundException e) {
061            throw new IOException(e.toString());
062          }
063        }
064    
065        @Override
066        public void close() throws IOException {
067          ois.close();
068        }
069    
070      }
071    
072      static class JavaSerializationSerializer
073        implements Serializer<Serializable> {
074    
075        private ObjectOutputStream oos;
076    
077        @Override
078        public void open(OutputStream out) throws IOException {
079          oos = new ObjectOutputStream(out) {
080            @Override protected void writeStreamHeader() {
081              // no header
082            }
083          };
084        }
085    
086        @Override
087        public void serialize(Serializable object) throws IOException {
088          oos.reset(); // clear (class) back-references
089          oos.writeObject(object);
090        }
091    
092        @Override
093        public void close() throws IOException {
094          oos.close();
095        }
096    
097      }
098    
099      @Override
100      @InterfaceAudience.Private
101      public boolean accept(Class<?> c) {
102        return Serializable.class.isAssignableFrom(c);
103      }
104    
105      @Override
106      @InterfaceAudience.Private
107      public Deserializer<Serializable> getDeserializer(Class<Serializable> c) {
108        return new JavaSerializationDeserializer<Serializable>();
109      }
110    
111      @Override
112      @InterfaceAudience.Private
113      public Serializer<Serializable> getSerializer(Class<Serializable> c) {
114        return new JavaSerializationSerializer();
115      }
116    
117    }