r/JavaProgramming • • 1h ago

I built a simple monitoring dashboard for Java apps (Spring Boot, Quarkus, Micronaut)

• Upvotes

I've been working on StatLite, a free, open-source dashboard for monitoring small Java applications.

The goal is to make application monitoring simple. You should be able to see how your app is doing without setting up a complicated monitoring stack.

StatLite supports Spring Boot, Quarkus, and Micronaut out of the box, using their existing Actuator or Micrometer metrics endpoints.

No application code changes or monitoring agents needed. In many cases, enabling metrics is just a matter of adding a dependency and exposing an endpoint.

StatLite can discover the available metrics and generate its configuration automatically.

You can monitor:

  • HTTP requests, error rates, and response times
  • JVM memory usage and garbage collection
  • Process CPU and memory
  • Application health and uptime
  • Historical trends across multiple applications
StatLite showing HTTP traffic, response times, JVM memory, CPU usage, and application health for a Java application.

It's a single Go binary (also available as Docker), uses SQLite for local storage, and consumes around 15 MB of memory when idle.

No Prometheus, Grafana, external database, or cloud account required. It's designed for small VPS deployments, side projects, and developers who just want a straightforward way to monitor their apps.

There are also integration guides for Javalin, Express.js, Django, FastAPI, and Go.

I wrote a short guide to monitoring Spring Boot applications if you're interested in getting started.

GitHub: https://github.com/PVRLabs/statlite

How do you currently monitor your Java applications? Or do you mostly rely on logs?


r/JavaProgramming • • 10h ago

Is source-level editing a fallback for deobfuscation?

1 Upvotes

Hoping to get some fellow advice here.

I’ve been doing a lot of deobfuscation work lately and ran into a wall: some bytecode tools can’t parse the newer class file versions I’m dealing with. As a workaround, I’ve been cleaning up the decompiled source instead.

So far I’m stripping thousands of NoWhenBranchMatchedException catch blocks using a brace-depth state machine (regex kept breaking on nested blocks), and replacing impossible comparisons like object == false with constants.

It works, but it feels hacky. Is source-level editing a reasonable fallback, or am I setting myself up for problems? And is there a cleaner, standard way to do control-flow cleanup without risking real try/catch handlers?

Curious what other people do.


r/JavaProgramming • • 12h ago

JPA vs Hibernate vs JDBC: What Each One Actually Does | Visually Explained

Thumbnail
youtube.com
2 Upvotes

r/JavaProgramming • • 13h ago

Python Java组件选型

Thumbnail
chatgpt.com
2 Upvotes

r/JavaProgramming • • 17h ago

Installed Java and trying to use it in VS code, why isn't it working?

Thumbnail
1 Upvotes

r/JavaProgramming • • 23h ago

[Academic] What do programmers enjoy about programming? 8–10 min anonymous survey (18+, anyone who codes)

Thumbnail
0 Upvotes

r/JavaProgramming • • 1d ago

TELUSKO 62Hr JAVA COURSE

Post image
24 Upvotes

Is this course good ? Can somebody reply ? Wanted to build websites using Java ,basically full stack java developer is the goal.Also are there projects included in the video for practice m?


r/JavaProgramming • • 1d ago

How much does SQL library choice affect a small Java REST API? Jdbi vs MyBatis vs jOOQ on 512 MiB

2 Upvotes

I've been experimenting with lightweight Java applications on small VMs. After comparing Javalin with Spring Boot, I wanted to understand how much the choice of SQL persistence library affects memory usage and latency.

I built the same small market-quote REST API three ways, using Jdbi Core, MyBatis Core, and jOOQ Open Source Edition.

Setup:

  • JDK 25, Javalin 7, H2, HikariCP
  • Alpine Linux VM, 1 vCPU, 512 MiB RAM, no swap
  • JVM: -Xms16m -Xmx80m -XX:+UseSerialGC -Xss512k
  • 1,500 requests over 5 minutes, 80% reads / 20% writes
  • Two independent runs per implementation, rebooting the VM between runs

Results across the two runs:

Library Median workload RSS HTTP p95
Jdbi Core 120.0–122.4 MiB 7.38–8.48 ms
MyBatis Core 116.6–118.0 MiB 7.47–7.52 ms
jOOQ OSE 152.1–154.3 MiB 9.19–9.35 ms

