How to Generate Package Private Code with jOOQ’s Code Generator

Java’s package private visibility is an underrated feature. When you omit any visibility modifier in Java, then the default (for most objects) is package private, i.e. the object is visible only to types in the same package:

class YouDontSeeMe {}
class YouDontSeeMeEither {}

In fact, a compilation unit (the .java file) can contain multiple such classes. You don’t have to create a file per package private type. You could even put all of these types in your package-info.java file, it doesn’t matter.

When using jOOQ’s code generator, things are generated as public types per default, as you are likely going to use this generated code everywhere. You can still restrict access using Java 9’s module system if you want.

But occasionally, even with jOOQ generated code, package private visibility can be useful, if some data access package wants to hide its implementation details from other packages in the module.

Here’s an example code generation configuration to make this happen:

<configuration>
  <generator>
    <strategy>
      <name>com.example.codegen.SinglePackageStrategy</name>

      <!-- Generates all objects in the same package -->
      <!-- Starting from jOOQ 3.19, you can declare the strategy code here
           This will simplify your code generation setup. In older
           versions, just put the class in an auxiliary build module and
           add it as a dependency.
        -->
      <java><![CDATA[package com.example.codegen;

import org.jooq.codegen.DefaultGeneratorStrategy;
import org.jooq.codegen.GeneratorStrategy.Mode;
import org.jooq.meta.Definition;

public class SinglePackageStrategy extends DefaultGeneratorStrategy {
    @Override
    public String getJavaPackageName(Definition definition, Mode mode) {
        return getTargetPackage();
    }
}]]></java>
    </strategy>

    <generate>

      <!-- Removes the "public" visibility modifier everywhere -->
      <visibilityModifier>NONE</visibilityModifier>
    </generate>

    <target>
      <packageName>com.example</packageName>

      <!-- This may be important if generating code in src/main/java! 
           It will prevent cleaning the other package directory contents.
           Alternatively, use a separate target <directory/>
        -->
      <clean>false</clean>
    </target>
  </generator>
</configuration>

That wasn’t too hard? Using this approach, you can ensure that your jOOQ generated code never leaks into any client code that shouldn’t see jOOQ types.

2 thoughts on “How to Generate Package Private Code with jOOQ’s Code Generator

  1. Then, is it correct to assume that we can also use visibilityModifier with Kotlin Generator to use ‘internal’ scope ? This would be even more practical than java package private visibility, as we would not have to restrict generated code to a single package :-)

Leave a Reply