Permalink
Browse files

THRIFT-1038. java: Generated Java code for structures containing bina…

…ry fields (or collections thereof) are not serializable (in the Java sense) even though they implement java.io.Serializable

This patch causes Java Serialized Thrift structs to be serialized onto the stream via the Compact Protocol.

Patch: Mathias Herberts

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1063907 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 34c2dbd commit c8d533b65e8b87f41cdfa04a4a021021a0636f30 Bryan Duxbury committed Jan 26, 2011
@@ -100,6 +100,8 @@ class t_java_generator : public t_oop_generator {
void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
+ void generate_java_struct_write_object(std::ofstream& out, t_struct* tstruct);
+ void generate_java_struct_read_object(std::ofstream& out, t_struct* tstruct);
void generate_java_meta_data_map(std::ofstream& out, t_struct* tstruct);
void generate_field_value_meta_data(std::ofstream& out, t_type* type);
std::string get_java_type_string(t_type* type);
@@ -725,6 +727,14 @@ void t_java_generator::generate_java_union(t_struct* tstruct) {
f_struct << endl;
+ generate_java_struct_write_object(f_struct, tstruct);
+
+ f_struct << endl;
+
+ generate_java_struct_read_object(f_struct, tstruct);
+
+ f_struct << endl;
+
scope_down(f_struct);
f_struct.close();
@@ -1261,6 +1271,10 @@ void t_java_generator::generate_java_struct_definition(ofstream &out,
}
generate_java_struct_tostring(out, tstruct);
generate_java_validator(out, tstruct);
+
+ generate_java_struct_write_object(out, tstruct);
+ generate_java_struct_read_object(out, tstruct);
+
scope_down(out);
out << endl;
}
@@ -3957,6 +3971,32 @@ void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct*
indent(out) << "}" << endl << endl;
}
+// generates java method to serialize (in the Java sense) the object
+void t_java_generator::generate_java_struct_write_object(ofstream& out, t_struct* tstruct) {
+ indent(out) << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {" << endl;
+ indent(out) << " try {" << endl;
+ indent(out) << " write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));" << endl;
+ indent(out) << " } catch (org.apache.thrift.TException te) {" << endl;
+ indent(out) << " throw new java.io.IOException(te);" << endl;
+ indent(out) << " }" << endl;
+ indent(out) << "}" << endl << endl;
+}
+
+// generates java method to serialize (in the Java sense) the object
+void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct* tstruct) {
+ indent(out) << "private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {" << endl;
+ indent(out) << " try {" << endl;
+ if (!tstruct->is_union() && has_bit_vector(tstruct)) {
+ indent(out) << " // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor." << endl;
+ indent(out) << " __isset_bit_vector = new BitSet(1);" << endl;
+ }
+ indent(out) << " read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));" << endl;
+ indent(out) << " } catch (org.apache.thrift.TException te) {" << endl;
+ indent(out) << " throw new java.io.IOException(te);" << endl;
+ indent(out) << " }" << endl;
+ indent(out) << "}" << endl << endl;
+}
+
THRIFT_REGISTER_GENERATOR(java, "Java",
" beans: Members will be private, and setter methods will return void.\n"
" private-members: Members will be private, but setter methods will return 'this' like usual.\n"
@@ -18,6 +18,11 @@
*/
package org.apache.thrift;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -309,4 +314,22 @@ public void testBytesBufferFeatures() throws Exception {
o.setReq_bin((byte[])null);
assertNull(o.getReq_bin());
}
+
+ public void testJavaSerializable() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ OneOfEach ooe = Fixtures.oneOfEach;
+
+ // Serialize ooe the Java way...
+ oos.writeObject(ooe);
+ byte[] serialized = baos.toByteArray();
+
+ // Attempt to deserialize it
+ ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ OneOfEach ooe2 = (OneOfEach) ois.readObject();
+
+ assertEquals(ooe, ooe2);
+ }
}
@@ -18,6 +18,10 @@
*/
package org.apache.thrift;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
@@ -200,4 +204,22 @@ public void testToString() throws Exception {
String expectedString = "<ComparableUnion binary_field:01 02 03>";
assertEquals(expectedString, cu.toString());
}
+
+ public void testJavaSerializable() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ TestUnion tu = TestUnion.string_field("string");
+
+ // Serialize tu the Java way...
+ oos.writeObject(tu);
+ byte[] serialized = baos.toByteArray();
+
+ // Attempt to deserialize it
+ ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ TestUnion tu2 = (TestUnion) ois.readObject();
+
+ assertEquals(tu, tu2);
+ }
}

0 comments on commit c8d533b

Please sign in to comment.