Generate version-agnostic Java wrappers from multiple protobuf schema versions.
Supports both Maven and Gradle build systems.
The Problem
When protobuf schemas evolve across versions, you face:
- Type mismatches:
int32in v1 becomesenumin v2 - Version-specific code: Different code paths for each version
- Maintenance burden: Changes ripple through the codebase
flowchart LR
subgraph without["Without Proto Wrapper"]
direction TB
V1["v1/*.proto"]
V2["v2/*.proto"]
S1["ServiceV1.java"]
S2["ServiceV2.java"]
V1 --> S1
V2 --> S2
end
Result: Duplicate code, version-specific logic, maintenance nightmare.
The Solution
Proto Wrapper generates a unified API that abstracts version differences:
flowchart LR
subgraph Input["Proto Files"]
V1["v1/*.proto"]
V2["v2/*.proto"]
end
subgraph Plugin["Proto Wrapper"]
PW[Generate]
end
subgraph Output["Generated Code"]
IF["Interface"]
I1["ImplV1"]
I2["ImplV2"]
end
subgraph App["Your Code"]
SVC["Service.java"]
end
V1 --> PW
V2 --> PW
PW --> IF
PW --> I1
PW --> I2
IF --> SVC
Usage:
// Works with v1, v2, or any future version Order order = ctx.wrapOrder(anyVersionProto); // Type conflicts handled automatically PaymentType type = order.getPaymentType(); // Auto-converted from int or enum long amount = order.getTotalAmount(); // Auto-widened from int32 or int64 // Serialize back to original version byte[] bytes = order.toBytes();
Quick Start
Maven
1. Add the plugin:
<plugin> <groupId>io.alnovis</groupId> <artifactId>proto-wrapper-maven-plugin</artifactId> <version>2.3.2</version> <configuration> <basePackage>com.example.model</basePackage> <protoRoot>${basedir}/proto</protoRoot> <versions> <version><protoDir>v1</protoDir></version> <version><protoDir>v2</protoDir></version> </versions> </configuration> <executions> <execution><goals><goal>generate</goal></goals></execution> </executions> </plugin>
2. Generate:
mvn generate-sources
Gradle
1. Apply the plugin:
plugins {
id("io.alnovis.proto-wrapper") version "2.3.2"
}
protoWrapper {
basePackage.set("com.example.model")
protoRoot.set(file("proto"))
versions {
version("v1")
version("v2")
}
}2. Generate:
./gradlew generateProtoWrapper
Features
| Feature | Description | Since |
|---|---|---|
| Multi-version support | Merge unlimited proto versions into unified API | v1.0 |
| Type conflict handling | Automatic conversion for int/enum, int/long, string/bytes | v1.0 |
| Builder pattern | Create and modify messages with fluent API | v1.1 |
| Well-known types | Convert Timestamp, Duration, wrappers to Java types | v1.3 |
| Oneof support | Full oneof field handling with conflict detection | v1.2 |
| Schema diff tool | Compare schemas, detect breaking changes | v1.5 |
| Incremental build | Skip unchanged protos, 50%+ faster rebuilds | v1.6.0 |
| Embedded protoc | Auto-download protoc, no manual installation needed | v1.6.5 |
| ProtoWrapper interface | Common base interface for type-safe proto access | v1.6.6 |
| Spring Boot Starter | Auto-configuration for Spring Boot applications | v1.6.7 |
| Java 8 compatibility | Generate Java 8 compatible code with targetJavaVersion=8 |
v1.6.8 |
| ProtocolVersions class | Centralized version constants with generateProtocolVersions=true |
v2.1.0 |
| Per-version proto syntax | Mixed proto2/proto3 projects with auto-detection | v2.2.0 |
| Field mappings | Explicit mapping for renumbered fields across versions | v2.2.0 |
| Renumber detection | Heuristic detection of field renumbering in diff tool | v2.2.0 |
| Validation annotations | Auto-generated @NotNull, @Valid on interface getters |
v2.3.0 |
| Schema metadata | Runtime access to enum values, field info, and version diffs | v2.3.1 |
| Default instance for messages | Unset message getters return empty wrapper (like protobuf) instead of null | v2.3.2 |
Type Conflict Handling
| Conflict | Example | Resolution |
|---|---|---|
| INT_ENUM | int32 ↔ enum |
Dual getters: getType() + getTypeEnum() |
| WIDENING | int32 → int64 |
Unified as wider type with range validation |
| STRING_BYTES | string ↔ bytes |
Dual getters: getText() + getTextBytes() |
| PRIMITIVE_MESSAGE | int32 → Money |
Dual getters with runtime support checks |
Documentation
| Document | Description |
|---|---|
| Getting Started | Step-by-step tutorial (15 min) |
| Configuration | All plugin options for Maven and Gradle |
| Spring Boot Starter | Integration with Spring Boot |
| Schema Metadata | Runtime access to enum values and version diffs |
| Cookbook | Practical examples and patterns |
| Contract Matrix | Field behavior reference (getter/has for all types) |
| Schema Diff | Compare schemas and detect breaking changes |
| Incremental Build | Build optimization details |
| Known Issues | Limitations and workarounds |
| Architecture | Internal design (for contributors) |
| API Reference | Generated code reference |
Examples
- Maven Example - Complete Maven project with tests
- Gradle Example - Complete Gradle project
- Spring Boot Example - Spring Boot integration
Generated Code Structure
target/generated-sources/proto-wrapper/
└── com/example/model/
├── api/
│ ├── Order.java # Interface
│ ├── PaymentType.java # Unified enum
│ ├── VersionContext.java # Version factory interface
│ ├── ProtocolVersions.java # Version constants (optional)
│ └── impl/
│ └── AbstractOrder.java # Template methods
├── metadata/ # Schema metadata (optional)
│ ├── SchemaInfoV1.java # V1 enum/message metadata
│ ├── SchemaInfoV2.java # V2 enum/message metadata
│ └── SchemaDiffV1ToV2.java # V1→V2 schema changes
├── v1/
│ ├── OrderV1.java # V1 implementation
│ └── VersionContextV1.java
└── v2/
├── OrderV2.java # V2 implementation
└── VersionContextV2.java
Requirements
- Java 17+
- Maven 3.8+ or Gradle 8.5+
No manual protoc installation required! The plugin automatically downloads the appropriate protoc binary from Maven Central if not found in PATH.
Installation
From Maven Central
Add dependency (plugins auto-download):
<dependency> <groupId>io.alnovis</groupId> <artifactId>proto-wrapper-core</artifactId> <version>2.3.2</version> </dependency>
From Source
git clone https://github.com/alnovis/proto-wrapper-plugin.git cd proto-wrapper-plugin mvn clean install # Maven modules ./gradlew publishToMavenLocal # Gradle plugin
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
Apache License 2.0 - see LICENSE for details.
See Also
- Changelog - Version history
- Roadmap - Planned features and releases
- Release Notes - Detailed release information
Acknowledgments
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications. YourKit is the creator of YourKit Java Profiler, YourKit .NET Profiler, and YourKit YouMonitor.