SkillAgentSearch skills...

Jackdaw

Java Annotation Processor which allows to simplify development

Install / Use

/learn @vbauer/Jackdaw
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Jackdaw Android Arsenal Build Status Maven

<img align="right" style="margin-left: 15px" width="300" height="243" src="jackdaw-misc/jackdaw.png" />

Jackdaw is a Java Annotation Processor which allows to simplify Java/Android development and prevents writing of tedious code.

Jackdaw was inspired by Lombok project, but in comparison with Lombok:

  • it does not need to have an extra plugin in IDE
  • it does not modify the existing source code

Features

Jackdaw supports the following compile time annotations:

<ul> <li><a href="#jadapter">@JAdapter</a></li> <li><a href="#jbean">@JBean</a></li> <li><a href="#jbuilder">@JBuilder</a></li> <li><a href="#jclassdescriptor">@JClassDescriptor</a></li> <li><a href="#jcomparator">@JComparator</a></li> <li><a href="#jfactorymethod">@JFactoryMethod</a></li> <li><a href="#jfunction">@JFunction</a></li> <li><a href="#jignore">@JIgnore</a></li> <li><a href="#jmessage">@JMessage</a></li> <li><a href="#jpredicate">@JPredicate</a></li> <li><a href="#jrepeatable">@JRepeatable</a></li> <li><a href="#jservice">@JService</a></li> <li><a href="#jsupplier">@JSupplier</a></li> </ul>

Setup

Jackdaw uses JitPack.io for distribution, so you need to configure JitPack's Maven repository to fetch artifacts (dependencies).

It is necessary to make dependency on jackdaw-core. This module contains compile time annotations which will be used to give a hints for APT. Module jackdaw-apt contains annotation processor and all correlated logic.

Maven

Repositories section:

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Dependencies section:

<dependencies>
    <dependency>
        <groupId>com.github.vbauer.jackdaw</groupId>
        <artifactId>jackdaw-core</artifactId>
        <version>${jackdaw.version}</version>
    </dependency>
</dependencies>

After that, you need to configure maven-compiler-plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <forceJavacCompilerUse>true</forceJavacCompilerUse>
                <annotationProcessorPaths>
                    <annotationProcessorPath>
                        <groupId>com.github.vbauer.jackdaw</groupId>
                        <artifactId>jackdaw-apt</artifactId>
                        <version>${jackdaw.version}</version>
                    </annotationProcessorPath>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

Gradle

Add custom repository:

repositories {
    mavenCentral()
    maven {
        url 'https://jitpack.io'
    }
}

Add provided scope to prevent jackdaw-apt:

configurations {
    provided
}

sourceSets {
    main.compileClasspath += configurations.provided
    test.compileClasspath += configurations.provided
    test.runtimeClasspath += configurations.provided
}

Specify needed dependencies:

dependencies {
    compile 'com.github.vbauer.jackdaw:jackdaw-core:1.0.9'
    provided 'com.github.vbauer.jackdaw:jackdaw-apt:1.0.9'
}

Configuration

Available parameters for annotation processor:

  • addSuppressWarningsAnnotation - Add @SuppressWarnings("all") annotation on all generated classes to prevent unnecessary issues of IDE inspections (default value is true).
  • addGeneratedAnnotation - Add @Generated annotation on all generated classes to have possibility skip execution of static code analysis (default value is true).
  • addGeneratedDate - Add date parameter to @Generated annotation. It is also necessary to switch on addGeneratedAnnotation parameter (default value is false).

Example configuration for maven-compiler-plugin:

<configuration>
    <compilerArgs>
        <arg>-AaddGeneratedAnnotation=true</arg>
        <arg>-AaddGeneratedDate=true</arg>
        <arg>-AaddSuppressWarningsAnnotation=false</arg>
    </compilerArgs>
</configuration>

Annotations

Some things that you need to know before exploring an examples:

  • Code style in the below examples was changed to minimize text in README.
  • Some annotations and imports were also removed to simplify understanding.
  • All generated classes will have the same package as original classes.

@JAdapter

