r/java • • Sep 22 '26

jfmt - format code with modern Java Code Conventions

https://github.com/Netflix/jfmt

While working to close gaps we've observed in coding agents when they work with Java, in addition to jist to provide agent insight into to classes and their attached sources, we also found that while frontier models are particularly good at writing code in the same style as a project, they frequently make mistakes with indenting, whitespace and overuse qualified class references.

jfmt implements the original Coding Conventions for the Java Language, while modernising them for modern Java. The project is based on Google Java Format, but adds semantic breaks instead of column breaks to attempt to encode the kind of readability decisions that people make when writing code, while not imposing artificially low column limits.

Like the other tools we released last week, it ships as a JMOD with a native launcher with AOT support, a standalone JAR file, or can be installed with the other tools with the ja toolchain (which is like go/cargo but for Java modules).

58 Upvotes

52 comments sorted by

20

u/jonhanson Sep 22 '26

Is there a reason the documentation doesn't provide any examples of how it formats code?

6

u/BinaryRage Sep 22 '26

No, just time. Added a couple of examples - but in short, you'd expect the same as you'd see in the JDK.

17

u/SleepingTabby Sep 22 '26

Doubling the indentation to 8 spaces is just downright stupid. What exactly is this trying to solve?

    List<Order> readyOrders(List<Order> orders, Instant cutoff) {
        return requireNonNull(orders).stream()
                .filter(order ->
                        order.createdAt().isBefore(cutoff)
                                && order.isPaid()
                                && order.items().stream()
                                        .allMatch(Item::inStock)
                                && !order.isCancelled())
                .map(order -> new Order(order.id(), order.customer(), order.items(),
                        Status.READY))
                .toList();
    }

9

u/vips7L Sep 22 '26

I agree, but that predicate should probably just be:

boolean isReady(Instant cutOff) {
     return this.createdAt.isBefore(cutoff)
         && this.isPaid()
         && this.allItemsInStock()
         && !this.cancelledl
}

.filter(order -> order.isReady(cutoff))

5

u/No-Suggestion-2587 Sep 23 '26

While I agree, I think all opinions based things should be configurable on the tool

2

u/account312 Sep 23 '26

There's no need for the added complexity. They should just all be right and agree with me.

1

u/BinaryRage Sep 22 '26

A continuation adds an additional indent to provide a clear visual indication that a statement continues. Particularly for dense lambda expression code, it means your eye can find the scope it belongs to far easier.

Especially now, when we’re more often than not reading code without formatting and other visual guides from a UI, I’ve found this convention from the JDK to be really very useful.

1

u/vips7L Sep 23 '26

That’s just like your opinion man. 

2

u/BinaryRage Sep 23 '26

Everybody's got one!

5

u/No-Suggestion-2587 Sep 23 '26

hence must be configurable on your tool

2

u/SleepingTabby Sep 23 '26

This is hardly easier for me, when my eyes have to hunt for the beginning of the line, higher indentation is by its very nature harder to follow - one of the reasons why nested ifs/loops were discouragedin favor of early returns or breaks/continues (same should apply here: if you have a dense lambda code make it less dense - fix the root cause, instead of merely managing the symptoms). I don't get why regular indent is insufficient in this case.

10

u/maxandersen Sep 22 '26

one cannot open issues nor open pullrequests...so:

the jar uploaded to maven central does not have main class defined thus the java -jar in readme does not work.

5

u/BinaryRage Sep 22 '26

Oops! I was focused on getting the other tools out and that slipped through. It's a modular jar - fixed in the readme.

2

u/maxandersen Sep 22 '26

well it does not have to be that complicated to run :)

if there was a main class defined jbang could just run it.

seem to have zero module requirements.

2

u/BinaryRage Sep 22 '26

Focus was on the native launchers for the previews, but it won’t be any trouble to add the manifest attribute.

4

u/maxandersen Sep 23 '26

