Upgrade process from java 8 to java 21

I tried to do this in parallel of some other things this morning but then i had to focus on another task :downcast_face_with_sweat:

You are perfectly right, this is a side effect of the automatic refactoring performed by openrewrite. I fixed these cases locally

Just a note, I had trouble compiling Orekit in java 21 with intelliJ. It’s a known problem which requires some manual action. See here

Cheers,
Romain.

Pipeline is finally green with an exact 95.0% coverage, ready for merge :melting_face:

Merge request set to auto merge following latest update on develop branch :champagne:.

As a follow up, would you agree with using var as well @orekit_dev_team ? I would do another merge request for this. It may be very interesting for field related classes.

Cheers,
Vincent

Thanks vincent.

I do like var personnally, but I would restrict its use only when the type is obvious (call to constructor, cast)

Cheers,
Romain.

Indeed that is where it is the most redundant. In case we at least agree on that, i’ll take a look and see how to do this for obvious cases only

First of all, thank you @Vincent for the upgrade.

I’m not a Java expert and have no personal opinion on the use of var. So I innocently googled “Is it better to use var in java” to have some opinions. The three first results [1], [2] and [3] converge on the same remark: var parameter should only be used where the code is already perfectly understandable (e.g. variable name perfectly reflecting what the object is) and clear. If the code is not perfectly understandable, so the var should be avoided.

I was surprised to not see Baeldung website result since I consider it as a good reference for Java tips and good practices. So I search on the website and found an interesting article [4]. This article also highlights that var shall be used carefully and provide some guildelines (Chapter 4).

Finally, I asked ChatGPT (I’m sorry for people that don’t like AI). I asked the question: “Is it recommended to use “var” type in Java?” Please find the answer below:

In modern Java, var is generally recommended when it improves readability, but not as a blanket replacement for explicit types.

Java introduced local variable type inference with var in Java 10. It lets the compiler infer the variable type from the initializer.



Example:

var message = "Hello";   // inferred as String

var count = 42;          // inferred as int



When var IS a good idea

1. The type is obvious from the right side

var users = new ArrayList<User>();

This avoids repetition without hurting clarity.



2. Long generic types

var map = new HashMap<String, List<Order>>();

This is cleaner and easier to read.



3. Streams and iterators

var entry = map.entrySet().iterator().next();

The explicit type would add noise.



When var is NOT recommended

1. The type is unclear

var result = process(data);

What is result? A String? List<User>? Optional<Order>?

Explicit types are better here:

OrderResult result = process(data);



2. Primitive confusion

var number = 1;   // int, not long

Inference may not match your intent.



3. API/public code readability suffers

If another developer must mentally infer the type, readability decreases.


So, based on my Google researches, my opinion is that we have to be careful on the use of var and limit it to the cases where it is useful, applicable, and with no decrease on the code understability. In addition, since Orekit is an open source library for which the code can be read by users, we shall be strongly careful on the use of var.

[1]: https://www.reddit.com/r/java/s/tHvh6aAqIa

[2]: https://medium.com/@spextreme/java-var-should-be-a-code-smell-17af0be79646

[3]: https://groups.google.com/g/project-lombok/c/JiAEGIcgFO4

[4]: https://www.baeldung.com/java-10-local-variable-type-inference

Thanks Bryan for the analysis. I agree with careful use of var.

I’m not familiar with the use of var in Java, but C++ has a similar convention (auto) and in general I found that auto/var is very handy in cases where the variable use scope and general type are clear, but writing out the exact type is cumbersome for the user (for example, the iterator value for a loop that is moving through a vector containing complex template values). Otherwise I prefer to type variables explicitly.

I was not able to do this.
On a Debian system, I tried to install ecj (using aptitude install ecj) and then set the path in IntelliJ to /usr/bin/ecj, which is a shell script invoking the compiler. It failed with IntelliJ saying it could not find the compiler. I then tried to set the path to the jar file referenced in the shell script. It failed too.

[edit]
I finally succedeed, using this:

mvn dependency:get -Dartifact=org.eclipse.jdt:ecj:3.45.0

and then putting /home/luc/.m2/repository/org/eclipse/jdt/ecj/3.45.0/ecj-3.45.0.jar in the Path to ECJ batch compiler tool text field in IntelliJ configuration.

I’m -0 for using var because I think it would make the code harder to read, and readability is a big part of maintainability, which is Orekit’s second priority, after correctness.

When I’m reading code I’ll ctrl-click on a variable name or type K to bring up the documentation for it. Then I can look to the left of the equals to determine it’s type. With var there would be another step where I have to look to the right and try to run part of the compiler in my mind to try to figure out the type. Even if it’s simple, like a string literal, it’s still an extra step.

As for writing code, I don’t think var really saves any typing. IDEs are quite good at predicting what I want to type now. I rarely type more than three characters of a class name before the IDE completes it for me.

That said, I haven’t used var in Java, but similar concepts in other languages such as javascript and Python leave me feeling a bit confused about the types of variables. So I’ll sit out using var and see if I can find an IDE feature to expand var to its inferred type to make reading the code a bit easier.

Regards,
Evan

I do agree that current IDEs are powerful enough to handle the verbose part of Java. I also personnally think that var decreases readability.

Given the previous answers, I would suggest leaving it as it is for now. We can always revisit the topic later. I think it might be more interesting for me to look into migrating from JUnit 5 to JUnit 6. I’ll do some research first to see whether it’s worth it.