Skip to content

Commit

Permalink
make FieldSerializer.serializeTransient usable
Browse files Browse the repository at this point in the history
  • Loading branch information
greg.lee committed Apr 6, 2016
1 parent d7feda9 commit 8aae38d
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/com/esotericsoftware/kryo/serializers/FieldSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ public class FieldSerializer<T> extends Serializer<T> implements Comparator<Fiel
* </p> */
private boolean useMemRegions = false;

/** If set, transient fields will be serialized */
private final boolean serializeTransient = false;

private boolean hasObjectFields = false;

static CachedFieldFactory asmFieldFactory;
Expand Down Expand Up @@ -457,6 +454,11 @@ public void setCopyTransient (boolean setCopyTransient) {
config.setCopyTransient(setCopyTransient);
}

// Enable/disable serialization of transient fields
public void setSerializeTransient (boolean setSerializeTransient) {
config.setSerializeTransient(setSerializeTransient);
}

/** This method can be called for different fields having the same type. Even though the raw type is the same, if the type is
* generic, it could happen that different concrete classes are used to instantiate it. Therefore, in case of different
* instantiation parameters, the fields analysis should be repeated.
Expand All @@ -481,7 +483,7 @@ public void write (Kryo kryo, Output output, T object) {
fields[i].write(output, object);

// Serialize transient fields
if (serializeTransient) {
if (config.isSerializeTransient()) {
for (int i = 0, n = transientFields.length; i < n; i++)
transientFields[i].write(output, object);
}
Expand Down Expand Up @@ -514,7 +516,7 @@ public T read (Kryo kryo, Input input, Class<T> type) {
fields[i].read(input, object);

// De-serialize transient fields
if (serializeTransient) {
if (config.isSerializeTransient()) {
for (int i = 0, n = transientFields.length; i < n; i++)
transientFields[i].read(input, object);
}
Expand Down Expand Up @@ -602,6 +604,12 @@ public CachedField[] getFields () {
return fields;
}

/** Get all transient fields controlled by this FieldSerializer
* @return all transient fields controlled by this FieldSerializer */
public CachedField[] getTransientFields () {
return transientFields;
}

public Class getType () {
return type;
}
Expand All @@ -621,6 +629,10 @@ public boolean getUseMemRegions () {
public boolean getCopyTransient () {
return config.isCopyTransient();
}

public boolean getSerializeTransient() {
return config.isSerializeTransient();
}

/** Used by {@link #copy(Kryo, Object)} to create the new object. This can be overridden to customize object creation, eg to
* call a constructor with arguments. The default implementation uses {@link Kryo#newInstance(Class)}. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public final class FieldSerializerConfig implements Cloneable {
private boolean useAsm;
/** If set, transient fields will be copied */
private boolean copyTransient = true;
/** If set, transient fields will be serialized */
private boolean serializeTransient = false;

{
useAsm = !FieldSerializer.unsafeAvailable;
Expand Down Expand Up @@ -98,6 +100,15 @@ public void setCopyTransient (boolean setCopyTransient) {
copyTransient = setCopyTransient;
}

/**
* If set, transient fields will be serialized
* Default is false
* @param serializeTransient
*/
public void setSerializeTransient(boolean serializeTransient) {
this.serializeTransient = serializeTransient;
}

public boolean isFieldsCanBeNull() {
return fieldsCanBeNull;
}
Expand All @@ -121,4 +132,8 @@ public boolean isUseAsm() {
public boolean isCopyTransient() {
return copyTransient;
}

public boolean isSerializeTransient() {
return serializeTransient;
}
}
80 changes: 80 additions & 0 deletions test/com/esotericsoftware/kryo/FieldSerializerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package com.esotericsoftware.kryo;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -479,6 +480,85 @@ public void testTransientsUsingGlobalConfig () {
assertEquals("Objects should be equal if copy includes transient fields", objectWithTransients2, objectWithTransients1);
}

public void testSerializeTransients () {
kryo.register(HasTransients.class);
HasTransients objectWithTransients1 = new HasTransients();
objectWithTransients1.transientField1 = "Test";
objectWithTransients1.anotherField2 = 5;
objectWithTransients1.anotherField3 = "Field2";

ByteArrayOutputStream outputStream;
Output output;
Input input;
byte[] outBytes;

FieldSerializer<HasTransients> ser = (FieldSerializer<HasTransients>)kryo.getSerializer(HasTransients.class);
ser.setSerializeTransient(false);

outputStream = new ByteArrayOutputStream();
output = new Output(outputStream);
ser.write(kryo, output, objectWithTransients1);
output.flush();

outBytes = outputStream.toByteArray();
input = new Input(outBytes);
HasTransients objectWithTransients3 = ser.read(kryo, input, HasTransients.class);
assertTrue("Objects should be different if write does not include transient fields",
!objectWithTransients3.equals(objectWithTransients1));
assertEquals("transient fields should be null", objectWithTransients3.transientField1, null);

ser.setSerializeTransient(true);

outputStream = new ByteArrayOutputStream();
output = new Output(outputStream);
ser.write(kryo, output, objectWithTransients1);
output.flush();

outBytes = outputStream.toByteArray();
input = new Input(outBytes);
HasTransients objectWithTransients2 = ser.read(kryo, input, HasTransients.class);
assertTrue("Objects should be equal if write includes transient fields", objectWithTransients2.equals(objectWithTransients1));
}

public void testSerializeTransientsUsingGlobalConfig () {
kryo.getFieldSerializerConfig().setSerializeTransient(false);
kryo.register(HasTransients.class);
HasTransients objectWithTransients1 = new HasTransients();
objectWithTransients1.transientField1 = "Test";
objectWithTransients1.anotherField2 = 5;
objectWithTransients1.anotherField3 = "Field2";

ByteArrayOutputStream outputStream;
Output output;
Input input;
byte[] outBytes;

FieldSerializer<HasTransients> ser = (FieldSerializer<HasTransients>)kryo.getSerializer(HasTransients.class);
outputStream = new ByteArrayOutputStream();
output = new Output(outputStream);
ser.write(kryo, output, objectWithTransients1);
output.flush();

outBytes = outputStream.toByteArray();
input = new Input(outBytes);
HasTransients objectWithTransients3 = ser.read(kryo, input, HasTransients.class);
assertTrue("Objects should be different if write does not include transient fields",
!objectWithTransients3.equals(objectWithTransients1));
assertEquals("transient fields should be null", objectWithTransients3.transientField1, null);

ser.setSerializeTransient(true);

outputStream = new ByteArrayOutputStream();
output = new Output(outputStream);
ser.write(kryo, output, objectWithTransients1);
output.flush();

outBytes = outputStream.toByteArray();
input = new Input(outBytes);
HasTransients objectWithTransients2 = ser.read(kryo, input, HasTransients.class);
assertTrue("Objects should be equal if write includes transient fields", objectWithTransients2.equals(objectWithTransients1));
}

public void testCorrectlyAnnotatedFields () {
kryo.register(int[].class);
kryo.register(long[].class);
Expand Down

0 comments on commit 8aae38d

Please sign in to comment.