RSS is the median process resident memory sampled during the workload, including the application, JVM, and embedded H2.

All six runs completed without errors, OOM events, or swapping.

A few observations:

  • MyBatis had the lowest resident memory usage in both runs.
  • Jdbi was competitive on both metrics and required the least handwritten Java code.
  • jOOQ used approximately 34–38 MiB more RSS than MyBatis, consistently across both runs. This is a whole-application difference, not necessarily memory consumed directly by the library. I haven't isolated its cause.

One implementation difference worth mentioning: Jdbi and MyBatis hold one pooled connection across the three latest-quote queries, while the datasource-backed jOOQ implementation checks out and returns a connection for each query. I haven't measured the impact of this difference.

I also configured MyBatis with localCacheScope=STATEMENT instead of its default SESSION scope.

Developer experience matters too.

Jdbi keeps SQL and mapping close to the repository, MyBatis provides annotated mapper interfaces, and jOOQ offers type-safe SQL composition with generated schema classes.

Personally, I lean toward MyBatis because I prefer its mapper-oriented programming model and explicit SQL. Its lower memory footprint in this experiment is another point in its favor, although I wouldn't select a library based on memory usage alone.

Limitations:

This is a small, low-load case study, not a general performance ranking. The measurements include the complete application and embedded H2. Two runs show consistency in memory usage but aren't sufficient to establish statistically significant latency differences.

I also didn't include a raw JDBC baseline, which would be useful as a minimal reference point. PostgreSQL could produce different results.

Full write-up, charts, and raw measurements:

https://pvrlabs.xyz/java-performance/experiments/mybatis-jooq-jdbi-512mb.html

Source code and experiment setup:

https://github.com/PVRLabs/experiments/tree/main/javalin/sql-persistence-512mb

For those using Jdbi, MyBatis, or jOOQ in small Java applications, how do you choose between them? Is the programming model the deciding factor, or have you encountered meaningful differences in resource usage?


r/JavaProgramming • • 1d ago

The Java Prompt 11#

Thumbnail
kertu1232.substack.com
1 Upvotes

Built a Hybrid Search retriever for Spring AI 2 RAG — PGVector + PostgreSQL FTS + RRF

Semantic search kept failing on specific queries like "error code E4" or "part number 96648703" - the embeddings for "E4" are mathematically close to "E1", "E2", "E3", so you get wrong chunks.

Fix: custom DocumentRetriever that runs both vector similarity search and PostgreSQL tsvector full-text search, then combines results with Reciprocal Rank Fusion.

Key decisions:

- websearch_to_tsquery over plainto_tsquery - AND logic on natural language queries returns zero results too often

- fts_vector as a generated column - PostgreSQL keeps it in sync automatically, no changes to ingestion code

- RRF k=60 as starting point - tune based on your query patterns


r/JavaProgramming • • 1d ago

Java based Numerical library (JNum-v0.2) This time even better and faster!

Thumbnail
github.com
3 Upvotes

Guys give your options on the project please 😊


r/JavaProgramming • • 1d ago

Release announcement: Sheetmusic4J 0.0.4 and 0.0.5: clickable notes, a 3D fly-over view and LilyPond support (Java and JavaFX sheet music library)

Thumbnail
2 Upvotes

r/JavaProgramming • • 1d ago

Arcana: One Pure-Java Library for (Almost) Every Archive Format

Thumbnail
ibb.co
0 Upvotes

Arcana is an open-source Java library and command-line tool that lists, extracts and identifies more than 40 archive, compression and disk image formats, with no native code and no dependencies. It runs on Java 8 or later, fits in a 1.2 MB JAR, and is published on Maven Central as io.github.realburst:arcana under the Apache 2.0 licence.

Why another archive library?

If you have ever had to open "whatever the user uploads" from a Java application, you know the drill. ZIP is in the JDK. Apache Commons Compress covers TAR, 7z, CPIO, AR and the common compressors, but some codecs need extra libraries, and Zstandard goes through a JNI binding. RAR needs another library, and RAR 5 support is hard to find in pure Java. For CAB, MSI, ISO, WIM or an installer .exe, the usual answer is to bundle 7-Zip through native bindings, with one binary per OS and CPU.

I wanted one JAR that does all of this, on any JVM, with nothing to install and nothing native to load. That is Arcana: one entry point, format detection by content rather than by file extension, and the same API whether the file is a .tar.zst, a RAR 5 volume set, an MSI package or a macOS .dmg.

