Protobuf serialization for pre-existing objects with runtime schema generation and polymorphic type handling
npx @tessl/cli install tessl/maven-io-protostuff--protostuff-runtime@1.8.00
# Protostuff Runtime
1
2
Protostuff Runtime provides runtime schema generation and serialization capabilities for protocol buffers in Java, enabling efficient serialization of pre-existing Java objects without requiring compile-time code generation. It offers dynamic schema creation at runtime, automatic field mapping and validation, support for complex object hierarchies including inheritance and polymorphism, and pluggable serialization formats.
3
4
## Package Information
5
6
- **Package Name**: io.protostuff:protostuff-runtime
7
- **Package Type**: Maven
8
- **Language**: Java
9
- **Installation**: Add to your Maven dependencies:
10
11
```xml
12
<dependency>
13
<groupId>io.protostuff</groupId>
14
<artifactId>protostuff-runtime</artifactId>
15
<version>1.8.0</version>
16
</dependency>
17
```
18
19
## Core Imports
20
21
```java
22
import io.protostuff.runtime.RuntimeSchema;
23
import io.protostuff.runtime.DefaultIdStrategy;
24
import io.protostuff.runtime.RuntimeEnv;
25
import io.protostuff.runtime.IdStrategy;
26
import io.protostuff.runtime.Delegate;
27
import io.protostuff.Tag;
28
import io.protostuff.Exclude;
29
import io.protostuff.Schema;
30
```
31
32
## Basic Usage
33
34
```java
35
import io.protostuff.runtime.RuntimeSchema;
36
import io.protostuff.Schema;
37
import io.protostuff.Tag;
38
import io.protostuff.Exclude;
39
40
// Create and use a schema for your class with annotations
41
public class User {
42
@Tag(1)
43
public String name;
44
45
@Tag(2)
46
public int age;
47
48
@Tag(3)
49
public boolean active;
50
51
@Exclude // This field will not be serialized
52
public String password;
53
}
54
55
// Get schema for the User class
56
Schema<User> schema = RuntimeSchema.getSchema(User.class);
57
58
// Register schema for better performance (optional)
59
RuntimeSchema.register(User.class);
60
61
// Create and populate user object
62
User user = new User();
63
user.name = "Alice";
64
user.age = 25;
65
user.active = true;
66
user.password = "secret"; // Will be ignored during serialization
67
68
// The schema can now be used with any protostuff serialization format
69
// (requires protostuff-core dependency for actual serialization)
70
// Example: byte[] data = ProtostuffIOUtil.toByteArray(user, schema, buffer);
71
```
72
73
## Architecture
74
75
Protostuff Runtime is built around several key components:
76
77
- **Schema Generation**: `RuntimeSchema` creates schemas dynamically at runtime by introspecting Java classes
78
- **Type Strategy**: `IdStrategy` and `DefaultIdStrategy` handle polymorphic type identification and serialization
79
- **Field Access**: Efficient field access and mapping through `Field`, `FieldMap`, and `Accessor` abstractions
80
- **Custom Serialization**: `Delegate` system allows custom serialization for specific types
81
- **Runtime Environment**: `RuntimeEnv` provides configuration and optimization settings
82
- **Polymorphic Support**: Comprehensive handling of inheritance, collections, and complex object hierarchies via polymorphic schemas
83
- **Annotation Support**: `@Tag`, `@Exclude`, and `@Morph` annotations for field-level configuration
84
- **Object Instantiation**: Optimized object creation through `Instantiator` implementations
85
86
## Capabilities
87
88
### Schema Generation and Management
89
90
Core functionality for creating, registering, and managing runtime schemas for Java classes. Essential for all serialization operations.
91
92
```java { .api }
93
// Main schema operations
94
public static <T> Schema<T> getSchema(Class<T> typeClass);
95
public static <T> Schema<T> getSchema(Class<T> typeClass, IdStrategy strategy);
96
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass);
97
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, IdStrategy strategy);
98
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, String[] exclusions, IdStrategy strategy);
99
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, Set<String> exclusions, IdStrategy strategy);
100
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, Map<String, String> declaredFields, IdStrategy strategy);
101
102
// Registration for performance optimization
103
public static <T> boolean register(Class<T> typeClass);
104
public static <T> boolean register(Class<T> typeClass, Schema<T> schema);
105
public static <T> boolean map(Class<? super T> baseClass, Class<T> typeClass);
106
public static boolean isRegistered(Class<?> typeClass);
107
public static boolean isRegistered(Class<?> typeClass, IdStrategy strategy);
108
109
// Schema constants
110
public static final int MIN_TAG_VALUE = 1;
111
public static final int MAX_TAG_VALUE = 536870911;
112
```
113
114
[Schema Generation](./schema-generation.md)
115
116
### Type Strategy and Polymorphic Handling
117
118
Advanced type identification and polymorphic serialization strategies for handling inheritance hierarchies, collections, and complex object structures.
119
120
```java { .api }
121
// IdStrategy base functionality
122
public abstract boolean isDelegateRegistered(Class<?> typeClass);
123
public abstract <T> HasDelegate<T> getDelegateWrapper(Class<? super T> typeClass);
124
public abstract <T> Delegate<T> getDelegate(Class<? super T> typeClass);
125
public abstract boolean isRegistered(Class<?> typeClass);
126
public abstract <T> HasSchema<T> getSchemaWrapper(Class<T> typeClass, boolean create);
127
128
// DefaultIdStrategy implementation
129
public <T> boolean registerPojo(Class<T> typeClass);
130
public <T> boolean registerPojo(Class<T> typeClass, Schema<T> schema);
131
public <T extends Enum<T>> boolean registerEnum(Class<T> enumClass);
132
public <T> boolean registerDelegate(Delegate<T> delegate);
133
```
134
135
[Type Strategy](./type-strategy.md)
136
137
### Custom Serialization and Delegates
138
139
System for implementing custom serialization logic for specific types, providing higher priority than default serializers.
140
141
```java { .api }
142
// Delegate interface
143
public interface Delegate<V> {
144
FieldType getFieldType();
145
V readFrom(Input input) throws IOException;
146
void writeTo(Output output, int number, V value, boolean repeated) throws IOException;
147
void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException;
148
Class<?> typeClass();
149
}
150
151
// HasDelegate wrapper
152
public Delegate<T> getDelegate();
153
```
154
155
[Custom Serialization](./custom-serialization.md)
156
157
### Runtime Environment and Configuration
158
159
Environment configuration, optimization settings, and utility classes for controlling runtime behavior and performance characteristics.
160
161
```java { .api }
162
// Runtime environment constants and settings
163
public static final boolean ENUMS_BY_NAME;
164
public static final boolean AUTO_LOAD_POLYMORPHIC_CLASSES;
165
public static final boolean PRESERVE_NULL_ELEMENTS;
166
public static final boolean USE_SUN_MISC_UNSAFE;
167
public static final IdStrategy ID_STRATEGY;
168
169
// Object instantiation utilities
170
public static <T> Instantiator<T> newInstantiator(Class<T> clazz);
171
172
// Instantiator interface
173
public abstract class Instantiator<T> {
174
public abstract T newInstance();
175
}
176
```
177
178
[Runtime Environment](./runtime-environment.md)
179
180
### Field Access and Optimization
181
182
Low-level field access optimization and reflection utilities for high-performance field operations.
183
184
```java { .api }
185
// Field access abstraction
186
public abstract class Field<T> {
187
public final WireFormat.FieldType type;
188
public final int number;
189
public final String name;
190
public final boolean repeated;
191
public final int groupFilter;
192
}
193
194
// Field value accessor for optimization
195
public abstract class Accessor {
196
public abstract void set(Object owner, Object value);
197
public abstract <T> T get(Object owner);
198
}
199
```
200
201
[Field Access](./field-access.md)
202
203
### Polymorphic Schema Factories
204
205
Factory system for creating polymorphic schemas that handle inheritance, collections, and complex object hierarchies.
206
207
```java { .api }
208
// Polymorphic schema factory enum
209
public enum PolymorphicSchemaFactories implements PolymorphicSchema.Factory {
210
ARRAY, NUMBER, CLASS, ENUM, COLLECTION, MAP, THROWABLE, POJO, POJO_MAP, POJO_COLLECTION, OBJECT;
211
}
212
213
// Factory methods for polymorphic handling
214
public static PolymorphicSchema.Factory getFactoryFromField(java.lang.reflect.Field f, IdStrategy strategy);
215
public static PolymorphicSchema getSchemaFromCollectionOrMapGenericType(Class<?> clazz, IdStrategy strategy);
216
```
217
218
[Polymorphic Schemas](./polymorphic-schemas.md)
219
220
### Annotation-Based Configuration
221
222
Field-level configuration annotations for controlling serialization behavior, field numbers, and exclusions.
223
224
```java { .api }
225
// Tag annotation for field number assignment
226
@Target(ElementType.FIELD)
227
public @interface Tag {
228
int value();
229
String alias() default "";
230
int groupFilter() default 0;
231
}
232
233
// Exclude annotation for skipping fields
234
@Target(ElementType.FIELD)
235
public @interface Exclude {
236
}
237
238
// Morph annotation for polymorphic behavior
239
@Target({ElementType.FIELD, ElementType.TYPE})
240
public @interface Morph {
241
boolean value() default true;
242
}
243
```
244
245
[Annotations](./annotations.md)
246
247
## Error Handling
248
249
Protostuff Runtime may throw the following exceptions:
250
251
- `IllegalArgumentException` - Invalid field numbers, null class parameters, or invalid configuration
252
- `IdStrategy.UnknownTypeException` - Unknown polymorphic types when using strict type strategies
253
- `RuntimeException` - General runtime errors during schema generation or field access
254
- `IOException` - I/O errors during serialization/deserialization operations (when used with serialization libraries)
255
256
## Type Definitions
257
258
```java { .api }
259
// Core schema interface (implemented by RuntimeSchema)
260
public interface Schema<T> {
261
String messageName();
262
String messageFullName();
263
Class<T> typeClass();
264
T newMessage();
265
boolean isInitialized(T message);
266
void mergeFrom(Input input, T message) throws IOException;
267
void writeTo(Output output, T message) throws IOException;
268
String getFieldName(int number);
269
int getFieldNumber(String name);
270
}
271
272
// Field map interface for schema field access
273
public interface FieldMap<T> {
274
Field<T> getFieldByNumber(int n);
275
Field<T> getFieldByName(String fieldName);
276
int getFieldCount();
277
List<Field<T>> getFields();
278
}
279
280
// Field representation
281
public abstract class Field<T> {
282
public final WireFormat.FieldType type;
283
public final int number;
284
public final String name;
285
public final boolean repeated;
286
public final int groupFilter;
287
288
protected abstract void writeTo(Output output, T message) throws IOException;
289
protected abstract void mergeFrom(Input input, T message) throws IOException;
290
}
291
292
// Schema wrapper for polymorphic contexts
293
public abstract class HasSchema<T> {
294
public abstract Schema<T> getSchema();
295
public abstract Pipe.Schema<T> getPipeSchema();
296
}
297
298
// Delegate wrapper for polymorphic contexts
299
public class HasDelegate<T> {
300
public Delegate<T> getDelegate();
301
}
302
303
// RuntimeSchema class extends Schema and implements FieldMap
304
public class RuntimeSchema<T> implements Schema<T>, FieldMap<T> {
305
public final Instantiator<T> instantiator;
306
307
// Constructors
308
public RuntimeSchema(Class<T> typeClass, Collection<Field<T>> fields, Constructor<T> constructor);
309
public RuntimeSchema(Class<T> typeClass, Collection<Field<T>> fields, Instantiator<T> instantiator);
310
311
// Schema interface methods
312
public Pipe.Schema<T> getPipeSchema();
313
}
314
315
// IdStrategy configuration flags
316
public abstract class IdStrategy {
317
public static final int ENUMS_BY_NAME = 1;
318
public static final int AUTO_LOAD_POLYMORPHIC_CLASSES = 2;
319
public static final int PRESERVE_NULL_ELEMENTS = 4;
320
public static final int MORPH_NON_FINAL_POJOS = 8;
321
public static final int MORPH_COLLECTION_INTERFACES = 16;
322
public static final int MORPH_MAP_INTERFACES = 32;
323
public static final int COLLECTION_SCHEMA_ON_REPEATED_FIELDS = 64;
324
public static final int POJO_SCHEMA_ON_COLLECTION_FIELDS = 128;
325
public static final int POJO_SCHEMA_ON_MAP_FIELDS = 256;
326
public static final int DEFAULT_FLAGS;
327
}
328
```