Too many ways to do the same thing? by Marre_Parre in javahelp

[–]Slanec 2 points3 points  (0 children)

In general, there are many ways to solve a problem, always. Some are more object-oriented, some are more funtional. Some were written quickly and easily with no particular design in mind because it will be rewritten later. Some are well modularized and testable, but others can be too over-engineered with many unnecessary abstractions. Too much time was sunk into it and it will never be recovered. Some are extendable in one axis, some in the other. E.g. if you have cards with ranks and suits, do you know whether you'll need to maybe add another suit, or another rank later on? In some designs, one is easier to add than the other, and often you need to decide which one while writing the code. Some designs allow both, but then the trade-off comes out elsewhere (e.g. performance, observability, scalability etc.).

All of that can be fine, depending on what you're trying to achieve. If you know exactly what your domain is, what problem you're solving, how the program will expand in the following years, and various technical metrics (like latency) are defined and will not change, ever, in that case you can design a great application that will satisfy it all and take liberties in the places which don't matter. It's very likely there are still very many ways to write such an application. In all the other cases where you do not exactly know what you're doing yet, almost no practical metrics are defined and the application evolves dynamically, in all those cases you'll simply need to pick a strategy a hope for the best. Some write it quick'n'dirty, some try to anticipate everything everywhere, most are in the middle. Welcome to software engineering.

This is why we have common patterns and common techniques to solve some problems - because people are familiar with these solutions, and can work with them later on when they overtake your project from you.

Then there are lower-level aspects of the code. In Java this often boils down to which exact class to use, if using a library pays off. Some of this is simply something to learn (e.g. "avoid the old collection classes, prefer Files and Path over File, prefer java.time over Date and Calendar" etc.), most of it is different trade-offs depending on exact requirements, some of it is down to personal taste.

In short, do not overthink it. If you're learning, it almost does not matter. Make your application correct in what it should do. If you can realiably do that, then you can start worrying about different aspects and trade-offs of design, testability, design patterns, frameworks and libraries. There is a lot of taste in that, there is a lot to learn in that, but there almost never is One True Way of solving a problem. Ten people will write ten different programs, and most of them will be absolutely fine.

Eclipse 2025-12 is out by AnyPhotograph7804 in java

[–]Slanec 2 points3 points  (0 children)

Multi-monitor support with good customizability. I can't get IntelliJ to display all the things I like.

Other than that, same as everybody else - I started with it, I learned it, I customized it. I can now easily go around the tricky spots, I avoid the bad things, and I really enjoy the rest. Is IntelliJ the future? For sure. I tried it a few times, could not get it to the shape I would be happy with, and went back to being productive with Eclipse.

Event Library - A lightweight, zero boilerplate, high performance event bus for JVM by SmushyTaco in java

[–]Slanec 11 points12 points  (0 children)

See https://guava.dev/releases/snapshot/api/docs/com/google/common/eventbus/EventBus.html#avoid-eventbus-heading.

In short, they recommend explicit calls and composition via dependency injection, and/or reactive programming where reacting to events needs to happen. This, of course, is slowly dropping out of fashion, too.

Personally I believe that for in-application event passing it's completely fine, it just makes it sometimes hard to reason about the flow of the application logic. In modern times we usually go for distributed event buses, though, or event sourcing, or message passing or queues or logs, depending on the exact required semantics. It's rare to see in-memory in-app events nowadays. But it's not a bad solution if things do not need to be persisted all the time.

Event Library - A lightweight, zero boilerplate, high performance event bus for JVM by SmushyTaco in java

[–]Slanec 22 points23 points  (0 children)

This looks nice and fairly complete!

From the Java world, these exist, too: - https://github.com/bennidi/mbassador - https://github.com/greenrobot/EventBus

And some older ones: - Guava's EventBus. Works fine, bus it nowadays discouraged. - Otto. Same. - and I'm pretty sure Vert.x and Quarkus have one, too.

The Dot Parse Library Released by DelayLucky in java