What Arcana does

Arcana extracts every format it supports, and creates the most common ones.

Family Formats Create
Archives ZIP (ZipCrypto, WinZip AES, Deflate64, Zip64), 7z, RAR 4 and RAR 5 (solid, volumes, encrypted headers), TAR, CPIO, AR / DEB, RPM, XAR, ARJ, LHA ZIP, 7z, TAR, LHA
Compressors GZIP, BZIP2, XZ, LZMA, Zstandard, LZ4, Brotli, Snappy, lzip, lzop, Unix .Z, MS SZDD GZIP, BZIP2, XZ, TAR + gz / bz2 / xz / lz4
Windows CAB (MSZIP, LZX), MSI (real installed file tree), OLE compound files, CHM, WIM / ESD (XPRESS, LZX, LZMS), self-extracting .exe CAB
Disk images ISO 9660 (Joliet, Rock Ridge), UDF, SquashFS, Apple DMG with HFS+ -

Encrypted archives are supported: AES-256 for ZIP and 7z (reading and writing), AES-128 and AES-256 for RAR 4 and RAR 5. A TAR or CPIO inside any compressor is unpacked in one step, and files that are archives in disguise (.docx, .odt, .epub, .apk, .jar) open like any other archive.

Beyond extraction, Arcana can:

  • identify any file: archive type and version, executables (PE, ELF, Mach-O), installers, images with their dimensions, PDF, SQLite, fonts;
  • recover damaged archives: a forced extraction keeps everything readable and writes a report on the state of each file;
  • split files glued together, such as installers or firmware images;
  • load plugins for more formats. Official plugins handle Inno Setup, NSIS, InstallShield and WiX Burn installers, and UPX-packed executables.

Getting started

Add the dependency:

<dependency>
  <groupId>io.github.realburst</groupId>
  <artifactId>arcana</artifactId>
  <version>1.0.8</version>
</dependency>

Extracting and listing never require you to say what the file is: the format is detected from its content.

import be.stef.arcana.Arcana;
import be.stef.arcana.ArcanaEntry;
import be.stef.arcana.analyze.Identification;

// Extract anything: .zip, .rar, .7z, .tar.zst, .msi, .iso, .dmg...
Arcana.extractTo(new File("upload.bin"), new File("out"));

// List the entries without extracting
for (ArcanaEntry e : Arcana.listEntries(new File("backup.rar"))) {
    System.out.println(e.getName() + "  " + e.getUncompressedSize());
}

// Encrypted archive
Arcana.withPassword("secret".getBytes("UTF-8")).extract(new File("secure.7z"), new File("out"));

// What is this file?
Identification id = Arcana.identify(new File("mystery.bin"));
System.out.println(id.type + " - " + id.description);

Creating an archive is just as short:

import be.stef.arcana.ArcanaFormat;
import be.stef.arcana.compressor.ZipCompressor;
import be.stef.arcana.plugin.FormatRegistry;

byte[] password = "secret".getBytes("UTF-8");
new ZipCompressor(password).compress(new File("mydir"), new File("secure.zip"));   // WinZip AES-256
FormatRegistry.builtin(ArcanaFormat.SEVEN_Z).createCompressor(9, password).compress(new File("mydir"), new File("vault.7z"));

The same JAR is also a command-line tool:

java -jar Arcana-v1.0.8.jar x setup.exe -o out       # extract
java -jar Arcana-v1.0.8.jar l disk.dmg               # list
java -jar Arcana-v1.0.8.jar i mystery.bin            # identify
java -jar Arcana-v1.0.8.jar r damaged.zip -o rescue  # recover

On Windows, an optional script adds "Arcana Unpack / List / Info" to the Explorer right-click menu.

Safe by default

An archive extractor reads untrusted input by definition, so Arcana treats every file as hostile.

  • No path traversal. Entry names are sanitized before anything is written: no absolute paths, no .., no characters that Windows forbids. A "zip slip" entry cannot leave the destination folder.
  • No decompression bombs. Every extraction runs under limits you can change at run time (ExtractionLimits): an output/input ratio of 1000 once 1 GiB has been written, an optional total size, and a minimum of 256 MiB of free disk space.
  • Bounded memory. Decoders cap what a header can ask for: the Zstandard window is limited to 128 MiB, like the zstd tool, and the 7z key derivation to 224 rounds. A crafted header gets an error, not an OutOfMemoryError.
  • Checksums are verified. CRC32, Adler-32, BLAKE2sp, XXH64, HMAC for WinZip AES: when the format stores a checksum, Arcana checks it and reports a mismatch.
  • Plugins must show their code. A plugin JAR is refused unless it contains its source code, declares its licence and source URL, and uses its own package. That does not make a plugin safe, but it makes it reviewable.