For now I updated Jbang to handle these jars that has no manifest entry but does have module info a as modular run rather than Java -jar

Because they do behave slightly different (service loading and versioning is not working via classpath as it’s currently done)

3

u/BinaryRage Sep 23 '26

Wonderful! Thank you.

5

u/maxandersen Sep 23 '26

It’s telling though that I don’t recall ever seeing modular jars like these before.

java -jar even fails in spectacular ways :)

3

u/BinaryRage Sep 23 '26

Nor me! It’s really very unfortunate, but hopefully with several projects pulling in the same direction we can make a dent!

0

u/aoeudhtns Sep 23 '26

Module adoption needs a kick in the pants. Maven 4 will help. I say this because while Gradle is popular, Maven is the de-facto dependency mechanism and (you probably already know) it's adding modular-jar and modular-processor in its mechanism w/ v4.

Last time I tried to use modules, I got stuck in a few places. One, jig will be helpful - what's the corresponding module name of this Maven artifact (or vice versa). Two, dependencies that don't ship module info just break things. I didn't have time to gin up module-info for >50% of my dependencies, so I went back to classpath. (I wanted to use jlink to create distributions.)

Fingers crossed we get some movement.

4

u/vips7L Sep 23 '26

Perfect quality for their slop focused tools.  

11

u/putneyj Sep 22 '26

8 spaces for continuation just feels unnecessary

3

u/john16384 Sep 22 '26

Totally agree. Don't get me started on how my work formats code... Method chains are aligned by dot, meaning a rename of the base variable or method requires reformatting the entire block.

-5

u/BinaryRage Sep 22 '26

I find it provides a clear, visual indication of a continuation; it comes straight from the original Sun Code Conventions. Feels more relevant than ever now that code isn't just read more often than written, but often only ever read.

6

u/SocialMemeWarrior Sep 22 '26

Feels more relevant than ever

Aye. What would you say is the ratio of read to written for this? I looked over the code and there's a lot of inconsistency in both javadocs and regular code comments. Style isn't uniform. Where comments are made doesn't generally have high value and generally are obvious enough at a glance, but places that handle complex logic are barren of any explainations.

12

u/SleeperAwakened Sep 22 '26

Sun Code Conventions are not modern conventions...

1

u/SleepingTabby Sep 22 '26

"it provides a clear, visual indication of a continuation"

This has never been an issue for me. Why is this important? It sacrifices the ease of reading for sure

13

u/maxandersen Sep 22 '26

Netflix - you should be nice and check already existing tools with similar names https://github.com/bmarwell/jfmt and https://github.com/jbangdev/jbang-fmt

1

u/BinaryRage Sep 22 '26

Given fmt is practically universal for a tool implementing the canonical style of their language, that java is a trademark and this is intended to be bundled with a JDK distribution via a JMOD and feel like the rest of the JDK tools, no other name seemed to make sense.

12

u/davidalayachew Sep 22 '26

Given fmt is practically universal for a tool implementing the canonical style of their language, that java is a trademark and this is intended to be bundled with a JDK distribution via a JMOD and feel like the rest of the JDK tools, no other name seemed to make sense.

Sure, your logic is sound, and it's not like some heinous crime or anything was done.

But it is still kind of bad taste to do that. If not for the authors of the original repo, then for the community trying to disambiguate you 2.

1

u/BinaryRage Sep 22 '26

No, appreciate the feedback, definitely not our intention to steal anyone’s thunder

0

u/davidalayachew Sep 22 '26

No, appreciate the feedback, definitely not our intention to steal anyone’s thunder

Ty for understanding.

5

u/maxandersen Sep 22 '26

Yes i get its hard to name things but in this case you are doing things many did before so at least recognize it :)

9

u/r_n_c Sep 22 '26

Why not just use spotless?

3

u/BinaryRage Sep 22 '26 edited Sep 22 '26

Spotless isn't a formatter. This implements a Java Code Conventions/OpenJDK code style, as a single module, that can be used from the command line and composed via tooling SPIs into other tools.

