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.