class SerializableWritable[T <: Writable](@transient var t: T) extends Serializable {
def value: T = t
override def toString: String = t.toString
private def writeObject(out: ObjectOutputStream): Unit = Utils.tryOrIOException {
out.defaultWriteObject()
new ObjectWritable(t).write(out)
}
private def readObject(in: ObjectInputStream): Unit = Utils.tryOrIOException {
in.defaultReadObject()
val ow = new ObjectWritable()
ow.setConf(new Configuration(false))
ow.readFields(in)
t = ow.get().asInstanceOf[T]
}
}
The usage of ObjectWritable:
val ow = new ObjectWritable()
ow.setConf(new Configuration(false))
ow.readFields(in)
ObjectWritable class defination:
public class ObjectWritable implements Writable, Configurable {
private Class declaredClass;
private Object instance;
private Configuration conf;
private static final Map<String, Class<?>> PRIMITIVE_NAMES = new HashMap();
constructors
public ObjectWritable() {
}
public ObjectWritable(Object instance) {
this.set(instance);
}
public ObjectWritable(Class declaredClass, Object instance) {
this.declaredClass = declaredClass;
this.instance = instance;
}
conf operation
public void setConf(Configuration conf) {
this.conf = conf;
}
public Configuration getConf() {
return this.conf;
}
primitive
static {
PRIMITIVE_NAMES.put("boolean", Boolean.TYPE)
PRIMITIVE_NAMES.put("byte", Byte.TYPE)
PRIMITIVE_NAMES.put("char", Character.TYPE)
PRIMITIVE_NAMES.put("short", Short.TYPE)
PRIMITIVE_NAMES.put("int", Integer.TYPE)
PRIMITIVE_NAMES.put("long", Long.TYPE)
PRIMITIVE_NAMES.put("float", Float.TYPE)
PRIMITIVE_NAMES.put("double", Double.TYPE)
PRIMITIVE_NAMES.put("void", Void.TYPE)
}
write
public void write(DataOutput out) throws IOException {
writeObject(out, this.instance, this.declaredClass, this.conf)
}
public static void writeObject(DataOutput out, Object instance, Class declaredClass, Configuration conf) throws IOException {
writeObject(out, instance, declaredClass, conf, false)
}
public static void writeObject(DataOutput out, Object instance, Class declaredClass, Configuration conf, boolean allowCompactArrays) throws IOException {
if(instance == null) {
instance = new ObjectWritable.NullInstance(declaredClass, conf)
declaredClass = Writable.class
}
if(allowCompactArrays && declaredClass.isArray() && instance.getClass().getName().equals(declaredClass.getName()) && instance.getClass().getComponentType().isPrimitive()) {
instance = new Internal(instance)
declaredClass = Internal.class
}
UTF8.writeString(out, declaredClass.getName())
if(declaredClass.isArray()) {
int length = Array.getLength(instance)
out.writeInt(length)
for(int i = 0
writeObject(out, Array.get(instance, i), declaredClass.getComponentType(), conf, allowCompactArrays)
}
} else if(declaredClass == Internal.class) {
((Internal)instance).write(out)
} else if(declaredClass == String.class) {
UTF8.writeString(out, (String)instance)
} else if(declaredClass.isPrimitive()) {
if(declaredClass == Boolean.TYPE) {
out.writeBoolean(((Boolean)instance).booleanValue())
} else if(declaredClass == Character.TYPE) {
out.writeChar(((Character)instance).charValue())
} else if(declaredClass == Byte.TYPE) {
out.writeByte(((Byte)instance).byteValue())
} else if(declaredClass == Short.TYPE) {
out.writeShort(((Short)instance).shortValue())
} else if(declaredClass == Integer.TYPE) {
out.writeInt(((Integer)instance).intValue())
} else if(declaredClass == Long.TYPE) {
out.writeLong(((Long)instance).longValue())
} else if(declaredClass == Float.TYPE) {
out.writeFloat(((Float)instance).floatValue())
} else if(declaredClass == Double.TYPE) {
out.writeDouble(((Double)instance).doubleValue())
} else if(declaredClass != Void.TYPE) {
throw new IllegalArgumentException("Not a primitive: " + declaredClass)
}
} else if(declaredClass.isEnum()) {
UTF8.writeString(out, ((Enum)instance).name())
} else if(Writable.class.isAssignableFrom(declaredClass)) {
UTF8.writeString(out, instance.getClass().getName())
((Writable)instance).write(out)
} else {
if(!Message.class.isAssignableFrom(declaredClass)) {
throw new IOException("Can\'t write: " + instance + " as " + declaredClass)
}
((Message)instance).writeDelimitedTo(DataOutputOutputStream.constructOutputStream(out))
}
}
read
public static Object readObject(DataInput in, Configuration conf) throws IOException {
return readObject(in, (ObjectWritable)null, conf);
}
public static Object readObject(DataInput in, ObjectWritable objectWritable, Configuration conf) throws IOException {
String className = UTF8.readString(in);
Class declaredClass = (Class)PRIMITIVE_NAMES.get(className);
if(declaredClass == null) {
declaredClass = loadClass(conf, className);
}
Object instance;
if(declaredClass.isPrimitive()) {
if(declaredClass == Boolean.TYPE) {
instance = Boolean.valueOf(in.readBoolean());
} else if(declaredClass == Character.TYPE) {
instance = Character.valueOf(in.readChar());
} else if(declaredClass == Byte.TYPE) {
instance = Byte.valueOf(in.readByte());
} else if(declaredClass == Short.TYPE) {
instance = Short.valueOf(in.readShort());
} else if(declaredClass == Integer.TYPE) {
instance = Integer.valueOf(in.readInt());
} else if(declaredClass == Long.TYPE) {
instance = Long.valueOf(in.readLong());
} else if(declaredClass == Float.TYPE) {
instance = Float.valueOf(in.readFloat());
} else if(declaredClass == Double.TYPE) {
instance = Double.valueOf(in.readDouble());
} else {
if(declaredClass != Void.TYPE) {
throw new IllegalArgumentException("Not a primitive: " + declaredClass);
}
instance = null;
}
} else if(declaredClass.isArray()) {
int instanceClass = in.readInt();
instance = Array.newInstance(declaredClass.getComponentType(), instanceClass);
for(int str = 0; str < instanceClass; ++str) {
Array.set(instance, str, readObject(in, conf));
}
} else {
Internal var9;
if(declaredClass == Internal.class) {
var9 = new Internal();
var9.readFields(in);
instance = var9.get();
declaredClass = instance.getClass();
} else if(declaredClass == String.class) {
instance = UTF8.readString(in);
} else if(declaredClass.isEnum()) {
instance = Enum.valueOf(declaredClass, UTF8.readString(in));
} else if(Message.class.isAssignableFrom(declaredClass)) {
instance = tryInstantiateProtobuf(declaredClass, in);
} else {
var9 = null;
String var11 = UTF8.readString(in);
Class var10 = loadClass(conf, var11);
Writable writable = WritableFactories.newInstance(var10, conf);
writable.readFields(in);
instance = writable;
if(var10 == ObjectWritable.NullInstance.class) {
declaredClass = ((ObjectWritable.NullInstance)writable).declaredClass;
instance = null;
}
}
}
if(objectWritable != null) {
objectWritable.declaredClass = declaredClass;
objectWritable.instance = instance;
}
return instance;
}
read from or write to protobuf
private static Message tryInstantiateProtobuf(Class<?> protoClass, DataInput dataIn) throws IOException {
try {
if(dataIn instanceof InputStream) {
Method iae1 = getStaticProtobufMethod(protoClass, "parseDelimitedFrom", new Class[]{InputStream.class});
return (Message)iae1.invoke((Object)null, new Object[]{(InputStream)dataIn});
} else {
int iae = ProtoUtil.readRawVarint32(dataIn);
if(iae < 0) {
throw new IOException("Invalid size: " + iae);
} else {
byte[] data = new byte[iae];
dataIn.readFully(data);
Method parseMethod = getStaticProtobufMethod(protoClass, "parseFrom", new Class[]{byte[].class});
return (Message)parseMethod.invoke((Object)null, new Object[]{data});
}
}
} catch (InvocationTargetException var5) {
if(var5.getCause() instanceof IOException) {
throw (IOException)var5.getCause();
} else {
throw new IOException(var5.getCause());
}
} catch (IllegalAccessException var6) {
throw new AssertionError("Could not access parse method in " + protoClass);
}
}
static Method getStaticProtobufMethod(Class<?> declaredClass, String method, Class... args) {
try {
return declaredClass.getMethod(method, args);
} catch (Exception var4) {
throw new AssertionError("Protocol buffer class " + declaredClass + " does not have an accessible parseFrom(InputStream) method!");
}
}
NullInstance
private static class NullInstance extends Configured implements Writable {
private Class<?> declaredClass;
public NullInstance() {
super((Configuration)null);
}
public NullInstance(Class declaredClass, Configuration conf) {
super(conf);
this.declaredClass = declaredClass;
}
public void readFields(DataInput in) throws IOException {
String className = UTF8.readString(in);
this.declaredClass = (Class)ObjectWritable.PRIMITIVE_NAMES.get(className);
if(this.declaredClass == null) {
try {
this.declaredClass = this.getConf().getClassByName(className);
} catch (ClassNotFoundException var4) {
throw new RuntimeException(var4.toString());
}
}
}
public void write(DataOutput out) throws IOException {
UTF8.writeString(out, this.declaredClass.getName());
}
}