0
# Runtime Environment and Configuration
1
2
Environment configuration, optimization settings, and utility classes for controlling runtime behavior and performance characteristics. The `RuntimeEnv` class provides access to system-wide configuration options and utility methods for object instantiation.
3
4
## Capabilities
5
6
### Runtime Environment Constants
7
8
Global configuration constants that control default behavior across the protostuff-runtime library.
9
10
```java { .api }
11
/**
12
* Java version detection - true if running on Java 9 or higher
13
*/
14
public static final boolean JAVA_9_AND_ABOVE;
15
16
/**
17
* Default enum serialization mode - true to serialize by name, false by ordinal
18
*/
19
public static final boolean ENUMS_BY_NAME;
20
21
/**
22
* Auto-load polymorphic classes when encountered during deserialization
23
*/
24
public static final boolean AUTO_LOAD_POLYMORPHIC_CLASSES;
25
26
/**
27
* Preserve null elements in collections and arrays
28
*/
29
public static final boolean PRESERVE_NULL_ELEMENTS;
30
31
/**
32
* Enable morphing for non-final POJO types in polymorphic scenarios
33
*/
34
public static final boolean MORPH_NON_FINAL_POJOS;
35
36
/**
37
* Enable morphing for collection interfaces (List, Set, Queue, etc.)
38
*/
39
public static final boolean MORPH_COLLECTION_INTERFACES;
40
41
/**
42
* Enable morphing for map interfaces
43
*/
44
public static final boolean MORPH_MAP_INTERFACES;
45
46
/**
47
* Use collection schema on repeated fields instead of simple repeated values
48
*/
49
public static final boolean COLLECTION_SCHEMA_ON_REPEATED_FIELDS;
50
51
/**
52
* Use POJO schema on collection fields for complex object handling
53
*/
54
public static final boolean POJO_SCHEMA_ON_COLLECTION_FIELDS;
55
56
/**
57
* Use POJO schema on map fields for complex object handling
58
*/
59
public static final boolean POJO_SCHEMA_ON_MAP_FIELDS;
60
61
/**
62
* Enable sun.misc.Unsafe usage for performance optimizations
63
*/
64
public static final boolean USE_SUN_MISC_UNSAFE;
65
66
/**
67
* Always use sun.reflect.ReflectionFactory for object instantiation
68
*/
69
public static final boolean ALWAYS_USE_SUN_REFLECTION_FACTORY;
70
71
/**
72
* Never use sun.reflect.ReflectionFactory for object instantiation
73
*/
74
public static final boolean NEVER_USE_SUN_REFLECTION_FACTORY;
75
76
/**
77
* Default ID strategy instance used throughout the library
78
*/
79
public static final IdStrategy ID_STRATEGY;
80
```
81
82
### Object Instantiation
83
84
Utility methods for creating optimized object instantiators that can bypass constructors when needed.
85
86
```java { .api }
87
/**
88
* Create an instantiator for the specified class
89
* The instantiator will use the most efficient method available:
90
* - Constructor with no arguments if available
91
* - sun.reflect.ReflectionFactory if enabled and available
92
* - Unsafe allocation if enabled and available
93
*
94
* @param clazz The class to create instantiator for
95
* @return Instantiator instance for the class
96
*/
97
public static <T> Instantiator<T> newInstantiator(Class<T> clazz);
98
```
99
100
### Instantiator Abstract Class
101
102
Abstract base class for object instantiation with performance optimizations.
103
104
```java { .api }
105
/**
106
* Abstract base class for optimized object instantiation
107
*/
108
public abstract static class Instantiator<T> {
109
110
/**
111
* Create a new instance of the target class
112
* Implementation uses the most efficient instantiation method available
113
*
114
* @return New instance of T
115
*/
116
public abstract T newInstance();
117
}
118
```
119
120
## Usage Examples
121
122
### Basic Environment Configuration
123
124
```java
125
import io.protostuff.runtime.RuntimeEnv;
126
import io.protostuff.runtime.RuntimeSchema;
127
import io.protostuff.Schema;
128
129
// Check environment capabilities
130
if (RuntimeEnv.JAVA_9_AND_ABOVE) {
131
System.out.println("Running on Java 9+");
132
}
133
134
if (RuntimeEnv.USE_SUN_MISC_UNSAFE) {
135
System.out.println("Unsafe optimizations enabled");
136
}
137
138
// Use default ID strategy
139
Schema<User> schema = RuntimeSchema.getSchema(User.class, RuntimeEnv.ID_STRATEGY);
140
```
141
142
### Custom Object Instantiation
143
144
```java
145
// Create instantiator for performance-critical paths
146
RuntimeEnv.Instantiator<User> userInstantiator = RuntimeEnv.newInstantiator(User.class);
147
148
// Use instantiator in performance-critical code
149
public User createUser() {
150
User user = userInstantiator.newInstance();
151
// Initialize user fields as needed
152
return user;
153
}
154
155
// Create instantiators for multiple types
156
RuntimeEnv.Instantiator<Order> orderInstantiator = RuntimeEnv.newInstantiator(Order.class);
157
RuntimeEnv.Instantiator<Product> productInstantiator = RuntimeEnv.newInstantiator(Product.class);
158
```
159
160
### Configuration-Aware Code
161
162
```java
163
/**
164
* Service that adapts behavior based on runtime configuration
165
*/
166
public class SerializationService {
167
168
private final IdStrategy strategy;
169
170
public SerializationService() {
171
// Use different strategies based on configuration
172
if (RuntimeEnv.PRESERVE_NULL_ELEMENTS && RuntimeEnv.ENUMS_BY_NAME) {
173
int flags = IdStrategy.PRESERVE_NULL_ELEMENTS | IdStrategy.ENUMS_BY_NAME;
174
this.strategy = new DefaultIdStrategy(flags);
175
} else {
176
this.strategy = RuntimeEnv.ID_STRATEGY;
177
}
178
}
179
180
public <T> Schema<T> getSchema(Class<T> clazz) {
181
return RuntimeSchema.getSchema(clazz, strategy);
182
}
183
184
public boolean supportsComplexCollections() {
185
return RuntimeEnv.COLLECTION_SCHEMA_ON_REPEATED_FIELDS;
186
}
187
188
public boolean supportsUnsafeOptimizations() {
189
return RuntimeEnv.USE_SUN_MISC_UNSAFE;
190
}
191
}
192
```
193
194
## System Property Configuration
195
196
The runtime environment reads configuration from system properties. You can override defaults by setting these properties:
197
198
### Core Behavior Properties
199
200
```java
201
// Set via system properties or JVM arguments
202
203
// Enum serialization: -Dprotostuff.runtime.enums_by_name=true
204
System.setProperty("protostuff.runtime.enums_by_name", "true");
205
206
// Auto-load classes: -Dprotostuff.runtime.auto_load_polymorphic_classes=true
207
System.setProperty("protostuff.runtime.auto_load_polymorphic_classes", "true");
208
209
// Preserve nulls: -Dprotostuff.runtime.preserve_null_elements=true
210
System.setProperty("protostuff.runtime.preserve_null_elements", "true");
211
212
// Morphing options
213
System.setProperty("protostuff.runtime.morph_non_final_pojos", "true");
214
System.setProperty("protostuff.runtime.morph_collection_interfaces", "true");
215
System.setProperty("protostuff.runtime.morph_map_interfaces", "true");
216
217
// Schema options
218
System.setProperty("protostuff.runtime.collection_schema_on_repeated_fields", "true");
219
System.setProperty("protostuff.runtime.pojo_schema_on_collection_fields", "true");
220
System.setProperty("protostuff.runtime.pojo_schema_on_map_fields", "true");
221
```
222
223
### Performance Properties
224
225
```java
226
// Unsafe usage: -Dprotostuff.runtime.use_sun_misc_unsafe=false
227
System.setProperty("protostuff.runtime.use_sun_misc_unsafe", "false");
228
229
// Reflection factory control
230
System.setProperty("protostuff.runtime.always_use_sun_reflection_factory", "true");
231
System.setProperty("protostuff.runtime.never_use_sun_reflection_factory", "true");
232
233
// Field factory selection
234
System.setProperty("protostuff.runtime.use_reflection_field_factory", "true");
235
```
236
237
## Performance Optimization Patterns
238
239
### Instantiator Caching
240
241
```java
242
/**
243
* Factory with cached instantiators for better performance
244
*/
245
public class ObjectFactory {
246
247
private static final Map<Class<?>, RuntimeEnv.Instantiator<?>> INSTANTIATORS =
248
new ConcurrentHashMap<>();
249
250
@SuppressWarnings("unchecked")
251
public static <T> T newInstance(Class<T> clazz) {
252
RuntimeEnv.Instantiator<T> instantiator =
253
(RuntimeEnv.Instantiator<T>) INSTANTIATORS.computeIfAbsent(
254
clazz, RuntimeEnv::newInstantiator
255
);
256
return instantiator.newInstance();
257
}
258
259
// Pre-populate cache for known types
260
static {
261
preloadInstantiators(User.class, Order.class, Product.class);
262
}
263
264
private static void preloadInstantiators(Class<?>... classes) {
265
for (Class<?> clazz : classes) {
266
INSTANTIATORS.put(clazz, RuntimeEnv.newInstantiator(clazz));
267
}
268
}
269
}
270
```
271
272
### Environment-Aware Schema Factory
273
274
```java
275
/**
276
* Schema factory that creates optimized schemas based on environment
277
*/
278
public class OptimizedSchemaFactory {
279
280
private static final IdStrategy OPTIMIZED_STRATEGY;
281
282
static {
283
// Build strategy based on environment capabilities
284
int flags = 0;
285
286
if (RuntimeEnv.ENUMS_BY_NAME) {
287
flags |= IdStrategy.ENUMS_BY_NAME;
288
}
289
290
if (RuntimeEnv.PRESERVE_NULL_ELEMENTS) {
291
flags |= IdStrategy.PRESERVE_NULL_ELEMENTS;
292
}
293
294
if (RuntimeEnv.COLLECTION_SCHEMA_ON_REPEATED_FIELDS) {
295
flags |= IdStrategy.COLLECTION_SCHEMA_ON_REPEATED_FIELDS;
296
}
297
298
if (RuntimeEnv.POJO_SCHEMA_ON_COLLECTION_FIELDS) {
299
flags |= IdStrategy.POJO_SCHEMA_ON_COLLECTION_FIELDS;
300
}
301
302
OPTIMIZED_STRATEGY = new DefaultIdStrategy(flags);
303
}
304
305
public static <T> Schema<T> getOptimizedSchema(Class<T> clazz) {
306
return RuntimeSchema.getSchema(clazz, OPTIMIZED_STRATEGY);
307
}
308
309
public static IdStrategy getOptimizedStrategy() {
310
return OPTIMIZED_STRATEGY;
311
}
312
}
313
```
314
315
### Reflection Information
316
317
```java
318
/**
319
* Utility for checking reflection capabilities
320
*/
321
public class ReflectionCapabilities {
322
323
public static boolean hasUnsafeSupport() {
324
return RuntimeEnv.USE_SUN_MISC_UNSAFE;
325
}
326
327
public static boolean hasReflectionFactorySupport() {
328
return !RuntimeEnv.NEVER_USE_SUN_REFLECTION_FACTORY;
329
}
330
331
public static boolean isModernJava() {
332
return RuntimeEnv.JAVA_9_AND_ABOVE;
333
}
334
335
public static String getCapabilitiesReport() {
336
StringBuilder report = new StringBuilder();
337
report.append("Runtime Capabilities:\n");
338
report.append("- Java 9+: ").append(RuntimeEnv.JAVA_9_AND_ABOVE).append("\n");
339
report.append("- Unsafe: ").append(RuntimeEnv.USE_SUN_MISC_UNSAFE).append("\n");
340
report.append("- ReflectionFactory: ").append(!RuntimeEnv.NEVER_USE_SUN_REFLECTION_FACTORY).append("\n");
341
report.append("- Enums by name: ").append(RuntimeEnv.ENUMS_BY_NAME).append("\n");
342
report.append("- Preserve nulls: ").append(RuntimeEnv.PRESERVE_NULL_ELEMENTS).append("\n");
343
return report.toString();
344
}
345
}
346
```
347
348
## Configuration Best Practices
349
350
1. **System Properties**: Set configuration via system properties for application-wide consistency
351
2. **Environment Detection**: Use environment constants to adapt behavior at runtime
352
3. **Performance Settings**: Enable unsafe and reflection factory optimizations when possible
353
4. **Null Handling**: Configure null preservation based on your data requirements
354
5. **Enum Serialization**: Choose between name-based or ordinal-based enum serialization
355
6. **Instantiator Caching**: Cache instantiators for frequently created objects
356
7. **Strategy Selection**: Use environment-aware strategy creation for optimal performance
357
8. **Testing**: Test with different configurations to ensure compatibility across environments
358
359
## Thread Safety
360
361
All `RuntimeEnv` constants and methods are thread-safe:
362
363
- **Constants**: All static final fields are immutable and thread-safe
364
- **newInstantiator()**: Returns thread-safe instantiator instances
365
- **Instantiator.newInstance()**: All implementations are thread-safe
366
- **Configuration**: System property-based configuration is read once at class loading
367
368
The default `ID_STRATEGY` instance is also thread-safe and can be shared across threads.