New versions: Dev (3.15) | Latest (3.14) | 3.13

jOOQ Refaster

Applies to ✅ Open Source Edition   ✅ Express Edition   ✅ Professional Edition   ✅ Enterprise Edition

In addition to static API usage validation through the Checker Framework or Error Prone, starting from jOOQ 3.13, we are adding experimental support for automatic API migration using Refaster, a sub project of Error Prone. This works through a Java compiler plugin emitting a patch file with suggested replacements which then can be applied to the source base to perform the jOOQ API migration.

Provided Refaster Templates

In an initial version, jOOQ provides the following .refaster files with sets of Refaster templates:

To use either of the two sets of Refaster templates, you first need to download the linked file above (or locate it in the downloaded jOOQ ZIP distribution) and then configure Refaster as described in the next section.

Configuring Refaster

In order to apply the Refaster templates, the Error Prone Java compiler plugin must be configured in your project's Maven pom.xml file. For a Java 8 project the required configuration looks as follows:

<properties>
  <javac.version>9+181-r4173-1</javac.version>
</properties>
<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <fork>true</fork>
        <compilerArgs>
          <arg>-XDcompilePolicy=simple</arg>
          <arg>-Xplugin:ErrorProne -XepPatchChecks:refaster:/full/path/to/deprecation-3.13.5.refaster 
               -XepPatchLocation:${basedir}</arg>
          <arg>-J-Xbootclasspath/p:${settings.localRepository}/com/google/errorprone/javac/${javac.version}/javac-${javac.version}.jar</arg>
        </compilerArgs>
        <annotationProcessorPaths>
          <path>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_refaster</artifactId>
            <version>2.3.4</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>

For Java 11+ a custom Error Prone build from https://jitpack.io/ (kindly provided by Picnic Technologies) is required, as the latest official Error Prone Refaster builds don't yet support Java 11+.

<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>
<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <release>11</release>
        <source>11</source>
        <target>11</target>
        <fork>true</fork>
        <compilerArgs>
          <arg>-XDcompilePolicy=simple</arg>
          <arg>-Xplugin:ErrorProne -XepPatchChecks:refaster:/full/path/to/deprecation-3.13.5.refaster 
               -XepPatchLocation:${basedir}</arg>
        </compilerArgs>
        <annotationProcessorPaths>
          <path>
            <groupId>com.github.PicnicSupermarket.error-prone</groupId>
            <artifactId>error_prone_refaster</artifactId>
            <version>v2.3.4-picnic-2</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>

Using Refaster

With Refaster configured as described above, the next step is to compile the code using Maven as usual (e.g. using mvn compile). The Refaster plugin will then check the code against the templates in the configured .refaster file and for any detected matches it will append a suggested replacement as a patch hunk to an error-prone.patch unified diff patch file, which is written to the configured directory (see -XepPatchLocation parameter).

The patch file can now be applied using patch -p0 -u -i error-prone.patch or a corresponding feature in the IDE.

Caveats

  • Refaster currently doesn't provide any @SuppressWarnings-like mechanism to suppress replacements from being suggested for a given piece of code.
  • You may have to repeat the process of recompiling the sources and applying the patches multiple times, as Refaster is not always able to suggest multiple replacements per expression / statement. The recommendation is thus to repeat the process until no patch file is produced anymore.
  • In some cases it is possible that the code resulting from the patch application has compilation errors. This is by design, as the old jOOQ API typically relied on some implicit type conversion, which itself is the reason for the deprecation of the API. One example would be field.abs() where the type of field is not compatible with Field<Number>. In such cases the code has to be corrected manually (e.g. by changing DSL.abs(field) to DSL.abs(field.cast(BigDecimal.class))).
The jOOQ Logo