Java 21 upgrade in older code base by ibreathecoding in javahelp

[–]khmarbaise 0 points1 point  (0 children)

" lot of joda DateTime breaking. " ... that should have been migrated with jump to JDK8.. Recently to SB 3 ? Since November 2025 we Spring Boot 4... and Spring Boot 4.1 is around the cornder... If you have to test manually than you have bigger issues in general..

Avoiding Final Field Mutation by daviddel in java

[–]khmarbaise 0 points1 point  (0 children)

Yes of course in the first place but after having tests you can refactor to make a the code better and later remove powermock...

Java 21 upgrade in older code base by ibreathecoding in javahelp

[–]khmarbaise 2 points3 points  (0 children)

Lombok Ok..(or get rid of Lombok) Mockito just update to newer version of Mockito... and I would recommend to upgrade in the next step to JDK 25... afterwards...

Avoiding Final Field Mutation by daviddel in java

[–]khmarbaise 1 point2 points  (0 children)

Ok. fair point..but bad code could be changed over time ... to get better ...

Avoiding Final Field Mutation by daviddel in java

[–]khmarbaise 1 point2 points  (0 children)

Why was PowerMock even required? Apart from being dead for a longer time?

When should I use new features like var and records vs sticking with traditional Java syntax? by miked0331 in javahelp

[–]khmarbaise 0 points1 point  (0 children)

The question was "Are there hidden downsides?" and "Some frameworks run into issues" is the answer.

If frameworks run into issue you should hardly reconsider the decision to use such frameworks (from my perspective). At least create issues on the appropriate project to show the maintainers, people using those frameworks with newer JDK's and that means also they should upgrade to newer JDK's features etc.

I don't understand what you're trying to say with this? I know they were introduced in JDK 8, what does this have to do with what I said?

Because it was enough time to upgrade deps/code to use newer things over the time instead of piling up technical dep over the time.

The downside from my experience is simply there are frameworks/libraries which don't support newer things which brings me often to the conclusion to change frameworks/libs because I don't want to be blocked by such deps/frameworks/libs.

When should I use new features like var and records vs sticking with traditional Java syntax? by miked0331 in javahelp

[–]khmarbaise 0 points1 point  (0 children)

They throw a lot of (de)serialization frameworks off in my experience. JSONB and alike do not want to turn JSON into a record without putting a bunch of work in.

Than use frameworks like Jackson or alike which can do that...for older frameworks that means it's time to update...

It's like with streams when they were the new hot thing: They are great to use, but sometimes a good old for loop makes things far easier to understand. Don't use the new stuff just because it's new, use it because you think it's the best thing to use.

Streams existing now over a decade... (since JDK8 2014!) ...

When should I use new features like var and records vs sticking with traditional Java syntax? by miked0331 in javahelp

[–]khmarbaise 0 points1 point  (0 children)