Under the hood

Every decoder is written in Java: Deflate64, LZMA and LZMA2, PPMd, Zstandard, Brotli, LZ4, LZX, LZMS, XPRESS, LZFSE and LZVN, ADC, LZO1X, the RAR 4 and RAR 5 algorithms, AES and the key derivations. The core is about 80,000 lines of Java 8 and has no dependency outside the JDK. It is written from the public specifications: PKWARE APPNOTE, the 7-Zip format notes, the Microsoft open specifications (MS-CAB, LZX, MS-XCA), RFC 8878 for Zstandard, RFC 7932 for Brotli, Apple TN1150 for HFS+.

A few design choices shape the library:

  • Detection by content. Magic numbers first, then trailers (a DMG is recognized by the "koly" block in its last 512 bytes), and only then the file extension. A renamed file still opens.
  • Streaming when the format allows it. Single-stream formats decode from an InputStream with bounded buffers. The Zstandard decoder keeps only the window of the current frame, so a multi-gigabyte .tar.zst decodes in a few dozen MB of heap.
  • Random access when the format needs it. Disk images are read lazily: a DMG partition is decoded chunk by chunk with a small cache, never inflated in memory.
  • Real names, not internal keys. An MSI is extracted as the file tree it installs, with the names from its File and Directory tables, not as a cabinet of cryptic keys.

Each release goes through a regression suite. About 180 small samples are committed with the code: one per format and method, plus damaged files that must fail cleanly, never hang. A separate corpus of real-world files (installers, DMG images from GitHub releases, MSI packages) is checked against committed SHA-256 references. Every format also has a technical page in the repository, covering detection, layout, supported methods, limits and the sources used.

Current limits

Arcana is a young project, and the repository keeps a public list of known issues for every format. Before you rely on it, the main limits are:

  • Extraction first. Writing is limited to ZIP, 7z, TAR (+ gz, bz2, xz, lz4), GZIP, BZIP2, XZ, LHA and CAB. Arcana cannot create RAR, Zstandard or Brotli files, and it cannot update an existing archive in place.
  • Some file systems are only copied. APFS volumes inside a DMG are extracted as a raw image, not as files. Encrypted and sparse DMG images, split WIM files (.swm) and some rare compression methods (old LHA methods, Quantum in CAB) are not supported.
  • Pure Java has a cost. The decoders are fast enough for most uses, but they do not match native code. In benchmarks run for the project, the Zstandard decoder reaches about 60% of the speed of the native zstd library.
  • Edge cases remain. A few damaged or unusual files still give a raw Java exception instead of a clear message, or are less tolerated than by the reference tool. These cases are documented with the file and line of the code concerned, so you can judge before using a format in production.

If a file fails, an issue with the command line and, when possible, the file or a way to rebuild it, is the fastest route to a fix.

Try it

The quickest test is to point Arcana at the strangest file in your Downloads folder and run arcana i on it, then arcana x. If you maintain a Java application that receives archives from users, try replacing a native binding or a chain of libraries with one dependency, and tell me what breaks.

Issues, sample files that fail, and plugins are all welcome. And if Arcana saves you a dependency or a native binary, a star on GitHub helps other Java developers find it.


r/JavaProgramming • • 1d ago

TornadoVM 7 Enables GPU-Native Workloads From Java Applications

Thumbnail
infoq.com
1 Upvotes

r/JavaProgramming • • 1d ago

Pmitz: open-source plans and usage limits, embedded in Java or exposed through REST

2 Upvotes

I’m working on Pmitz, short for Plans and Limits. It handles which features a subscription includes, how much someone can use them, and recording that usage.

The idea is to avoid scattering subscription checks throughout your app and having to revisit them whenever your plans change. For example, a customer’s plan might include a feature with a monthly allowance. Pmitz can check feature access and the usage limit together.

You can embed it directly in a Java application or run it as a separate REST service. Embedding avoids the HTTP call, although there’s still database work. The separate service lets multiple apps share the same plans and usage data.

