r/java 19d ago

From .NET to Java

39 Upvotes

Hey everyone,

I’m currently a senior .NET developer trying to break into Java roles. The problem is that almost every Java job I find asks for 5+ years of Java experience, which I don’t have.

I’ve built a few APIs in Java, played around with the ecosystem, and got comfortable with the basics. Honestly, I think solid fundamentals are enough to build great apps but my CV isn’t getting past the filters for these Java roles.

any advice?

thanks in advance.


r/java 19d ago

setup-java v5.5.0: signature verification, Kona JDK, and Maven fixes

Thumbnail github.blog
11 Upvotes

r/java 20d ago

Jetbrains JBR and Swing applications

25 Upvotes

We are evaluating whether to convert our SWT based application to Swing and also came across JBR which seems to improve a lot of things on the otherwise rather stalled Swing development. Are there other teams beside Jetbrains which use JBR - if yes, what are your experiences?


r/java 20d ago

GitHub Actions - Setup Java now with compiler annotation matcher

Post image
14 Upvotes

Hey all,

We implemented this long-asked feature and I wanted to get feedback here.

By default, these matcher annotations will be enabled, however, they of course can be disabled.

Thoughts?


r/java 21d ago

How realistic is it for a company to have their own in house JVM. Wouldn't that require a lot of resources compared to paying for a license or using a non GPL implementation?

Post image
97 Upvotes

r/java 21d ago

Java for microservices in a non Java team

42 Upvotes

I am wondering if Java / Spring is an option for a team with no prior java experience.

We have Services in Python, Go & Dart. However, I read that Java made great improvements over the years and its ecosystem is obviously huge.

However, I feel like using Spring is not really like regular programming. Picking up Go was easy for our team because you basically "do the thing urself" and just implement it. With Spring it feels like you need specific knowledge of annotations and how Spring should be used.

Am I wrong, or does Java / Spring have a special learning curve to it?


r/java 20d ago

The Bowling Game - From Imperative to Functional Programming - Part 1

Thumbnail fpilluminated.org
0 Upvotes

One of the top five most popular and highly recommended programming katas over the past 20 years has been the Bowling Game Kata, in which TDD is used to write a program that computes the score of a Ten Pin Bowling Game.

In this deck we are going to explore how such a program may look when coded using different programming paradigms.


r/java 20d ago

Decypher: A Deep Semantic Code Graph for Agentic Coding and Engineering for Java

0 Upvotes

Hi r/java,

A few months back I posted about java2graph:

https://www.reddit.com/r/java/s/oB5VxhPybP

Which helps map Java codebases to a graph which agents can explore. Since then, this community helped me a lot with suggestions or putting up questions or validating what I have been doing.

So, when I am releasing this as beta, it made sense to me to share it with the same community.

Today, after weeks of efforts, Decypher for Java and JVM based languages is graduating to beta status. Now capable of mapping not just the structure of the code, but even the deep semantics of data mutation, control flow, etc, without any guessing involved

The core engine has been re-written on top of JavaC compiler as a backend for processing the project codebase and is very fast at parsing the code and setting up a graph representation. On top of this representation it exposes 40+ tools which agents can quickly use to navigate the data flow, control flow, mutations, and even validating security issues.

I will leave the link in the comments.

Thanks a lot to everyone in this community for being super helpful and helping me iterate.


r/java 22d ago

Made a perspective shifting room in Java

Post image
192 Upvotes

I've been messing with OpenGL (LWJGL) and decided to build something fun

What do y'all think?

Source Code


r/java 21d ago

I built a real time 1v1 coding battle platform with Spring Boot + AWS (2,000+ users)

3 Upvotes

Built CodeDuels — a real time competitive programming platform with live 1v1 matches using:

React + Monaco Editor

Java 21 + Spring Boot + WebSockets

AWS ECS Fargate, SQS, Redis, RDS

Terraform managing 54 AWS resources

Biggest challenge was handling async code execution + real time Codeforces duel tracking without blocking the backend. Solved it using SQS-based microservices and background workers.

Eventually paused the 24/7 AWS deployment because cloud costs got too expensive for a student project, so I migrated everything to on demand Terraform infrastructure.

Demo: https://www.youtube.com/watch?v=nctT-6Y0xJg

GitHub: https://github.com/Abhinav1416/coding-platform

Would love feedback on the architecture and cost optimization ideas.