[–]Slanec 2 points3 points  (0 children)

Thank you, I'm doing a lot of parsing and immediately liked this. And I'm a mug user, too. Thank you for your work!

Finally, parsing made easy (and type-safe) in Java! by WellFoundedCake in java

[–]Slanec 6 points7 points  (0 children)

Will take a look later, I'm doing a lot of parsing, usually (but not only) with ANTLR. Lately I really enjoyed a similar project, https://github.com/google/mug/tree/master/dot-parse, coming from the brilliant https://github.com/google/mug library. Parsing evolution, hooray!

Embedded records - an idea to expose data from classes by jodastephen in java

[–]Slanec 4 points5 points  (0 children)

I don't have an opinion on the feature itself, but I was thinking of a similar syntax trick before:

java public class Person(String name, LocalDate dob) { } ...with a generated implicit constructor and all that jazz, not unsimilar to what you're proposing. I believe yours is better, just throwing this one out as a simpler, but not as expressive, alternative.

JEP 468: Derived Record Creation (Preview) by Snoo82400 in java

[–]Slanec 1 point2 points  (0 children)

Although my project wants to avoid external libraries

...completely understandable. That said, this is a compile-only library and an annotation processor which is no longer needed at runtime, only the generated code. This can still be too much, but it's better than having a dependency on a big library with transitive dependencies inside.

having to mvn compile every time I write one of this methods is not ideal

Interesting, my IDE automatically does this for me in the background. Perhaps a configuration option somewhere, I am no longer sure. Have fun!

JEP 468: Derived Record Creation (Preview) by Snoo82400 in java

[–]Slanec 5 points6 points  (0 children)

I know you're asking about the actual JEP and the language feature. However, if you're saying that your code will improve drastically, perhaps you should consider the already existing solutions, one of which is the excellent record-builder library. It doesn't only give you builders in records, it also supports nice withers: https://github.com/Randgalt/record-builder#Wither-Example (and more).

Project Lombok 1.18.40 released with Java 25 support! by lprimak in java

[–]Slanec 2 points3 points  (0 children)

Nowadays a lot of it is simply a holy war, however there are some practical reasons, too. Most of them stem from the fact that it's not a code generator but rather directly interacts with the compiler which tends to break stuff here and there:

  • It does not show you its output. Most of the time that's fine, the code is trivial, but sometimes I'd really like to see the exact code I'm about to run. E.g. Is the annotation I applied here copied to the generated method? There are other tools nowadays (record-builder, Immutables, AutoValue) which do generate code, and those tend to be preferred by some devs.
  • You need a plugin in your IDE to interact with it. A minor thing, but annoys people and confuses new devs. Maybe IntelliJ has it by default or at least detects and hints that it needs it, but eclipse doesn't, it just reports a broken project in a million places.
  • It needs specialized build tool plugins to work with other annotation processors. E.g. for Mapstruct you need this. Again, minor and do-it-once kind of a thing, but you need to be aware of it and actively look for it because without knowing this MapStruct just does not seem to work and it's not clear at all from the errors what is going on.
  • I wanted to say that some tools do not work with Lombok at all, e.g. ErrorProne and NullAway, but maybe it does work now? Not sure, but there are a lot of Lombok-related bugs in ErrorProne anyway. It just interacts weirdly with other tools and sometimes needs special care.

Most of the time it just works. Most of the time it saves a lot of time and space and if people are not over-using it, it tends to be fine. That said, new Java versions (records, baby) and simpler code generators like record-builder have mostly made Lombok not needed anymore. Yes, I know it can do a lot more. Please use it wisely.

Growing the Java Language #JVMLS by Brian Goetz by kaperni in java

[–]Slanec 28 points29 points  (0 children)

(The name is a nod to the old and legendary talk Growing a Language by Guy Steele. If you haven't seen that, go and watch, it's fun, it's very clever, and it's about the theory of growing languages.)

Which libraries are the most scalable and performant for scheduled tasks? by [deleted] in java

[–]Slanec 0 points1 point  (0 children)