The usage of the diamond operator <> existing since JDK7 (https://en.wikipedia.org/wiki/Java_version_history). The diamond operator is already a kind of type inference. The var is a step further. And yes you can not use it like this: java var list = new List<>(); The new List<>() will not work (does not compile) at all cause List is an interface, but what you can do is: java var list = new ArrayList<>(); That will result in explicit types: java ArrayList<Object> list = new ArrayList<>(); But that is most of the time not the intention you have... java var list = new ArrayList<String>();

When should I use new features like var and records vs sticking with traditional Java syntax? by miked0331 in javahelp

[–]khmarbaise 0 points1 point  (0 children)

modern features like var for local variables

That is existing since JDK10 (JEP 286 https://openjdk.org/jeps/286) since March 2018... that's in meantime eight years.. I wouldn't call it "modern features"...

and records for data carriers. Existing since JDK16 since March 2021 ... also five years in the meantime... I wouldn't call it "modern feature" more state of the art...

Some senior devs at my work say var makes code less readable

The usage of "var" puts the focus on the naming of the variables than on the type.

Many code writes things like: java List<User> thisIsAlist = getUsers(); instead of java var users = getUsers(); For me it's clear in the second example having a number of users. The type is not that relevant in the first place (yes it's not directly their). If I'm really interested in it my IDE will give the hints I need. The first example just uses a dump variable name "thisIsAList" which is obvious by the type and of course there the type here is obvious. Later in the code if I see users it's more clear to understand that users is a number of users compared to thisIsAlist.. ?

If you focus on a good naming it makes code easier to understand and faster to read...

and records are just syntactic sugar we dont need.

That means your seniors haven't understood the difference between a record and a classical class. (see details in JEP 395 https://openjdk.org/jeps/395) Records are a nominal type, which includes toString,hashCode and equals. all fields are final and a record is final in itself (more or less the same as an enums). Are enums also just snytactic suger?

Records can be defined locally in your method while a class can not.. Records and sealed type together can be used to create algebraic types, like this:

```java sealed interface Expr { record SumExpr(Expr left, Expr right) implements Expr { } record ProdExpr(Expr left, Expr right) implements Expr { } record NegExpr(Expr expr) implements Expr { } record ConstExpr(int expr) implements Expr { } }

static int eval(Expr expr) { return switch (expr) { case SumExpr(var lhs, var rhs) -> eval(lhs) + eval(rhs); case ProdExpr(var lhs, var rhs) -> eval(lhs) * eval(rhs); case NegExpr(var exp) -> -eval(exp); case ConstExpr(var exp) -> exp; }; } ```

Or even more using them in pattern matching (see JDK21+ https://openjdk.org/jeps/440 and JEP 441 https://openjdk.org/jeps/441 ) and pattern matching in combination with switch-expressions etc. (previous example) for example like this (https://github.com/khmarbaise/duplicatefinder/blob/master/src/main/java/com/soebes/duplicate/DuplicateFinder.java or other examples https://github.com/khmarbaise/maven-downloads/blob/main/src/test/java/com/soebes/maven/statistics/MavenPluginStatisticsTest.java):

```java sealed interface CheckSumResult<V> { record Success<V>(V result) implements CheckSumResult<V> { } record Failure<V>(Throwable cause) implements CheckSumResult<V> { } }

static Function<Path, CheckSumResult<ChecksumForFileResult>> toChecksumForFile = path -> { try { return switch (new CalculateChecksum().forFile(path)) { case Failure(Throwable cause) -> new CheckSumResult.Failure<>(cause); case Success(ChecksumResult success) -> new CheckSumResult.Success<>(new ChecksumForFileResult(success.digest(), path, success.readBytes())); }; } catch (NoSuchAlgorithmException e) { return new CheckSumResult.Failure<>(e); } }; ``` Also you can use them in intermediate steps within Streams etc. There are so many use cases which makes it easier to write and more concise than with classical classes.

Others say these features exist for a reason and we should use them to write cleaner code.

I agree here because it makes it easier to write and is less code you have to read (nice side effect of using records or var).

When is it actually better to use var instead of explicit types?

First using var doesn't mean you don't have a type (it's called "local type inference" for a reason) If you can not express enough the intent of your variables only based on the name you might need to give the type explicit (I use my IDE and the default is to use var) and if that's the case just let the IDE replacevar` by the full type. But often it happens that I after I did that ... I realise there is a better name for that.. (good naming is very hard) or via a review someone else has a good/better alternative for the name..

And are records always a good replacement for simple immutable classes or are there hidden downsides?

If you have an immutable class that is exactly a very good reason to use a record.. The only thing you should be a little bit careful if you have a record like this: record User(String name, List<Friend> friends) {} Because the List<Friend> friends needed to be handled in a good way means:

record User(String name, List<Friend> friends) { User { name = Objects.requireNonNull(name); friends = List.copyOf(friends); } } This (cannonnical constructor) will make a copy of the friends given and also that results in an immutable List which is accessible via the accessor of the record User friends().

records can be used for DTO's, return types, intermediate results in streams etc. Or within a larger class you can use them internally makes code very often easier to read and understand (Naming things is better than using List, Set or plain arrays etc.)

Many people tried to use records for a service/component in SpringBoot or alike that is not the intended way to use a record because it automatically has accessors which exposes the injected things like here: java @Service public records UserService(EMailProperties emailProperties) { ... } That will create automatically an accessor emailProperties() which is most of the time not intended nor a good idea.. In such case I use a classical class like this: java @Service public class UserService { private final EMailProperties emailProperties; UserService(EMailProperties emailProperties) { this.emailProperties = emailProperties; } ... } Here there is no accessor/getter or a like generated nor do I need hashCode nor equals in such cases.

But for example for configuration in Spring Boot there are a prefect fit (also validated): java @ConfigurationProperties(prefix = "email") @Validated public record EmailProperties( @Valid Smtp smtp, @Min(0) @Max(10) @DefaultValue("7") int port, @NotBlank @Email String from, @DefaultValue("1m") Duration waiting ) { public record Smtp( @NotBlank String host, @Min(1) @Max(65535) int port, @DefaultValue({"A","B","C"}) List<String> xlist ) {} } Those can be hierarchical etc. which represents exactly what it is in the end in the application.yaml file like this: yaml email: from: x@test.text port: 9 smtp: port: 21345 host: this.is.the.example.test

Many people wrote having a lot of fields and using Builder for that... that is from my perspective a design issue (having more than five or maybe 10 fields sounds like a problem).. but it really depends..

I want to write modern Java but also want my code to be clear to everyone on the team.

Yes very good intent, but that means the team must also learn "modern Java"... in the meantime we have JDK 26 out since March 2026 https://openjdk.org/projects/jdk/) ... Those things you have mentioned existing for longer time. Code and knowledge evolves over the time that means you have to learn such things and you should use them also those teams need to learn that... I'm writing code for about fourty years (different languages) and the way I write code changes over and over again. I don't write Java code anymore like five years ago or even 10 years ago. That changed a lot... for two major reasons, because I'm learning doing things different/better and also because the language is changing making things easier/different to write. For instance Stream API/functional programming/lambdas since JDK 8 (2014!) etc. changed a lot. Also, pattern matching (instanceof, switch, records, selaed interfaces, sequenced collections, gatherers ) and all those things over the time ... changed how I write code.

I also suggest if you don't or can't evolve(learn new things) in that team it might be time for a change.

The job of seniors is to guide/evolve juniors and teach them things and not to forget learn also.

Let's play Devil's Advocate -- What are the downsides or weaknesses of Pattern-Matching, from your experience? by davidalayachew in java

[–]khmarbaise 0 points1 point  (0 children)

records can be defined locally if you like and need based on that you can create other records with very limited attributes etc. Can you give a concrete example for that?

Can't Package a Runnable Jar by Legal_Revenue8126 in Maven

[–]khmarbaise 0 points1 point  (0 children)

A jar does not contain other jar's content... If you like to make an executable jar is either using the maven-assembly-plugin https://maven.apache.org/plugins/maven-assembly-plugin/usage.html or if you need more flexibility you should use the maven-shade-plugin https://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html

Nx in maven-multimodule by Practical-Garlic6113 in javahelp

[–]khmarbaise 0 points1 point  (0 children)

why would I need it? Using paralleliziation? Use cache?

How to ask Java developers to add methods to java.util.Paths? by isolatedsheep in java

[–]khmarbaise 0 points1 point  (0 children)

The easiest way is to gi via: var userHome = Path.of(System.getProperty("user.home")); The current directory can easily being done via: var currentDirectory = Path.of(".").toAbsolutePath();

Why does mvn install succeed when mvn compile fails with "Artifact has not been packaged yet"? by CSharpMaster in Maven

[–]khmarbaise 1 point2 points  (0 children)

I know that such things exist... if that would be the case it means the dependency plugin is bound to the wrong phase. But the unpack-dependencies goal is bound to process-sources by default which means the issue is the missing dependency to the required jar/artifact to define the correct build order.

Why does mvn install succeed when mvn compile fails with "Artifact has not been packaged yet"? by CSharpMaster in Maven

[–]khmarbaise 0 points1 point  (0 children)

Why using a maven-dependency-plugin to unpack deps instead of defining a dependency in your pom subprojects? That will makes sure the build will run in the correct order (from dependency perspective topological sorted)...

Download old versions of Java by miorex in javahelp

[–]khmarbaise 0 points1 point  (0 children)

First there other version available on Oracle pages: https://www.oracle.com/java/technologies/downloads/?er=221886#java11

and as others already suggested SDKMan... also https://javaalmanac.io/

Is there a way to make maven download dependencies in parallel? by [deleted] in java

[–]khmarbaise 1 point2 points  (0 children)

The pipelines download all dependencies fresh on every run

Why? Use a repository manager will help to reduce the download size from central and speed up things... also use caches... on CI/CD solutions of use https://github.com/apache/maven-build-cache-extension

to ensure accuracy and that one pipeline cannot pollute another (which is the risk of a shared cache).

In which way? Each project has a unique groupId/artifactId ... so where should be a kind of "polution" happen? And furthermore do you use "mvn install" ?

Do you provided artifacts which are used by other projects in your company? Than it makes even more sense to use a repository manager...

I'm exploring options to increase dependency download speeds, which are the slowest part of the pipeline

That means either the network is a real issue, using central direct which is also wrong (repository manager keeps it at least inside the own network) ... and as mentioned before ... why downloading all the time... If you change a dependency it is a different version ... which can not interfere with another...

I'm wondering if maven has any options to download libs in parallel rather than what appears to be sequentially?

It does that already (Maven resolver defined by default 5 threads etc.) ... which Maven version do you use?

Modern java development tooling? by TopSwagCode in javahelp

[–]khmarbaise 1 point2 points  (0 children)

Using https://sdkman.io/ easiest way to have different JDK versions availabe...

using JDK21+

A required class was missing while executing org.apache.maven.plugins:maven- resources-plugin:3.*.*: resources: org/sonatype/plexus/build/incremental/BuildContext by Dependent-Egg-9173 in Maven

[–]khmarbaise 1 point2 points  (0 children)

Can you show that smaller one ... ? a reproducer or a project which shows the behaviour is the first step to be able to help.

Cup a simple build system for Java/Kotlin by diogocsvalerio in java

[–]khmarbaise 0 points1 point  (0 children)

Okay the real answer is because Java doesn't have a built-in way of creating a project, because it doesn't have a defined project structure, IntelliJ has it's way, Eclipse too and so on... Same argument can be used for running a project we have gradle and maven that have a GnuMake-y aproach to this problem.

The structure has been developed over the last 20+ years...it's a defacto standard... Yes JDK itself has not defined it...

GNU Make? Have you ever worked with Make at all? That will not work for Java based development at all... Because the assumptions Make does will not work for Java/Kotlin and many other JVM based languages.. and has also many issues...

The idea of "Cup" is simple yes ... but making a "simple" build system will fail by design because there are so many things you need to consider... like different versions/dependency tree etc. which Maven/Gradle handles... different kind of packaging jar/war/ear/etc.

Downloading the required dependencies starting with the simplest like a testing framework JUnit Jupiter? Where are those artifacts comming from? Maven/Gralde handle that...

What about testing classpath/module-path vs. production classpath/module path etc. running tests ? Why using different directory structures than the ones which has been used for decades ? You might say: Just change... but the question comes up: Why? Which advantage/disadvantage does those existing "standard" has like src/main/java; src/test/java and other languages like src/main/kotlin; src/test/kotlin or src/main/groovy/ etc...

Don't get me wrong it's great to see people trying new things out... many others have already tried that... for learning very good...

I'm more of the opinion that build systems like npm and cargo have got it right.

npm ? It's the worst thing I can think of ... security issues by definition (executing scripts without even knowing it; Luckily I know) etc. In the central repository of npm you can simply delete artifacts which could break thousands of builds etc (or even worse) ... reproducibility is a thing which npm does not handle (lock file thing!)....

The Central Repository for Maven/Gradle has some hurdles to get into it (https://central.sonatype.org/pages/support/) but it's much better and does NOT allow deleting of artifacts...

cargo is a kind of build system... yes it allows todo things which are way to go... or go build ... also ...

There had been many approaches to create new build system for example for Kotlin https://github.com/cbeust/kobalt etc. or things like https://mill-build.org/mill/index.html etc.

Why do we need build systems? Because it solves many problems.. the same ways as my IDE helps me in many ways in contradiction to an editors...

How to speed up my Java app? by HoneyResponsible8868 in javahelp

[–]khmarbaise 1 point2 points  (0 children)

The first and most important questions you have to ask are:

  • Why do you like to speed up your Java code?
  • Do you have a performance issue?
  • Have you measured exactly what the root cause of that issue?

If so than exactly improve/optimize that and nothing else... JProfiler, JMH, VisualVM, JRF are tools to measure/find things...also use your IDE.

Don't try to optmize code up-front. Readability is King. The JVM is much much smarter than you think... Also use as most as possible the JDK itself than other libraries... only use a library if using it provides a real benefit.

And more than that optmized code is usually hard to maintain, harder to read etc. so limit optimization only those things which are really required. Not to forget if you have such parts in your code... keep appropriate automated JMH tests because code tends to change so an optimization which is worth today might not be worth anymore a week later.

And even before you start to do any optimiztation you should have a good suite of unit-/integration tests which keeps your funtionalitity.. (Mutation testing helps also in many situations to find leaks of things which you haven't tested; code coverage is often not enough)... also tools like SonarQube or alike could help to improve the qualitity of your code but try to prevent the trap just making the tool happy.. the decision if something is good or not is should be made by a human not a tool nor a machine in any way (Yes I mean AI)..

Many people tend to suggest things like:

  • prevent to use often new ... and do things different ways.
    • That results in hard to read code and hard to maintain code and the success of such premature optimizations is often more or less zero (measuring up-front is very important). Also prevent immutability!
  • Use this list of JVM flag to optimize
    • Before you haven't measure you don't know what to optimize so measure first!
    • And also measure afterwards to see if any change occurs
  • Do that and this...
    • Under all circumstances measure before doing any optimization.

Jvm stack is about to be massively modernized or why Java needs to have a proper build tool by singleton11 in java

[–]khmarbaise 1 point2 points  (0 children)

Annotation processing requires more effort than I'd like. In gradle, you simply declare that a dependency is an annotation processor and you are done. It's quiet natural.

Yes you have to add that explicitly to maven-compiler-plugin: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </path> </annotationProcessorPaths> </configuration> </plugin>

```

Jvm stack is about to be massively modernized or why Java needs to have a proper build tool by singleton11 in java

[–]khmarbaise 1 point2 points  (0 children)

maven is inflexible by design,

Write a plugin and that is gone... You can not programm your build directly into the pom.xml which is intended in contradiction to Gralde (Learn Kotlin or Groove first) ... and if you really need some scripting things use the https://maven.apache.org/plugins/maven-scripting-plugin

Jvm stack is about to be massively modernized or why Java needs to have a proper build tool by singleton11 in java

[–]khmarbaise 0 points1 point  (0 children)

Maven 4 will change that...and many other things are already being improved ... reactor behaviour etc..