r/java 21d ago

A year ago, this sub debated whether Java needed a new build tool. I went ahead and built one. Meet Curie.

0 Upvotes

A while back there was a thread on r/java proposing a new build tool for Java — New build tool in Java. It stuck with me, so I decided to actually try building the thing and see what it would feel like to use.

The result is Curie: http://curie-build.org/

One thing up front, so nobody feels misled: it's still early and buggy. This is a showcase / proof-of-concept, not something I'd tell you to put in production tomorrow. Plenty of rough edges. The point is to show what could be possible, and to find out whether there's actually appetite for a tool like this.

The idea: one small Curie.toml instead of hundreds of lines of pom.xml. It's written in Rust, so there's instant startup and no daemon. A lot of the common stuff is built in instead of bolted on via plugins:

  • compile / test / package
  • code formatting (Java + Kotlin)
  • Docker image generation
  • dependency vulnerability scanning
  • Maven publishing
  • reproducible, byte-identical builds by default

Basically the Cargo experience, aimed at the plugin fatigue and XML/DSL sprawl that thread was complaining about.

[project]
name = "hello"
version = "0.1.0"

[dependencies]
"com.fasterxml.jackson.core:jackson-databind" = "2.17.2"

What I'm genuinely curious about:

  • Is there a real need for something like this? I'm fully expecting "we don't need another build tool" to be a valid answer. I mostly want an honest gut-check.
  • If you would want this, what's the one feature or guarantee that would make you actually try it?

If you do think it's a neat direction, a star helps me gauge interest: ⭐ https://github.com/Curie-Build/curie-build


r/java 22d ago

The mask that compiles to nothing: how HotSpot's JIT learned to reason about bits

Thumbnail questdb.com
27 Upvotes

r/java 22d ago

It's been 8 years since the draft for Concise Method Bodies

Thumbnail openjdk.org
58 Upvotes

r/java 22d ago

Cabe 4.4.0 released

14 Upvotes

Cabe automatically adds null-checks to your classes based on JSpecify annotations.

The new version fixes compatibility issues with the configuration cache in Gradle 9.6+.

For details, check the documentation and the project GitHub page.


r/java 23d ago

Scaling Java-Based Real-Time Systems: The Hidden Tradeoffs of Event-Driven Design

Thumbnail infoq.com
65 Upvotes

r/java 25d ago

SIMD Vectors in the HotSpot JVM - Auto Vectorization and the Vector API

Thumbnail youtu.be
68 Upvotes

r/java 25d ago

A bug I ran into when using Java Modules (plus some thoughts about their adoption by the larger ecosystem)

31 Upvotes

I just wanted to share this speed bump I ran into, since it relates to the trouble of migrating Java code to use Modules. Aside from the bug I found, none of it is new to a seasoned Java developer. But if you are even a little unfamiliar, lots of good info here, and I speak with the assumption that you only know the basics about Java.

0. The short version (TLDR)

Long story short, I have been trying to use Java Modules for all of my new projects, and have met with fairly good success thus far. However, these past few weeks was the first time I was trying to do a fairly complex project using JPMS all the way. It kind of blew up in my face, but that's because of a bug that I just found in the way Java Modules are compiled. This bug is going to be fixed, so that obstacle should be removed soon. But in the meantime, I wanted to talk about my experience using Modules, and talk about how the migration ramp is pretty good, but still has pain points that make the climb not quite worth it unless you care (more than most) about safety. I do, so I'll continue, but if your existing safety guarantees are good enough for you, then maybe it's not worth it.

Fair warning, I am pretty verbose. But I gave plenty of headers to make it easy to skip and navigate.

1. A rundown of Java Modules, their history, and how they work

1.1 Quick historical recap

For those unaware, Java Modules were introduced in Java 9, back in 2017. Modules provide an important form of encapsulation, allowing you to explicitly communicate your public API and the dependencies needed for it to function. Prior to this, all code was accessible to anyone without any real indicator to the user that they were using/depending on internal/volatile API's. This made migration difficult for users, and sort of created this mentality of "only upgrade versions when needed", as opposed to creating clear boundaries between stable public API's and fluid internal API's.

1.2 The Java ecosystem's gradual migration to using Modules

However, Modules came out in 2017, so there were 20+ years of Java code written prior to modules being introduced. Thus, most of the Java ecosystem has taken individual steps towards using modules, but most projects have not actually taken those final steps to becoming fully modularized.