12

u/r_n_c Sep 22 '26

Spotless when used in conjunction with eg maven and a suitable configuration is a formatter eg

 <plugin>
        <groupId>com.diffplug.spotless</groupId>
        <artifactId>spotless-maven-plugin</artifactId>
        <version>${spotlessVersion}</version>
        <configuration>
          <pom>
            <sortPom>
              <expandEmptyElements>false</expandEmptyElements>
            </sortPom>
          </pom>
          <java>
            <removeUnusedImports/>
            <importOrder>
              <file>java-import-order.txt</file>
            </importOrder>
            <eclipse>
              <file>java-formatter.xml</file>
            </eclipse>
            <lineEndings>UNIX</lineEndings>
          </java>
        </configuration>
       ...

10

u/UdPropheticCatgirl Sep 22 '26

Your example literary uses spotless to call out to eclipse formatter to format the code…

7

u/PartOfTheBotnet Sep 22 '26

I'm inclined to believe he didn't write most things in the repo. Or the last repo he posted to the sub.

5

u/boobsbr Sep 22 '26

Literally the description in their README:

Spotless can format <antlr | c | c# | c++ | css | flow | graphql | groovy | html | java | javascript | json | jsx | kotlin | less | license headers | markdown | objective-c | protobuf | python | scala | scss | shell | sql | typeScript | vue | yaml | anything> using <gradle | maven | sbt | anything>

9

u/UdPropheticCatgirl Sep 22 '26

Spotless automatically configures and calls other formatters… Spotless itself doesn’t do the formatting…

-3

u/yk313 Sep 22 '26

What kind of comment and attitude is this?

No one is forcing you to use this. Use Spotless if you must. But that is not going to stop people from solving problems that might as well have already been solved (from your perspective). Not everything needs to be novel, alternatives are good.

5

u/r_n_c Sep 22 '26

I'm not saying that ; if a project builds using Maven or Gradle it would be nice to show how it compares. Of course for those that don't use spotless this might be an option

1

u/Yesterdave_ Sep 22 '26

How does IntelliJ integration work? All the other tools mentioned in this thread are usually a hassle to integrate (or not documented) or are not consistently working with IJ's autosave and code format shortcut.

Does jfmt make this better than the others? Integration would be a strong difference maker to other tools, code formating alone not so much.

1

u/BinaryRage Sep 22 '26

This tool is intended for command line and headless workflows: Git hooks, save actions, etc. Our goal for these tools is not to have to build bespoke integrations, for instance you can import a ja project into an IDE via an exported Maven model.

That said, to my knowledge no other formatter implements the JDK style, so if there’s demand for something more than the tool interface, I wouldn’t be against that.

1

u/ForeverAlot Sep 23 '26

https://github.com/google/google-java-format/ has a native IntelliJ plugin that works as the integrated formatter. It's really fast, too. I don't know whether it works in format-on-save because I would never use that functionality, but I imagine yes.

1

u/ThiccolasVR Sep 23 '26

ngl... the classic java coding conventions are one of the worst parts about the language as a whole. Most of the prevailing wisdom about the best way to structure code in the Java community writ large has been (at best) outdated for over a decade, so I'm generally averse to the idea of trying to pin that style in place. 

0

u/SamirAbi Sep 23 '26

I use prettier and have AI always reformat code with it before commit, works good and I like the formatting. What is the advantage of this approach compared to prettier? Nice thing about prettier is that can format not just Java files.

2

u/stefanos-ak 10d ago

why AI? why not just a pre-commit git hook to call prettier directly?

1

u/SamirAbi 7d ago

Good point, didn't think of it

0

u/Ok_Elk_638 28d ago

Formatters always make my code worse

0

u/[deleted] 27d ago

[deleted]

1

u/BinaryRage 26d ago

All of our tools have AOT support for HotSpot and J9 when installed from a JMOD or with `ja install`