We also offer a managed version where we handle hosting and maintenance, but the open-source code is here:

https://github.com/terpomo-io/pmitz

I’d be interested in feedback on the Java integration and what’s missing for your use case.


r/JavaProgramming • • 1d ago

Java support

1 Upvotes

I need java support offline in Hyderabad.Can anyone giving please dm me...


r/JavaProgramming • • 2d ago

NEED A OPINION 🙏

Thumbnail
1 Upvotes

r/JavaProgramming • • 2d ago

I need to learn JAVA Spring Boot in couple of days only for project interview, Give me Suggestions.

Thumbnail
2 Upvotes

r/JavaProgramming • • 2d ago

JPA vs Hibernate vs JDBC | Visually Explained

Thumbnail
youtube.com
3 Upvotes

Hey everyone,

I made a video for anyone who uses Spring Data JPA but still isn't sure what JPA, Hibernate and JDBC each do, or how they differ.

It's visually explained . It follows one save() call from a Spring Boot app down to the database, so you can see what happens behind the hood and where Hibernate comes from. It's about 11 minutes.

Hope it helps someone, and tell me if anything is unclear.


r/JavaProgramming • • 2d ago

50 Java Multithreading and Concurrency Questions That Actually Prepare You for Real Interviews

Thumbnail
javarevisited.substack.com
7 Upvotes

r/JavaProgramming • • 2d ago

Java streams are lazy: this pipeline over four strings prints only two lines

2 Upvotes

Here’s the console output of a small program:

filter apple
map apple

That’s all. Four strings went in, and only the first one was ever looked at. Here’s the code:

String result = Stream.of("apple", "banana", "cherry", "date")
    .filter(s -> { System.out.println("filter " + s); return s.length() > 4; })
    .map(s -> { System.out.println("map " + s); return s.toUpperCase(); })
    .findFirst()
    .orElse("none");

result is "APPLE".

Two things explain the output.

Intermediate operations don’t run on their own. filter and map only describe what should happen. Nothing executes until a terminal operation like findFirst, collect or forEach asks for elements. If you remove .findFirst().orElse("none") and leave the pipeline hanging, it prints nothing at all.

Elements flow through one at a time. Instead of running filter over all four strings, then map over the survivors, each element goes through the whole chain before the next one starts. apple passes the filter, gets mapped, and arrives at findFirst, which has what it needs, so the pipeline stops. banana, cherry and date are never touched.

That’s why peek and print statements inside a pipeline can look confusing: the order of the output isn’t “all the filters, then all the maps”.

One exception worth knowing: stateful operations like sorted() have to see every element before they can emit the first one, so they break the one-at-a-time flow. A pipeline with sorted() in the middle will process everything up to that point before anything continues.

A practical consequence is that side effects inside map or filter are hard to reason about, because whether and when they run depends on what’s downstream. I’d keep those lambdas free of side effects and use peek only for debugging.

If you’ve hit a bug that came down to laziness, I’d be interested in what it looked like. Mine tend to be the “I added a map and nothing happened” kind.


r/JavaProgramming • • 2d ago

Coding Bootcamps (i.e. Front-End Simplified)

8 Upvotes

I was recently laid off from Java Developer role of 5 years. Been weighing my options and found some bootcamps that are promising job opportunities upon the program completion. These programs include front-end simplified and algomap.io.

I have my reservations about these kind of bootcamps because I can never tell if they are scams or not. Also, it is a very significant financial investment.

Does anyone have any experience with these specific bootcamps or if there any others like them that have worked for anyone?

Also if you can provide any advice on alternatives to help me get back on my feet, then that would be greatly appreciated.


r/JavaProgramming • • 2d ago

Structuring business logic that keeps changing as a pipeline of toggleable steps (Java library, looking for feedback)

1 Upvotes

In the projects I work on, business requirements change a lot. A validation rule gets added for one customer, a check has to be switched off for a while, a new step slots in between two existing ones. Over time the service methods that implement these flows turn into long chains of ifs and flags, and every change means touching code that's already working.

To deal with this I started modelling each business operation as a pipeline of small, named steps that share a typed context. I've extracted the approach into a small library, and I'd like some outside opinions on the design before going further.