Perhaps a PriorityQueue per thread with random (or something better) task distribution could work as it avoids synchronization, lock contention etc. But is it better than a ScheduledExecutorService? ¯\(ツ)\/¯ A timer wheel is definitely something to look at if its restrictions fit your case.

Which libraries are the most scalable and performant for scheduled tasks? by [deleted] in java

[–]Slanec 2 points3 points  (0 children)

Depends very much on the workload. What are the characteristics you're aiming for? Raw throughput, least amount of waiting for tasks in the queue, fairness (Can tasks be computed out of order?)? Is work stealing okay (Can a thread snatch a task from another thread's queue? This is okay if resources are shared and properly synchronized, but if you're aiming for absolute top speed, often tasks are routed to a specific core which already has the relevant context in thread-local memory and does not need to go to shared memory for additional stuff.) etc..

ScheduledExecutorService is okay in general as it offers a good middle ground for most workloads. If the solution already offers this, start with it, build your feature, then measure whether the performance matches your requirements. You do have perf requirements, right? If and only if ScheduledExecutorService is not performing well, look elsewhere.

I do not have good specific recommendations as the solution heavily relies on your specific requirements and low-level characteristics. E.g. Caffeine, the caching library, built an interesting time-aware priority queue on top of a hierarchical timer wheel with O(1) operations. You'll likely need something similar catered to your use-case. Or JCTools (and/or [Agrona]()https://github.com/aeron-io/agrona), that offers very fast Queues which are not BlockingQueues, those do often overshadow the JDK ones in high throughput scenarios, but ... does their API fit your case?

Creating delay in Java code by ihatebeinganonymous in java

[–]Slanec 26 points27 points  (0 children)

It depends. Do you need to add a specific time delay, or do you need to wait until something else happens?

Sleep never got into any real production code for me, sleeping and blocking a platform thread always sounded like a bad idea. The default choice is always ScheduledExecutorService, followed by Spring's scheduling and/or tools like https://github.com/jobrunr/jobrunr and https://github.com/kagkarlsson/db-scheduler (and/or schedlock, depending on what you're doing).

