Library for manually creating Java serialization data.

Overview

⚠️ This library is currently experimental, its behavior and API might change in the future.


serial-builder

Library for creating Java serialization data; mainly intended for research purposes. It is not recommended to use it in production as alternative for ObjectOutputStream.

Compared to using Java's ObjectOutputStream this library has the following advantages:

  • It is not necessary to have the target classes on the classpath; it is possible to refer to classes only by their name.
  • It is possible to write arbitrary field values without having to access the internals of the target class with reflection.
  • It is possible to omit data or add additional serialization data which would normally not be written.

The entrypoints of this library are the classes SerialBuilder and SimpleSerialBuilder. The API structure of SerialBuilder is pretty close to the actual serialization data format. This allows low level creation of serialization data, at the cost of verbose usage and reduced error checking. SimpleSerialBuilder operates on a higher level, which makes its usage more concise and less error-prone. In most cases the API offered by SimpleSerialBuilder should suffice.

The API offered by this library uses a 'fluent builder style', where all methods calls are chained after each other (with indentation to increase readability) until the end of the chain is reached, and the resulting serialization data in the form of byte[] is returned. Using the API in any other way is not supported and might cause exceptions. It is recommended to follow the IDE code completion suggestions while using the API, looking at the builder API interfaces is most likely not that helpful.

Usage examples (SimpleSerialBuilder)

Class hierarchy

Let's assume you have these two classes:

class ClassA implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    public String a;
}

class ClassB extends ClassA {
    @Serial
    private static final long serialVersionUID = 1L;

    public String b;
}

To create serialization data for an instance of ClassB, you can use the API in the following way:

byte[] serialData = SimpleSerialBuilder.startSerializableObject()
    // Start at the superclass
    .beginClassData(ClassA.class)
        .beginObjectField("a", String.class)
            .string("value-a")
        .endField()
    .endClassData()
    .beginClassData(ClassB.class)
        .beginObjectField("b", String.class)
            .string("value-b")
        .endField()
    .endClassData()
.endObject();

writeObject method

Let's assume you have the following class with writeObject and readObject methods:

class ClassWithWriteObject implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    public int i;
    public String s;

    public transient int i2;
    public transient String s2;

    @Serial
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();

        out.writeInt(i2);
        out.writeObject(s2);
    }

    @Serial
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();

        i2 = in.readInt();
        s2 = (String) in.readObject();
    }
}

To create serialization data for it, you can use the API in the following way:

{ writer.writeInt(2); writer.string("manually-written"); }) .endClassData() .endObject();">
byte[] serialData = SimpleSerialBuilder.startSerializableObject()
    .beginClassData(ClassWithWriteObject.class)
        // Represents the data written by the `defaultWriteObject()` call
        .primitiveField("i", 1)
        .beginObjectField("s", String.class)
            .string("test")
        .endField()
        // Represents the data manually written by `writeObject`
        .writeObjectWith(writer -> {
            writer.writeInt(2);
            writer.string("manually-written");
        })
    .endClassData()
.endObject();

Proxy instances

Let's assume you have the following java.lang.reflect.InvocationHandler implementation:

class CustomInvocationHandler implements InvocationHandler, Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    public String result;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        return result;
    }
}

To create serialization data for a java.lang.reflect.Proxy instance which uses an instance of that invocation handler, you can use the API in the following way:

// Starts a Proxy object which implements the Callable interface
byte[] serialData = SimpleSerialBuilder.startProxyObject(Callable.class)
    .beginSerializableInvocationHandler()
        .beginClassData(CustomInvocationHandler.class)
            .beginObjectField("result", String.class)
                .string("custom-result")
            .endField()
        .endClassData()
    .endObject()
.endProxyObject();

Handles

The serialization protocol supports handles which refer to a previously written instance. This API supports this feature through the Handle class. First you create a new (unassigned) Handle, then you pass it to one of the builder methods with Handle parameter and afterwards you can use it to refer to the previously written object.

This library does not support using Handle in all cases where the serialization protocol supports it, but all interesting cases should be covered (if you are missing support for a use case, feel free to create a GitHub issue).

Let's assume you have the following class:

class Container implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    public Serializable element;
}

To create serialization data for an instance of this class which contains itself, you can use the API in the following way:

