Skip to content

cschanck/single-file-java

Repository files navigation

Single File Java

What can you do in one file, no dependencies?

Modern Java development is often a joy because of the extensive ecosystem. Lots of the time, you can easily rely on lots of third-party libraries to help build your masterpiece.

This is one of the great strengths of Java, no question, and in no way would I want to do professional Java without the ecosystem.

However, it can be instructive to look backwards, back to a time before build systems with automatic dependencies, back before frameworks upon frameworks, back when if you wanted something to work — you built it yourself. The whole thing. No libraries from kind strangers.

Software minimalism is alive!

Ground Rules

  • 1000 lines in a file, no more than 132 chars on a line, commented enough to be useful.

    • This led to minor formatting tricks in the case of PegLegParser, which is juuuust barely under 1000 lines.

    • But stick to the included IntelliJ code style definition in the repo

  • No dependencies beyond test code deps for your single test file.

  • Apache 2.0 License. Thank you.

  • 1 piece of functionality; i.e., collections of random misc utils don’t count.

  • Not production pretty, necessarily. These classes are best regarded as erector set pieces for rapid prototyping, not production deployment. This means you are free to:

    • use deprecated/risky things like Serialization

    • forgo getters and setters in favor of direct field access

    • be slightly unconcerned with visibility of fields and methods

    • use Unsafe, etc.

    • do evil reflection tricks

    • ignore casting warnings and such. (Linting not a priority)

    • don’t feel compelled to do argument/bounds checking if there is no room

  • Should still have useful comments, and yes those lines count.

  • Learn to lean on internal Java things. Inner classes/interfaces help a lot, as can thread pools and such.

  • One JUnit4 test file, which also functions as a good place to show how to use the file; you can have test scoped dependencies.

  • For the moment, language level of Java 8, though I am wondering about Java 11. But still, lots of folks are working in 8. Something to revisit.

You are allowed (encouraged) one Asciidoc doc file per file, in src/docs. This can be used if the unit test file plus comments is insufficient to describe how to use the file.

The priority is on working, reliable code, suitable for prototyping something larger. Performance is not a top priority.

Feel free to think about building "mini-frameworks". For example, the LittleCASPaxos implementation delegates all of the network and storage functionality to some interfaces a user would have to provide; network transport and key-value persistence are not actually part of the LittleCASPaxos remit.

How Did We Get Here?

So, the way I started this was because I needed quick and dirty persistence, and some recent annoyances with third-party deps made me decide to see how fast I could build a thing. It was a short hop from "how fast" to "how small"; in the old days, when I started coding (long before humans invented the wheel :-) ), small, tight code was everything.

"How small can I make it" somehow morphed into "let’s see if I can do it in one file", and then — I ended up with ChiseledMap, a useful single file persistent map. What I found was that it was wonderfully concentrating and freeing to restrict myself to no outside libraries, and only one file. It was also nice to ignore the "production quality" ogre a bit, since we all deal with that beast at our day jobs all the time. Being free to use things like serialization, not be hyper concerned with security, and not totally worry about perf can be very nice.

It’s also easier to be restricted this way than you might think. The Java standard library is really rich, with a ton of adequate things built in. You’ll be surprised what it is like to code something this way; I would not have bet that I could do a Single-Decree Paxos impl in under 300 SLOCS, for example, but the bounded nature of the project helped me stay focused.

Another, very minor motivation was to refute the constant whining about how verbose Java is. Java can be verbose, but that is also part of its strength. But even with the verbosity, you can write a lot with a little code.

And yes, this can end up looking like a hodgepodge of random utilities. Duly noted.

Usage & Docs

See the Overview doc for a description of current files. See specific docs in src/docs for more info.

Maven!

We’re on Maven Central!

    <dependency>
      <groupId>org.singlefilejava</groupId>
      <artifactId>single-file-java</artifactId>
      <version>1.2.0</version>
    </dependency>

But really, you can just download the file you need if you like, and modify to suit.

Contributing

Feel free! Push a PR, or just file an Issue as an idea. Try and keep the guidelines in mind, obvs, but aim high.