How to beautify java code reliably

jeremiec

jeremiec

Posted on February 7, 2024

How to beautify java code reliably

I recently had to set up code formatting on a spring boot java application. Auto code formatting is important to avoiding useless diffs in source files, reducing noise in code review, allowing reviewers to focus on what matters.

Ideally we want:

  • Automatic formatting on file save in IDE's (vscode, IntelliJ)
  • Capacity to run in CI

I wanted to integrate well with vscode and after trying some solution like:

  • java autoformat, which I couldn't run in CI and that was not really portable between IDEs
  • maven auto formatting plugin (didn't run on save easily in IDEs)

I ended up, from a friend suggestion, looking into a java prettier plugin. Prettier allowed for an easy integration with most Web IDE, can be configured to format on save for vscode and is trivial to run in CI.

Installing prettier for java

Let's start with the setup in command line:

{
  "name": "api",
  "version": "0.0.1",
  "private": true,
  "devDependencies": {
    "prettier": "2.5.1",
    "prettier-plugin-java": "1.6.1"
  },
  "engines": {
    "node": "16.x"
  },
  "scripts": {
    "format": "prettier --write \"{,**/}*.{java,yml,yaml,md,json}\"",
    "check-format": "prettier --check \"{,**/}*.{java,yml,yaml,md,json}\"",
    "lint": "npm run check-format"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Install the required node_module: npm install

šŸ’” Don't forget to add node_modules to your .gitignore.

šŸ’” I highly recommend adding a .prettierignore that list autogenerated files to avoid formatting those, eg:

node_modules
target
Enter fullscreen mode Exit fullscreen mode

You can now format java code running npm run format šŸš€

šŸ’” Do not forget to add node as a dependency for your project installation and to run npm ci in your project installation script for new developers.

We now want to improve developer experience by integrating with IDEs, running the formatter in CLI being impractical.

Monorepo

If you are using a monorepo, I highly recommend setting up prettier in the root of your monorepo instead of setting up prettier in each sub directory.

Integrating with IDEs

vscode

To set up prettier in vscode: add the prettier for java extension to recommended vscode extensions for the project, to do so, you can simply add the id of the extension to: .vscode/extensions.json:

{
  "recommendations": [
    "pivotal.vscode-boot-dev-pack",
    "vscjava.vscode-java-pack",
    "redhat.vscode-xml",
    "sonarsource.sonarlint-vscode",
    "gabrielbb.vscode-lombok",
    "dbaeumer.vscode-eslint",
+   "esbenp.prettier-vscode", // the classic prettier extension
    "shengchen.vscode-checkstyle",
  ]
}
Enter fullscreen mode Exit fullscreen mode

then set up this extension as the default linter for java file in .vscode/settings.json :

{
// rest of your configuration
// automatic format on save, I recommend the save on focus lost option as well
+   "editor.formatOnSave": true,
+   "[java]": {
+       "editor.defaultFormatter": "esbenp.prettier-vscode"
+   }
}
Enter fullscreen mode Exit fullscreen mode

Already we can easily format java code on save:
Formatting java code on save

I highly recommend checking in the .vscode folder in your versioning tool (most likely git) to share this configuration with all developers.

IntelliJ

To integrate with prettier java formatter:

Name: Prettier-java
File type: Java
Program:  full path to `.bin/prettier` eg: `node_modules/.bin/prettier`
Arguments: --write $FilePathRelativeToProjectRoot$
Output paths to refresh: $FilePathRelativeToProjectRoot
Auto-save edited files to trigger the watcher: check it
Trigger the watcher on external changes: check it
Enter fullscreen mode Exit fullscreen mode

prettier documentation can be found here for IntelliJ integration

Integrate code formatting check in CI

Now we only need to integrate this check in CI, I'm using gitlab for this example, but the principles can be transposed to any other CI.

First we need to add a new job:

stages:
  - build
  - test
  - deploy

# ... rest of the file

# beautify backend files with prettier
lint-back:
  image: node:lts-alpine # We use a node image to run prettier
  stage: test # must match an existing stage
  needs: [] # none required optimization that explain to gitlab ci that this test has no dependency and can start as soon as possible
  script:
    - npm ci
    - npm run lint
# ... rest of the file
Enter fullscreen mode Exit fullscreen mode

now just push your change, and you are all set:

CI running lint successfully

šŸ’– šŸ’Ŗ šŸ™… šŸš©
jeremiec
jeremiec

Posted on February 7, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related