-
Notifications
You must be signed in to change notification settings - Fork 70
Generate code
When sensible, prefer to generate rather than write code. Here's why:
- Intelligent laziness is a virtue.
- Tools always work, unless they have bugs, and you can fix bugs. Programmers make typos, and fixing typos is a challenge when not obvious. Worse are _ thinkos_; code generation does not " think", so is immune to this problem.
- Generated code does not need code review, only the source input for generation needs review, and this is usually shorter and easier to understand. Only your hand-written code needs review.
- Generated code is usually ignored by tooling such as linting or code coverage (and there are simple workarounds when this is not the case). Your hand-written code needs tooling to shift problems left.
Note that many features for which in Java one would use code generation
(eg, Lombok's @Getter
or @ToString
), can be
built-in language features in other languages such as Kotlin or Scala (eg,
properties
or data classes).
Lombok is by far the most popular tool in Java for code generation. Lombok is an annotation processor, that is, a library (jar) which cooperates with the Java compiler. (An introductory guide to annotations and annotation processors is a good article if you'd like to read more on how annotation processing works.)
Lombok covers many common use cases, does not have runtime dependencies, there are plugins for popular IDEs that understand Lombok's code generation, and has tooling integration for JaCoCo's output code coverage (see below).
Do note though, Lombok is not a panacea, and has detractors. For example, to generate code as an annotation processor, it in places relies on internal JDK APIs, though the situation has improved as the JDK exposes those APIs in portable ways.
Be sparing in disabling code coverage!
JaCoCo knows about Lombok's
@Generated
, and will
ignore annotated code.
A typical use is for the main()
method in a framework such as Spring Boot
or Micronaut.
For a command-line program, you will want to test your main()
.
Do note that Lombok reflects on internal features of the JDK.
If you have issues, for Maven: use in your project the
--add-opens java.base/java.lang=ALL-UNNAMED
example from .mvn/jvm.config
, and look to address these.
The solutions in the project are a "workaround" assuming Java 21.
This is a two-edged sword: as the JVM improves access controls, you may find,
especially dependencies, that there are times you want deep reflection.
Configure Lombok in
src/lombok.config
rather than the project root or a
separate config
directory.
At a minimum:
config.stopBubbling=true
lombok.addLombokGeneratedAnnotation=true
lombok.anyConstructor.addConstructorProperties=true
lombok.extern.findbugs.addSuppressFBWarnings=true
Lines:
-
stopBubbling
tells Lombok that there are no more configuration files higher in the directory tree. -
addLombokGeneratedAnnotation
helps JaCoCo ignore code generated by Lombok. -
addConstructorProperties
helps JSON/XML frameworks such as Jackson (this may not be relevant for your project, but is generally harmless, so the benefit comes for free). -
addSuppressFBWarnings
helps SpotBugs ignore code generated by Lombok.
- Automating
Dockerfile
— YMNNALFT: Easy Docker Image Creation with the Spring Boot Maven Plugin and Buildpacks (NB — you do not need to have a Spring Boot project to use the plugin: just treat the plugin as a "regular" one)
TODO: Placeholder section
TODO: Placeholder section
See the code repo for working examples.
This work is dedicated/deeded to the public following laws in jurisdictions
for such purpose.
The principal authors are:
You can always use the "Pages" UI control above this sidebar ☝ to navigate around all pages alphabetically (even pages not in this sidebar), to navigate the outline for each page, or for a search box.
Here is the suggested reading order: