CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-avro--avro

Apache Avro core components for data serialization with rich data structures, compact binary format, and schema evolution support

Pending
Overview
Eval results
Files

code-generation.mddocs/

Code Generation Support

Avro's code generation support provides integration with generated Java classes for type-safe, high-performance data operations. Specific operations work with POJOs generated from Avro schemas, offering compile-time type checking and optimized serialization performance.

Capabilities

Specific Data Utilities

Core utilities for working with generated Avro classes and their schemas.

public class SpecificData extends GenericData {
    public static SpecificData get();
    
    // Class and schema mapping
    public static Class<?> getClassName(Schema schema);
    public Schema getSchema(Class<?> c);
    public Schema getSchema(Object object);
    
    // Instance creation
    public Object newInstance(Class<?> c, Schema schema);
    public Object createFixed(Object old, Schema schema);
    public Object createRecord(Object old, Schema schema);
    public Object createEnum(String symbol, Schema schema);
    
    // Protocol support
    public Protocol getProtocol(Class<?> iface);
    
    // Conversion support
    public void addLogicalTypeConversion(Conversion<?> conversion);
    public Conversion<?> getConversionFor(LogicalType logicalType);
    public Collection<Conversion<?>> getConversions();
}

Usage Examples:

// Get SpecificData instance
SpecificData specificData = SpecificData.get();

// Get class name from schema
Schema userSchema = new Schema.Parser().parse(userSchemaJson);
Class<?> userClass = SpecificData.getClassName(userSchema);
System.out.println("Generated class: " + userClass.getName());

// Get schema from generated class
Schema schemaFromClass = specificData.getSchema(User.class);
System.out.println("Schema from class: " + schemaFromClass.getName());

// Create instance of generated class
User user = (User) specificData.newInstance(User.class, userSchema);
user.setName("Alice");
user.setAge(25);

// Work with protocols for RPC
Protocol userServiceProtocol = specificData.getProtocol(UserService.class);
System.out.println("Protocol: " + userServiceProtocol.getName());

Specific Record Interface

Base interface that all generated record classes implement.

public interface SpecificRecord extends IndexedRecord {
    Schema getSchema();
    
    // Specific record methods are typically generated
    // For example, for a User schema:
    // String getName();
    // void setName(String name);
    // Integer getAge();
    // void setAge(Integer age);
}

Usage Examples:

// Using generated record class (example)
public class User implements SpecificRecord {
    private static final Schema SCHEMA$ = new Schema.Parser().parse(SCHEMA_JSON);
    
    private String name;
    private Integer age;
    private String email;
    
    public User() {}
    
    public User(String name, Integer age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    @Override
    public Schema getSchema() {
        return SCHEMA$;
    }
    
    // Generated getters and setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    // IndexedRecord implementation
    @Override
    public Object get(int field) {
        switch (field) {
            case 0: return name;
            case 1: return age;
            case 2: return email;
            default: throw new IndexOutOfBoundsException();
        }
    }
    
    @Override
    public void put(int field, Object value) {
        switch (field) {
            case 0: name = (String) value; break;
            case 1: age = (Integer) value; break;
            case 2: email = (String) value; break;
            default: throw new IndexOutOfBoundsException();
        }
    }
}

// Use generated class
User user = new User("Bob", 30, "bob@example.com");
Schema userSchema = user.getSchema();
System.out.println("User: " + user.getName() + ", Age: " + user.getAge());

Specific Datum Reader

DatumReader optimized for generated classes with compile-time type safety.

public class SpecificDatumReader<T> extends GenericDatumReader<T> {
    public SpecificDatumReader();
    public SpecificDatumReader(Schema schema);
    public SpecificDatumReader(Schema writer, Schema reader);
    public SpecificDatumReader(Class<T> c);
    public SpecificDatumReader(Class<T> c, Schema writer, Schema reader);
    
    // Inherited from GenericDatumReader
    public void setSchema(Schema schema);
    public void setExpected(Schema reader);
    public T read(T reuse, Decoder in) throws IOException;
}

Usage Examples:

// Read generated objects from binary data
SpecificDatumReader<User> reader = new SpecificDatumReader<>(User.class);

InputStream inputStream = new FileInputStream("users.avro");
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(inputStream, null);

// Read specific records with type safety
User user1 = reader.read(null, decoder);
System.out.println("User name: " + user1.getName());

// Reuse objects for better performance
User reusedUser = null;
while (hasMoreData(decoder)) {
    reusedUser = reader.read(reusedUser, decoder);
    processUser(reusedUser);
}

// Schema evolution with generated classes
Schema writerSchema = getWriterSchema();
Schema readerSchema = User.SCHEMA$;
SpecificDatumReader<User> evolvingReader = 
    new SpecificDatumReader<>(User.class, writerSchema, readerSchema);

User evolvedUser = evolvingReader.read(null, decoder);

Specific Datum Writer

DatumWriter optimized for generated classes with compile-time type safety.

public class SpecificDatumWriter<T> extends GenericDatumWriter<T> {
    public SpecificDatumWriter();
    public SpecificDatumWriter(Schema schema);
    public SpecificDatumWriter(Class<T> c);
    