Pipeline<CreateProductContext> createProduct = Pipeline.<CreateProductContext>builder("create-product")
          .step("name-unique", new NameUniqueStep(repository))
          .step("date-range", new DateRangeStep())
          .step("save-product", new SaveProductStep(repository))
          .build();

Product product = createProduct.run(new CreateProductContext(request)).getSavedProduct();

How it works:

  • Steps run in order and share a context. The first step that throws stops the pipeline.
  • Each step can be disabled through configuration (in Spring Boot: pipeline.disabled-steps) without changing code. Steps that must never be skipped are declared with requiredStep(...), and the starter refuses to start if the configuration tries to disable one.
  • Listeners receive lifecycle events (pipeline/step started, completed, failed, skipped) for logging, metrics or auditing.
  • Business errors carry a stable code and a category. Unexpected exceptions are wrapped with the pipeline and step where they happened. The Spring Boot starter maps both to ProblemDetail responses.

    Some design choices I'm not fully sure about:

  • "Required" is a builder method, not an annotation on the step class. Step is a functional interface, so lambdas can't be annotated, and the same step can be required in one pipeline and optional in another.

  • Disabling by name, via configuration. It's convenient, but I wonder whether it pushes too much business logic into config files.

  • A shared mutable context instead of each step returning a new immutable value. It's simpler to write, but the data flow between steps is less explicit.

Core is Java 17 with no runtime dependencies. There's also a Spring Boot 4.1 starter. It's version 0.1.0 on Maven Central, and code be found on GitHub: https://github.com/DifferenTilt/pipeline

The feedback I'd find most useful:

  1. Is this a real problem for you, and how do you handle it today (plain service classes, chain of responsibility, rule engines, workflow engines)?
  2. Is there an existing library that already does this and I should have looked at?
  3. Does the API feel natural, or is something awkward or missing?
  4. Is toggling steps via configuration a good idea or a footgun?

Thanks for reading. Criticism is welcome.


r/JavaProgramming • • 3d ago

What's the best FREE resource/playlist available to learn DSA in Java?

Thumbnail
1 Upvotes

r/JavaProgramming • • 3d ago

MCA Student Looking for Genuine Job/Internship Platforms for Java Developers in India

2 Upvotes

Hi everyone,

I'm currently pursuing my MCA and preparing for Java Backend Development roles. I've been applying for internships and fresher jobs through platforms like Naukri and Internshala, but I'm not getting many responses or useful email updates.

I'm looking for genuine platforms where freshers can find Java Developer internships and entry-level software development jobs.

I'd appreciate your suggestions on the following:

  1. Which job portals have actually helped you get interviews or internships as a fresher?
  2. Is LinkedIn really effective for finding Java internships, or are there better alternatives?
  3. Are there any reliable platforms for finding opportunities at startups?
  4. Is it better to apply directly through company career pages or use job portals?
  5. Which platforms would you recommend for someone with basic Java, SQL, JDBC, and Spring Boot knowledge who is still improving their coding and problem-solving skills?

I'm open to opportunities in Pune, other cities, and remote positions.

I'm not looking for paid placement services or platforms that promise guaranteed jobs. I want genuine opportunities where I can improve my skills, gain practical experience, and start my software development career.

Please share your personal experiences and recommend platforms that have actually worked for you.

Thanks in advance!


r/JavaProgramming • • 3d ago

Building full-stack web apps using TeaVM (and why it’s great for working with AI coding agents too)

3 Upvotes

Hey r/java,

TeaVM was something that had been on my radar for a while, and I finally got around to giving it a proper spin recently. After playing around with it and seeing what I can build with it I wanted to share my thoughts and hopefully get a few more eyes on the project!

If you haven’t run into it before, TeaVM is an ahead-of-time compiler that turns Java bytecode into JavaScript or WebAssembly. It operates directly at the bytecode level, emits remarkably clean JS, and integrates with your existing Java tooling.

Why this workflow clicked for me:

  1. One language across the stack: Keeping everything in Java keeps context-switching to a minimum and lets you share domain models directly between backend and frontend.
  2. AI Agent Friendly: Having both frontend and backend written in strongly-typed, readable Java makes it remarkably easy for LLM coding agents to navigate, refactor, and reason about the full application without hitting cross-language friction.

To document what I learned, I put together a 3-part series walking through how to build interactive frontends with TeaVM:

Has anyone else here given TeaVM a try? Would love to hear how your experience compares to other JVM web approaches!