Serializing Java objects using Golang's gob encoding
July 16, 2016
A while ago while working with Terraform, I started reading up on Go's RPC library, and the encoding format it uses by default, which is gob. Then I found out there was no Java implementation for it. Which is a shame, because there are a few Go programs that might be nice to interface with from the software we're building at work. However, at work we use Java.
So I started working on an implementation, called jgobs. If you can think of a better name, please let me know.. this one isn't very original. Anyway, I'm not even sure this is going to be useful to us, let alone anyone else, but hey, it's a nice exercise.
Last week jgobs was able to serialize a simple (primitive fields only) object to a byte array which was deserialized by Go's gob library. This morning jgobs succesfully serialized an object that contains nested objects, which I think is pretty cool, so time for a small demo!
What we'll do is serialize a simple Person
object that has a name and an Address
object
associated with it. Then we'll deserialize it using Go.
// Address.java
package xyz.vanduuren.jgobs.demo;
public class Address {
public String streetName;
public int houseNumber;
public String city;
}
// Person.java
package xyz.vanduuren.jgobs.demo;
public class Person {
public String name;
public Address address;
}
// App.java
package xyz.vanduuren.jgobs.demo;
import xyz.vanduuren.jgobs.lib.Encoder;
import java.io.FileOutputStream;
import java.io.IOException;
public class App
{
public static void main(String[] args) throws IOException {
// Encode to a file
FileOutputStream fileOutputStream = new FileOutputStream("/tmp/gob_person.data");
// Create the encoder with the file outputstream
Encoder encoder = new Encoder(fileOutputStream);
// Create the person and address objects we want to encode
Person person = new Person();
Address address = new Address();
// Give them some data
address.streetName = "Kerksteeg";
address.city = "Leiden";
address.houseNumber = 1;
person.name = "Jan Klaassen";
person.address = address;
// Encode, and close the stream
encoder.encode(person);
fileOutputStream.close();
}
}
Running the above program will result in a Person
named Jan Klaassen that will
be serialized to /tmp/gob_person.data
.
We should be able to decode that with a simple Go program. Let's try.
// decode.go
package main
import (
"encoding/gob"
"fmt"
"os"
)
func main() {
type Address struct {
StreetName string
HouseNumber int8
City string
}
type Person struct {
Name string
Address Address
}
f, err := os.Open("/tmp/gob_person.data")
if err != nil {
fmt.Printf("open: %v\n", err)
os.Exit(1)
}
dec := gob.NewDecoder(f)
var person Person
err = dec.Decode(&person)
if err != nil {
fmt.Printf("decode: %v\n", err)
os.Exit(1)
}
fmt.Printf("decoded person: %v\n", person)
}
Let's compile and run it.
$ go build decode.go && ./decode
decoded person: {Jan Klaassen {Kerksteeg 1 Leiden}}
And it worked! There's still a lot more stuff to do for the encoder, and then I need to start work on the decoder. But I thought this was already pretty cool! 😄