    // Inherited from GenericDatumWriter
    public void setSchema(Schema schema);
    public void write(T datum, Encoder out) throws IOException;
}

Usage Examples:

// Write generated objects to binary format
SpecificDatumWriter<User> writer = new SpecificDatumWriter<>(User.class);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outputStream, null);

// Write specific records with type safety
User user = new User("Charlie", 35, "charlie@example.com");
writer.write(user, encoder);
encoder.flush();

// Write multiple users
List<User> users = Arrays.asList(
    new User("Alice", 25, "alice@example.com"),
    new User("Bob", 30, "bob@example.com"),
    new User("Carol", 28, "carol@example.com")
);

for (User u : users) {
    writer.write(u, encoder);
}
encoder.flush();

byte[] serializedData = outputStream.toByteArray();

Generated Class Annotations

Annotations used to mark and configure generated Avro classes.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvroGenerated {
    // Marks classes as Avro-generated
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FixedSize {
    int value();
}

Usage Examples:

// Generated record with annotations
@AvroGenerated
public class User implements SpecificRecord {
    // Implementation generated by Avro compiler
}

// Generated fixed class with size annotation
@AvroGenerated
@FixedSize(16)
public class MD5Hash implements SpecificFixed {
    private static final Schema SCHEMA$ = Schema.createFixed("MD5Hash", null, null, 16);
    private byte[] bytes = new byte[16];
    
    @Override
    public Schema getSchema() {
        return SCHEMA$;
    }
    
    @Override
    public byte[] bytes() {
        return bytes;
    }
}

// Check if class is Avro-generated
if (User.class.isAnnotationPresent(AvroGenerated.class)) {
    System.out.println("User class is Avro-generated");
}

// Get fixed size from annotation
if (MD5Hash.class.isAnnotationPresent(FixedSize.class)) {
    FixedSize annotation = MD5Hash.class.getAnnotation(FixedSize.class);
    System.out.println("Fixed size: " + annotation.value());
}

Builder Pattern Support

Generated classes often include builder patterns for convenient object construction.

// Example of generated builder (varies by schema)
public static class Builder {
    // Builder methods generated based on schema fields
    public Builder setName(String name);
    public Builder setAge(Integer age);  
    public Builder setEmail(String email);
    
    public User build();
    public Builder clear();
    
    // Field checking
    public boolean hasName();
    public boolean hasAge();
    public boolean hasEmail();
}

Usage Examples:

// Using generated builder (example pattern)
User user = User.newBuilder()
    .setName("David")
    .setAge(40)
    .setEmail("david@example.com")
    .build();

// Build with partial data
User partialUser = User.newBuilder()
    .setName("Eve")
    .build(); // Age and email will use defaults or be null

// Check what fields are set
User.Builder builder = User.newBuilder();
builder.setName("Frank");

if (builder.hasName()) {
    System.out.println("Name is set");
}
if (!builder.hasEmail()) {
    System.out.println("Email is not set");
}

User finalUser = builder.build();

Specific Error Handling

Error classes generated from schema error types implement SpecificRecord.

// Generated error class example
@AvroGenerated
public class UserNotFoundException extends Exception implements SpecificRecord {
    private static final Schema SCHEMA$ = parseSchema(ERROR_SCHEMA_JSON);
    
    private String userId;
    private String message;
    
    public UserNotFoundException() {}
    
    public UserNotFoundException(String userId, String message) {
        super(message);
        this.userId = userId;
        this.message = message;
    }
    
    @Override
    public Schema getSchema() {
        return SCHEMA$;
    }
    
    // Generated getters/setters
    public String getUserId() { return userId; }
    public void setUserId(String userId) { this.userId = userId; }
    
    @Override
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
}

Usage Examples:

// Throw generated error
public User findUser(String userId) throws UserNotFoundException {
    User user = userRepository.find(userId);
    if (user == null) {
        throw new UserNotFoundException(userId, "User not found: " + userId);
    }
    return user;
}

// Catch and handle generated error
try {
    User user = findUser("unknown123");
} catch (UserNotFoundException e) {
    System.err.println("Failed to find user: " + e.getUserId());
    System.err.println("Error message: " + e.getMessage());
    
    // Error also implements SpecificRecord
    Schema errorSchema = e.getSchema();
    System.out.println("Error schema: " + errorSchema.getName());
}

Types

public class SpecificData extends GenericData {
    // Utilities for generated classes
}

public interface SpecificRecord extends IndexedRecord {
    Schema getSchema();
}

public interface SpecificFixed extends GenericFixed {
    // Marker interface for generated fixed classes
}

public class SpecificDatumReader<T> extends GenericDatumReader<T> {
    // Type-safe reader for generated classes
}

public class SpecificDatumWriter<T> extends GenericDatumWriter<T> {
    // Type-safe writer for generated classes
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AvroGenerated {
    // Annotation for generated classes
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FixedSize {
    int value();
}

// Generated class interfaces (examples based on common patterns)
public interface Builder<T> {
    T build();
    Builder<T> clear();
}

public abstract class SpecificRecordBase implements SpecificRecord {
    // Base class for generated records (implementation detail)
}

public abstract class SpecificExceptionBase extends Exception implements SpecificRecord {
    // Base class for generated exceptions
}

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-avro--avro

docs

code-generation.md

encoding-decoding.md

file-operations.md

generic-data.md

index.md

message-operations.md

reflection-operations.md

schema-evolution.md

schema-system.md

tile.json