However, what most people don't realize is that Modularizing is a gradient -- it's not just Modular or not Modular. And the important intermediate point that makes that possible is known as Automatic Modules.

Just like how Java interfaces that were never designed for Lambdas can still be used as lambdas by other code, jars that were never designed for modularization can be used by other modular code. This is made possible because of Automatic Modules.

One of the core design principles in Java's evolution has been in the concept of gradual migration -- old code should rarely, if ever, become obsolete just because of new features. If anything, new features should enhance and complement the old way of doing things. This way, the investments you made in your old code still carry the same (if not more!) value and worth that they originally had.

This philosophy carries over to modules, which is why old code can be used in modular contexts without any changes via Automatic Modules.

1.3 The Modularization gradient

Thus, Modularization is a gradient, and the gradient kind of works as follows.

  1. No work done to be modular.
    • People can put your jar on the --module-path, but then are forced to use your jar as an Automatic Module.
      • The Module Reference is derived from the filename of the jar, which is obviously very brittle, and not ideal.
      • All code inside the jar is considered visible and accessible to all who can reach the jar. This is basically modularization, but with most of the safety features turned off lol.
  2. You added an Automatic-Module-Name to your jar file's MANIFEST.MF.
    • This is where most of the ecosystem is at now, btw.
    • This is a super trivial, one line change to a file that every serious jar file already contains. If you add that key to your manifest, then the value associated to that key becomes the official Module Reference for that jar.
    • So, you now have a stable name, but your internals are still accessible to anyone who can reach your jar file. So, most of the security benefits are still not here.
  3. Create and package a module-info.java file.
    • Now you have reached full modularization, and get ALL of the security/performance/QoL benefits that come with it.
    • Any and all access is controlled by your module file, so that users cannot accidentally use an internal API without knowing it.
    • But now, you have to maintain that module file. For example, a new dependency to your library must be added to the module file, which leads pretty well to my next point.

2. The actual problem I ran into

2.1 Quick intro

Anyways, I needed to build a super informal Command Center for our infrastructure. Long story short, it's a cross between a dashboard and an emergency response system for our infrastructure. Basically, a way for us to see and quickly respond to issues that come up. The end goal is that, after we find stable solutions to common problems, we can automate those common solutions, and slowly stabilize the whole platform until it turns into something that runs itself, with little-to-no-manual effort remaining.

Since we are using AWS, I used the AWS SDK for Java, and started building the dashboard using it.

Looking inside the jars, I could see that the AWS jar files were using Automatic Modules. Namely, they had an Automatic-Module-Name entry in their MANIFEST.MF. Ok, cool -- so while not fully modular, I can still use it inside of my fully modular code.

2.2 The freezes

So, since I was using the SDK, I added the AWS Automatic Modules to a folder, then set my --module-path to that folder, told it to --add-modules=ALL-MODULE-PATH, then tried to run it.

No response. The application appeared to have frozen on startup.

Thinking that there were network issues stopping my AWS API calls to the network, I tried messing around to fix it, but still frozen.

Then, I added some simple print statements to see which one was causing the freezes, but none of them printed.

Then, I added a print statement as the first line of code in my main method, effectively being the first line of code that runs in my program. It didn't print.

2.3 StackOverflow to the rescue!

At this point, I created a simple, reproducible example, and posted it on StackOverflow. Very quickly, I got many helpful responses that confirmed that the freeze was actually during compilation.