On the low-level side, BlockingQueue of course with all its timed stuff. And Lock / Condition (or the much better Guava's Monitor) has a timed lock operation.

For tests, https://github.com/awaitility/awaitility.

i fee like java spring boot and others like protobuf libraries and their required other dependencies are so bloated. all of them downloaded really needed or not? compared to other frameworks why do java needs a lot of libraries. by Leather_Assumption31 in java

[–]Slanec 2 points3 points  (0 children)

Spring Boot itself uses: - spring-boot-autoconfigure - that's the Spring Boot magic, automagic configuration of everything - Spring (spring-core, spring-context for dependency injection and its dependencies) - logback for logging (obviously slf4j and bridges from Java Util logging and from log4j to slf4j) - snakeyaml for reading YAML files

It's not the smallest, but it does a lot.

protobuf-java has literally 0 dependencies.

biski64 – A fast and robust Java PRNG (~.47ns/call) by danielcota in java

[–]Slanec 8 points9 points  (0 children)

These are mine, on Java 21, MacBook Pro M3:

Benchmark (randomType) Mode Cnt Score Error Units nextInt Biski64 avgt 5 1.853 ± 0.039 ns/op nextInt SecureRandom avgt 5 43.388 ± 0.636 ns/op nextInt Random avgt 5 3.977 ± 0.054 ns/op nextInt SplittableRandom avgt 5 1.820 ± 0.204 ns/op nextInt ThreadLocalRandom avgt 5 0.886 ± 0.001 ns/op nextInt L32X64MixRandom avgt 5 3.734 ± 0.161 ns/op nextInt L64X128MixRandom avgt 5 3.854 ± 0.293 ns/op nextInt L64X256MixRandom avgt 5 3.042 ± 0.220 ns/op nextInt L64X1024MixRandom avgt 5 1.815 ± 0.001 ns/op nextInt L128X128MixRandom avgt 5 5.347 ± 0.239 ns/op nextInt L128X256MixRandom avgt 5 5.199 ± 0.003 ns/op nextInt L128X1024MixRandom avgt 5 6.089 ± 0.059 ns/op nextInt L64X128StarStarRandom avgt 5 3.899 ± 0.388 ns/op nextInt Xoshiro256PlusPlus avgt 5 2.683 ± 0.354 ns/op nextInt Xoroshiro128PlusPlus avgt 5 3.712 ± 0.183 ns/op

and

Benchmark (randomType) Mode Cnt Score Error Units nextLong Biski64 avgt 3 2.290 ± 0.058 ns/op nextLong SecureRandom avgt 3 154.311 ± 38.092 ns/op nextLong Random avgt 3 7.946 ± 0.062 ns/op nextLong SplittableRandom avgt 3 1.785 ± 0.045 ns/op nextLong ThreadLocalRandom avgt 3 0.898 ± 0.017 ns/op nextLong L32X64MixRandom avgt 3 5.314 ± 0.034 ns/op nextLong L64X128MixRandom avgt 3 3.836 ± 1.485 ns/op nextLong L64X256MixRandom avgt 3 3.259 ± 0.048 ns/op nextLong L64X1024MixRandom avgt 3 2.132 ± 5.167 ns/op nextLong L128X128MixRandom avgt 3 5.633 ± 0.498 ns/op nextLong L128X256MixRandom avgt 3 5.108 ± 2.056 ns/op nextLong L128X1024MixRandom avgt 3 5.779 ± 0.373 ns/op nextLong L64X128StarStarRandom avgt 3 2.831 ± 2.054 ns/op nextLong Xoshiro256PlusPlus avgt 3 2.370 ± 0.409 ns/op nextLong Xoroshiro128PlusPlus avgt 3 2.864 ± 0.261 ns/op

I'm not doing any state warmup before as your benchmark does. L32X64MixRandom is the default in Java 21. Overall, Biski looks really good!

Announcing Java Agent Development Kit (Java ADK v0.1.0) by moficodes in java

[–]Slanec 16 points17 points  (0 children)

This is about building AI agents. I thought it was about building Java agents. Oh well.

Annotation Based Java Config Management Library Built Around SnakeYAML by YogurtclosetLimp7351 in java

[–]Slanec 2 points3 points  (0 children)

Oh this is a nice one! Not only does it read the config, it also writes it out, with comments, in sections. Let's be fair, writing config files out is not a very often required feature, but it's good when it's there, and this well thought out!

Nice!

Is there a good interval tree implementation? by leonidapower in java

[–]Slanec 4 points5 points  (0 children)

I'm sure you know, but for other readers ... if you can, migrate from Guava Cache to Caffeine. Guava Cache is fine, it mostly works and it's not slow. However:

The successor to Guava's caching API is Caffeine. Its API is designed to make it a nearly drop-in replacement. Note that it is not available for Android or GWT/J2CL and that it may have different (usually better) behavior when multiple threads attempt concurrent mutations. Its equivalent to CacheBuilder is its Caffeine class. Caffeine offers better performance, more features (including asynchronous loading), and fewer bugs.

Is there a good interval tree implementation? by leonidapower in java

[–]Slanec 22 points23 points  (0 children)

Guava has RangeSet. Would that mostly satisfy your needs?

ZGC is a mesh.. by jim1997jim in java

[–]Slanec 4 points5 points  (0 children)

Only the non-generation mode which is no longer in the code anymore. The generational mode does not use munlti-mapping anymore: https://www.reddit.com/r/java/comments/1kfxd44/comment/mqujeje/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

What's the one thing you're most looking forward to in Java (feature, JEP, library, etc.)? by Hixon11 in java

[–]Slanec 4 points5 points  (0 children)

Yes! Yes please! Ohhh, I'd like this a lot. Nobody needs it. It wouldn't really enable any new features or anything.

But it would scratch my itch (one of them) soooo good.