// First create a new unassigned handle
Handle selfHandle = new Handle();
// Then pass the handle here as argument to assign the written object to it
byte[] serialData = SimpleSerialBuilder.startSerializableObject(selfHandle)
    .beginClassData(Container.class)
        .beginObjectField("element", Serializable.class)
            // Finally, write a reference to the previously written object
            .objectHandle(selfHandle)
        .endField()
    .endClassData()
.endObject();

Similar / related projects

License

This project uses the MIT license; all contributions are implicitly under that license.

You might also like...

A Java library for serializing objects as PHP serialization format.

Java PHP Serializer Latest release: A Java library for serializing objects as PHP serialization format. The library fully implements the PHP serializa

Jun 13, 2022

Java serialization library, proto compiler, code generator

Java serialization library, proto compiler, code generator

A java serialization library with built-in support for forward-backward compatibility (schema evolution) and validation. efficient, both in speed and

Dec 23, 2022

Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Ribbon Ribbon is a client side IPC library that is battle-tested in cloud. It provides the following features Load balancing Fault tolerance Multiple

Jan 1, 2023

Screaming fast JSON parsing and serialization library for Android.

Screaming fast JSON parsing and serialization library for Android.

#LoganSquare The fastest JSON parsing and serializing library available for Android. Based on Jackson's streaming API, LoganSquare is able to consiste

Dec 18, 2022

FlatBuffers: Memory Efficient Serialization Library

FlatBuffers FlatBuffers is a cross platform serialization library architected for maximum memory efficiency. It allows you to directly access serializ

Dec 31, 2022

Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Ribbon Ribbon is a client side IPC library that is battle-tested in cloud. It provides the following features Load balancing Fault tolerance Multiple

Jan 4, 2023

A distributed data integration framework that simplifies common aspects of big data integration such as data ingestion, replication, organization and lifecycle management for both streaming and batch data ecosystems.

Apache Gobblin Apache Gobblin is a highly scalable data management solution for structured and byte-oriented data in heterogeneous data ecosystems. Ca

Jan 4, 2023

A scientific charting library focused on performance optimised real-time data visualisation at 25 Hz update rates for data sets with a few 10 thousand up to 5 million data points.

A scientific charting library focused on performance optimised real-time data visualisation at 25 Hz update rates for data sets with a few 10 thousand up to 5 million data points.

ChartFx ChartFx is a scientific charting library developed at GSI for FAIR with focus on performance optimised real-time data visualisation at 25 Hz u

Jan 2, 2023

A scientific charting library focused on performance optimised real-time data visualisation at 25 Hz update rates for data sets with a few 10 thousand up to 5 million data points.

A scientific charting library focused on performance optimised real-time data visualisation at 25 Hz update rates for data sets with a few 10 thousand up to 5 million data points.

ChartFx ChartFx is a scientific charting library developed at GSI for FAIR with focus on performance optimised real-time data visualisation at 25 Hz u

Dec 30, 2022

FST: fast java serialization drop in-replacement

FST: fast java serialization drop in-replacement

fast-serialization up to 10 times faster 100% JDK Serialization compatible drop-in replacement (Ok, might be 99% ..). As an example: Lambda Serializat

Dec 15, 2022

Java binary serialization and cloning: fast, efficient, automatic

Java binary serialization and cloning: fast, efficient, automatic

Kryo is a fast and efficient binary object graph serialization framework for Java. The goals of the project are high speed, low size, and an easy to u

Jan 5, 2023

Flash cards app using JavaFX, Scene Builder and persistence using Serialization with JAVA IO API

Flash cards app using JavaFX, Scene Builder and persistence using Serialization with JAVA IO API

Flashcards - JavaFX , Scene Builder, Serialized Persistence JAVA IO API Main Scene that will show all the Decks in Flash Card App Add or Edit Cards in

Nov 28, 2022

binary serialization format

Colfer Colfer is a binary serialization format optimized for speed and size. The project's compiler colf(1) generates source code from schema definiti

Dec 25, 2022

Framework for serialization to Json, XML, Byte and Excel, therefore an oviparous wool milk sow J

Framework for serialization to Json, XML, Byte and Excel, therefore an oviparous wool milk sow J

NetworkParser Framework for serialization from Java objects to Json, XML and Byte. NetworkParser is a simple framework for serializing complex model s

Nov 18, 2020

An examples of creating test records in the database with Spring Boot + Spring Data + JPA usage.

