GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • java.evolved

This view

  • Original page
  • New address

GeezerVison is showing javaevolved.dev — Tooling — java.evolved

Home / Topics / Tooling
🏷 Tooling 13 patterns

Topic: Tooling

All Java patterns related to Tooling — java.evolved

Language

Compact source files

Old public class HelloWorld { public static void main(String[] args) { System.out.println( "Hello, World!"); } }
Modern void main() { IO.println("Hello, World!"); }
hover to see modern →
JDK 25+ learn more →
Tooling

JShell for prototyping

Old // 1. Create Test.java // 2. javac Test.java // 3. java Test // Just to test one expression!
Modern $ jshell jshell> "hello".chars().count() $1 ==> 5 jshell> List.of(1,2,3).reversed() $2 ==> [3, 2, 1]
hover to see modern →
JDK 9+ learn more →
Tooling

Single-file execution

Old $ javac HelloWorld.java $ java HelloWorld // Two steps every time
Modern $ java HelloWorld.java // Compiles and runs in one step // Also works with shebangs: #!/usr/bin/java --source 25
hover to see modern →
JDK 11+ learn more →
Tooling

Multi-file source launcher

Old $ javac *.java $ java Main // Must compile all files first // Need a build tool for dependencies
Modern $ java Main.java // Automatically finds and compiles // other source files referenced // by Main.java
hover to see modern →
JDK 22+ learn more →
Tooling

JFR for profiling

Old // Install VisualVM / YourKit / JProfiler // Attach to running process // Configure sampling // Export and analyze // External tool required
Modern // Start with profiling enabled $ java -XX:StartFlightRecording= filename=rec.jfr MyApp // Or attach to running app: $ jcmd <pid> JFR.start
hover to see modern →
JDK 9+ learn more →
Tooling

Lazy stack inspection with StackWalker

Old StackTraceElement caller = Thread.currentThread() .getStackTrace()[2]; String callerClass = caller.getClassName();
Modern String callerClass = StackWalker.getInstance() .walk(frames -> frames.skip(1) .findFirst() .orElseThrow() .getClassName());
hover to see modern →
JDK 9+ learn more →
Tooling

Compact object headers

Old // Default: 128-bit object header // = 16 bytes overhead per object // A boolean field object = 32 bytes! // Mark word (64) + Klass pointer (64)
Modern // -XX:+UseCompactObjectHeaders // 64-bit object header // = 8 bytes overhead per object // 50% less header memory // More objects fit in cache
hover to see modern →
JDK 25+ learn more →
Tooling

Built-in HTTP server

Old // Install and configure a web server // (Apache, Nginx, or embedded Jetty) // Or write boilerplate with com.sun.net.httpserver HttpServer server = HttpServer.create( new InetSocketAddress(8080), 0); server.createContext("/", exchange -> { ... }); server.start();
Modern // Terminal: serve current directory $ jwebserver // Or use the API (JDK 18+) var server = SimpleFileServer.createFileServer( new InetSocketAddress(8080), Path.of("."), OutputLevel.VERBOSE); server.start();
hover to see modern →
JDK 18+ learn more →
Tooling

Class-file parsing with the standard API

Old ClassReader reader = new ClassReader( Files.readAllBytes(classFile)); reader.accept(visitor, 0);
Modern ClassModel model = ClassFile.of().parse(classFile); model.methods().forEach(method -> System.out.println( method.methodName().stringValue()));
hover to see modern →
JDK 24+ learn more →
Tooling

AOT class preloading

Old // Every startup: // - Load 10,000+ classes // - Verify bytecode // - JIT compile hot paths // Startup: 2-5 seconds
Modern // Training run: $ java -XX:AOTCacheOutput=app.aot \ -cp app.jar com.App // Production: $ java -XX:AOTCache=app.aot \ -cp app.jar com.App
hover to see modern →
JDK 25+ learn more →
Tooling

JUnit 6 with JSpecify null safety

Old import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class UserServiceTest { // JUnit 5: no null contracts on the API // Can assertEquals() accept null? Check source... // Does fail(String) allow null message? Unknown. @Test void findUser_found() { // Is result nullable? API doesn't say User result = service.findById("u1"); assertNotNull(result); assertEquals("Alice", result.name()); } @Test void findUser_notFound() { // Hope this returns null, not throws... assertNull(service.findById("missing")); } }
Modern import org.junit.jupiter.api.Test; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import static org.junit.jupiter.api.Assertions.*; @NullMarked // all refs non-null unless @Nullable class UserServiceTest { // JUnit 6 API is @NullMarked: // assertNull(@Nullable Object actual) // assertEquals(@Nullable Object, @Nullable Object) // fail(@Nullable String message) @Test void findUser_found() { // IDE warns: findById returns @Nullable User @Nullable User result = service.findById("u1"); assertNotNull(result); // narrows type to non-null assertEquals("Alice", result.name()); // safe } @Test void findUser_notFound() { @Nullable User result = service.findById("missing"); assertNull(result); // IDE confirms null expectation } }
hover to see modern →
JDK 17+ learn more →
Tooling

Runtime.exec(String) to ProcessBuilder arguments

Old Process process = Runtime.getRuntime() .exec("git show " + revision);
Modern Process process = new ProcessBuilder( "git", "show", revision) .redirectErrorStream(true) .start();
hover to see modern →
JDK 5+ learn more →
Tooling

Class.newInstance() to constructor reflection

Old Plugin plugin = pluginClass.newInstance();
Modern Plugin plugin = pluginClass .getDeclaredConstructor() .newInstance();
hover to see modern →
JDK 9+ learn more →
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.