@JAdapter allows to create class with empty method implementations using some interface or class. Using generated class, you can override only needed methods (like in Swing, ex: MouseAdapter).

Original class MouseListener:

@JAdapter
public interface MouseListener {
    void onMove(int x, int y);
    void onPressed(int button);
}

Generated class MouseListenerAdapter:

public class MouseListenerAdapter implements MouseListener {
    public void onMove(final int x, final int y) {
    }
    public void onPresses(final int button) {
    }
}

@JBean

@JBean generates some boilerplate code that is normally associated with simple POJOs (Plain Old Java Objects) and beans:

  • getters for all non-static/private fields,
  • setters for all non-static/private/final fields,
  • and copy constructors from super class

Original class AbstractUserModel:

@JBean
public abstract class AbstractUserModel {
    protected int id;
    protected String username;
    protected String password;
    protected boolean admin;
}

Generated class User:

public class User extends AbstractUserModel {
    public User() { super(); }

    public void setId(final int id) { this.id = id; }
    public void getId() { return id; }
    
    public String getUsername() { return username; }
    public void setUsername(final String username) { this.username = username; }
    
    public String getPassword() { return password; }
    public void setPassword(final String password) { this.password = password; }
    
    public boolean isAdmin() { return admin; }
    public void setAdmin(final boolean admin) { this.admin = admin; }
}

Prefix 'Abstract' and postfix 'Model' will be removed if they are presented.

@JBuilder

The @JBuilder annotation produces complex builder APIs for your classes.

Original class Company:

@JBuilder
public class Company {
    private int id;
    private String name;
    private Set<String> descriptions;

    public int getId() { return id; }
    public void setId(final int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(final String name) { this.name = name; }

    public Set<String> getDescriptions() { return descriptions; }
    public void setDescriptions(final Set<String> descriptions) { this.descriptions = descriptions; }
}

Generated class CompanyBuilder:

public class CompanyBuilder {
    private int id;
    private String name;
    private Set<String> descriptions;

    public static CompanyBuilder create() {
        return new CompanyBuilder();
    }
    public CompanyBuilder id(final int id) {
        this.id = id;
        return this;
    }
    public CompanyBuilder name(final String name) {
        this.name = name;
        return this;
    }
    public CompanyBuilder descriptions(final Set<String> descriptions) {
        this.descriptions = descriptions;
        return this;
    }
    public Company build() {
        final Company object = new Company();
        object.setId(id);
        object.setName(name);
        object.setListed(listed);
        object.setDescriptions(descriptions);
        return object;
    }
}

@JBuilder lets you automatically produce the code required to have your class be instantiable with code such as:

CompanyBuilder.create()
    .id(1)
    .name("John Smith")
    .descriptions(Collections.singleton("Good guy"))
    .build()

@JClassDescriptor

Sometimes it is necessary to use reflection, so it will be useful to have some string constants. @JClassDescriptor generates it for you easily.

Available parameters:

  • fields - generate information about fields (default is true).
  • methods - generate information about methods (default is true).

Original class Company:

@JClassDescriptor
public class Company {
    private int id;
    private String name;

    public int getId() { return id; }
    public void setId(final int id) { this.id = id; }

    public String getName() { return name; }
    public void setName(final String name) { this.name = name; }
}

Generated class CompanyClassDescriptor:

public final class CompanyClassDescriptor {
    public static final String FIELD_ID = "id";
    public static final String FIELD_NAME = "name";

    public static final String METHOD_ID = "getId";
    public static final String METHOD_SET_ID = "setId";
    public static final String METHOD_NAME = "getName";
    public static final String METHOD_SET_NAME = "setName";

    private CompanyClassDescriptor() {
        throw new UnsupportedOperationException();
    }
}

@JComparator

To generated safe and well-coded comparator, you have to write a lot of boilerplate code. @JComparator annotation allows to simplify this situation. To generate reverse order comparator, use parameter reverse.

Related Skills

View on GitHub
GitHub Stars318
CategoryDevelopment
Updated1mo ago
Forks34

Languages

Java

Security Score

100/100

Audited on Feb 12, 2026

No findings