Spring Boot + JPA — Clear Tests An examples of creating test records in the database with Spring Boot + Spring Data + JPA usage. Check out the article

Nov 24, 2022

Simplifies the development of creating a JPA-based data access layer.

Spring Data JPA Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals wi

Jan 5, 2023

A library for creating interactive console applications in Java

A library for creating interactive console applications in Java

Text-IO Text-IO is a library for creating Java console applications. It can be used in applications that need to read interactive input from the user.

Jan 5, 2023

Java library for creating text-based GUIs

Java library for creating text-based GUIs

Lanterna Lanterna is a Java library allowing you to write easy semi-graphical user interfaces in a text-only environment, very similar to the C librar

Dec 31, 2022

An annotation-based Java library for creating Thrift serializable types and services.

Drift Drift is an easy-to-use, annotation-based Java library for creating Thrift clients and serializable types. The client library is similar to JAX-

Dec 24, 2022
Comments
  • Non-fluent builder API

    Non-fluent builder API

    Currently the builder only provides a fluent API. While this has some advantages it also have some disadvantages:

    • Bad IDE support:
      • Auto-formatting would remove proper indentation
      • Easy to make indentation mistakes, no help from the IDE
      • IDE type hints can make code very verbose (and possibly also decrease IDE reaction speed)
    • More difficult to break creation appart into separate steps

    Therefore it might be useful to also offer a non-fluent builder API, for example similar to this:

    byte[] serialData = serializableObject(
        classData(
            SerializableClass.class,
            List.of(
                intField("i", 6),
                objectField(
                    "array",
                    int[].class,
                    array(new int[] {1, 2, 3})
                ),
                objectField(
                    "s",
                    String.class,
                    string("nested-test")
                )
            )
        )
    ).createSerialData();
    

    This could be realized in a rather user friendly way by exposing these static factory methods all on one class for which the user can then use a wildcard import (e.g. import static marcono1234...FactoryMethods.*;).

    As part of this, it might be reasonable to rename the existing builders (and their packages) to:

    • SerialBuilder: FluentSerialBuilder / LowLevelFluentSerialBuilder (possibly a bit too verbose)
    • SimpleSerialBuilder: SimpleFluentSerialBuilder (too verbose?) / FluentSerialBuilder

    The new builder API could be for now mostly be implemented on top of the existing fluent API. But eventually, especially for handle support, it might be easier to implement the fluent API on top of that new API. That would however also require a low level non-fluent API.

    enhancement 
    opened by Marcono1234 0
Owner
null
FlatBuffers: Memory Efficient Serialization Library

FlatBuffers FlatBuffers is a cross platform serialization library architected for maximum memory efficiency. It allows you to directly access serializ

Google 19.6k Dec 31, 2022
FST: fast java serialization drop in-replacement

fast-serialization up to 10 times faster 100% JDK Serialization compatible drop-in replacement (Ok, might be 99% ..). As an example: Lambda Serializat

moru0011 1.5k Dec 15, 2022
Java binary serialization and cloning: fast, efficient, automatic

Kryo is a fast and efficient binary object graph serialization framework for Java. The goals of the project are high speed, low size, and an easy to u

Esoteric Software 5.7k Jan 5, 2023
MessagePack serializer implementation for Java / msgpack.org[Java]

MessagePack for Java MessagePack is a binary serialization format. If you need a fast and compact alternative of JSON, MessagePack is your friend. For

MessagePack 1.3k Dec 31, 2022
this project is a checker for virus's and token loggers in java apps

Rat checker this project is a checker for virus's and token loggers in java apps this project is not finished and when it is it will never be perfect.

max! 40 Sep 30, 2021
Konas Client de-obfuscated and manually remaped by Gopro336, Perry, and other based people

Konas-Deobf-Remap This project doesent really have a purpose anymore now that the real source code has leaked (this is a higher version tho) Deobfusca

null 52 Dec 13, 2022
Konas Client de-obfuscated and manually remaped by Gopro336, Perry, and other based people

Konas-Deobf-Remap This project doesent really have a purpose anymore now that the real source code has leaked (this is a higher version tho) Deobfusca

null 52 Dec 13, 2022
A Java serialization/deserialization library to convert Java Objects into JSON and back

Gson Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to a

Google 21.7k Jan 8, 2023
A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back

A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back, with a transparent support of any kind of self-references and with a full Java 9 compatibility.

Andrey Mogilev 9 Dec 30, 2021