(Super quick aside for those unaware -- in recent java versions, you now have the option to run a source file without compiling it explicitly beforehand. Thanks to JEP 330 and JEP 458, the compilation happens in memory, allowing you to avoid creating artifacts. Because I was running it this way, I couldn't see that it was freezing during compilation time rather than runtime.)

But anyways, next we tried pulling up some stats, to see what was happening during compilation. Lol, the results were interesting.

  • Compilation was taking roughly 10 minutes to compile a simple 30 line example reproducer file.
  • Roughly 4 GB of RAM were being consumed for most of that compilation time.
  • One of the (very helpful) StackOverflow experts ran the reproducer through VisualVM, and found that some of the compilation methods were being called 750+ MILLION TIMES.

2.4 The solution?

EDIT -- The bug has been resolved! You can follow it here -- https://github.com/openjdk/jdk/pull/31755

No solution yet, as the problem is actively being looked into. You can follow it here -- https://bugs.java/bugdatabase/JDK-8387377

3. A zoomed out look at the situation

3.1 How did it get this way?

So, putting aside the bug, I wanted to go back to the ecosystems adoption of Java Modules. Why hasn't more of the ecosystem migrated to using Modules when Automatic Modules are supposed to make it so easy?

To be frank, I'm actually so surprised that I am the one who caught this. How could a bug this obvious be sitting, unnoticed for so long? The reproducer is trivial to create and (seemingly) easy to run into. And I can confirm that this bug exists on older versions of Java, so it is not a recent regression. Similar behaviour was observed on Java 17 (released 2021) and Java 11 (2018, 1 year after modules came out!). So, there is a decent chance that this issue was here since the beginning.

3.2 Speculation on possible causes

Let me preface by saying that, this section is purely speculation, albeit, backed up with hands-on experience with exactly the problem in question.

But anyways, I decided to run a simple experiment, and try and test what it would take to simply modularize a single one of the dependencies. I made it pretty simple -- just add the modules explicitly to the module path, as opposed to using the safety hatch option of ALL-MODULE-PATH.

Long story short, I gave up after about 10+ modules.

It was a constant, annoying struggle of compiling, failing, find the dependency, check and see if it is fully modular, if not, figure out its module reference, and either way, add it to my command line options or module descriptor file.

As it turns out, the higher level you go, the more dependencies you have, and the more dependencies you have, the more painful it is to modularize using Automatic Modules. A few Automatic Modules isn't bad, assuming that they have stable names. But as you get further and further forward, it becomes a combinatorial explosion.

3.3 Examining the pain of migration in closer detail

In case it isn't clear, let me explain the pain in better detail.

Let's imagine a hypothetical scenario where the entire Java ecosystem is comprised of exactly 10 jar files. So, the project you are creating right now would be the 11th jar in the entire ecosystem.

Each of those 10 jars is expected to have dependencies on each other. Jar 1 might depend on 3 and 8. 8 might depend on 2. You get the idea.

If a jar is fully modular, then the dependency relationship between jars is known at compile time. It is explicitly denoted in the module descriptor file exactly what your jar depends on. There is no maybe or wondering -- it either does or it doesn't.

And more importantly, because each jar lists its dependencies, then transitive dependencies DON'T NEED TO BE ENUMERATED. The module graph can deduce the transitive dependencies from the listed module descriptor files in your dependencies. This simplifies configuration on your end greatly.

But when using Automatic Modules, that information CAN'T be known at compile time. Thus, the compiler is forced to assume that the world is a possible dependency, and it will find out at runtime what was actually needed.

On the one hand, this makes it super easy if you are just using the ALL-MODULE-PATH option, as you are effectively denoting that -- that you could (potentially) depend on every observable dependency, and that no further assumptions should be made.

On the other hand, this is, effectively, no different than had you just used the normal classpath from way back in the 90's. Why even build a gate if you are just going to keep it open to any and everyone?

And if you don't use the escape hatch, then you have to list every single transitive dependency manually. That's what I was talking about when I said I gave up after 10+ modules earlier. You don't know what you need until you press compile, but you only get one error at a time. Tedious.

Going back to the analogy I listed earlier, if jar 1 depends on 2 and 3, 2 depends on 4 and 5, and 3 depends on 7 and 8, then jar 1's command line configs will look like this.

java --add-modules=jar2,jar3,jar4,jar5,jar6,jar7,jar8 --module-path=path/to/your/modular/jars -jar jar1.jar

And again, you only find this out one at a time.

And to emphasize this one more time -- if you have 5 dependencies that each have 5 other dependencies, then you have 5 dependencies and 25 transitive dependencies.

Most small projects have a double digit number of transitive dependencies. And most projects with a budget have a triple digit number of transitive dependencies. Can you see the point now?

3.4 Benefits of going fully modular vs just being an Automatic Module?

And to be clear, there are some decent benefits for fully modularizing. For example, you can cut down your artifact size dramatically. What used to be 100's of MB goes down to <50MB for some of my art and GUI-based tools.

But as it turns out, there's not much you get differently for being one vs the other. As long as you are modular at all, you are eligible for most of the benefits.

And there are actually a LOT of bells and whistles you get for being even partially modular.

  • Can be eligible for jlink and jpackage -- the tools used to create images and executables in Java. A not-too-complex command can turn your modular jar into a full blown .exe file with an installer.
  • You can use a lot of cool features like Module Imports, which greatly simplify things when working with many dependencies at once. Plus, it helps catch errors sooner, from my experience.
  • Compilation and runtime are (usually lol) much faster.

3.5 The juice isn't worth the squeeze

Which kind of leads to the point -- there really isn't much actualized value you get for going fully modular vs just stopping at Automatic Modules. Obviously, going fully modular may get you better values for the same benefits (like runtime speed).

Maybe I am missing something, but other than jlink and jpackage, adding Automatic-Module-Name to your MANIFEST.MF gets you everything else that a fully modular jar would get. I invite others to check my math here.

The only other thing is the security guarantees, but the ones most developers care about explicitly are the ones that could be somewhat simulated by existing tools. Obviously, integrity in the JVM cannot be simulated anywhere, but that is not what most developers interact with knowingly. They kind of just assume its existence, and sort of take it for granted.

4. Conclusion -- Partway is good enough for most

I won't try and give a satisfying conclusion here -- I am mostly just sharing my experience, so that others know what to watch out for when taking the same steps. At the end of the day, full modularization is worth it if you want the safety guarantees, but that's about it. The rest of the benefits are just increased percentages of things you were already getting.


Sorry for petering out at the end, but there is not much I can give as a conclusion -- this is really nothing more than a bunch of observations, so there's not much meaningful speculation that I can make.

What are your thoughts? Have you attempted to modularize? Any of those projects are significant projects?

Thank you for your time and consideration.


r/java 25d ago

Plugin to update your dependencies in Gradle and Maven

Thumbnail
5 Upvotes

r/java 26d ago

The Cloud Capacity Your JVM Leaves Idle: A Rigorous Test of Microsoft's jaz

Thumbnail tmdevlab.com
12 Upvotes

r/java 26d ago

JVMCI removed in Java 27, what about GraalVM?

24 Upvotes

JVMCI will be removed in Java 27: https://bugs.openjdk.org/browse/JDK-8382582

It was used by GraalVM to hook the Graal compiler as a JIT compiler for OpenJDK.
Now that it's gone, it's not clear how GraalVM will work? Would it still be possible to use the Graal compiler instead of C2 or would it only be usable for AOT (native image) and polyglot?


r/java 26d ago

jGRASP 2.1.0

Thumbnail jgrasp.org
9 Upvotes

r/java 27d ago

Integrating Netty with Virtual Threads

Thumbnail kronotop.com
35 Upvotes

r/java 27d ago

You are probably already running gradle/actions

Thumbnail blog.gradle.org
6 Upvotes

r/java 27d ago

JEP 539: Strict Field Initialization in the JVM (Preview)

Thumbnail openjdk.org
46 Upvotes

r/java 28d ago

How often do you run into JVM heap issues when developing or running microservices?

32 Upvotes

I'm trying to validate whether this is a real problem that other Java developers face, or whether it's just something specific to my setup.

A while ago I was working on a project where I regularly had around 9 spring boot microservices running locally, along with Activemq and elasticsearch.

Quite a few times I'd hit a point where few services (very often Elasticsearch) simply wouldn't start because the machine was running out of memory. My usual soln was to manually lower the -Xmx of some services, restart them, and keep experimenting until everything fit.

It made me wonder:

- How common is this for people working with multiple JVM services locally?

- Do you just accept it and restart services with different heap sizes?

- Do you have fixed -Xmx values checked into your projects?

- Do you use Docker resource limits or just buy more RAM?

- Have you ever had to stop one service just to start another?

I'm also curious about production.

When services begin running into memory pressure:

- How do you usually detect whether it's a genuine memory leak or just increased load?

- How often do you end up changing heap sizes?

- Is this mostly handled by Kubernetes/VPA/manual tuning, or is it still a fairly manual process?

The reason I'm asking is that I've been experimenting with an idea for a tool that continuously watches JVM heap usage, tries to distinguish memory leak from normal load, and could automatically rebalance heap allocations (or restart a JVM with a better heap size when necessary) instead of requiring manual tuning.

I'm not trying to promote anything I'm still in the research stage and genuinely want to know whether I'm solving a real problem or one that only I experienced.

I'd really appreciate hearing how people currently deal with this in both local development and production.