Skip to content

Conversation

gnodet
Copy link
Contributor

@gnodet gnodet commented Apr 25, 2025

This PR includes several improvements to modernize the codebase:

  1. Replace IllegalArgumentException with ClassCastException for type cast failures
  2. Replace IllegalArgumentException with NullPointerException for null checks
  3. Use modern Java collections API (toList() instead of collect(Collectors.toList()))
  4. Replace custom null checks with Objects.requireNonNull
  5. Add @nonnull and @nullable annotations throughout the codebase

These changes make the code more maintainable, safer, and aligned with modern Java practices.

@kwin
Copy link
Member

kwin commented Apr 27, 2025

Regarding point 2. (and the related point 4.): I consider the IAE more concise than an NPE in case a method argument is passed with null (although not allowed). Compare also with https://discuss.kotlinlang.org/t/why-does-requirenotnull-throw-an-illegalargumentexception/7617/4

@desruisseaux
Copy link
Contributor

I think that the main argument in favour of NullPointerException is consistency. Not all methods perform explicit null checks. Especially since JEP 358: Helpful NullPointerExceptions provides even more helpful messages than many explicit null checks. Therefore, if Objects.requireNonNull was throwing IllegalArgumentException for a null argument, we would be at risk of having sometime an IllegalArgumentException, and sometime a NullPointerException, depending on whether the method chooses to perform explicit null checks or not. It would also be a risk of compatibility break if the method implementation changes its strategy over time.

@gnodet gnodet force-pushed the refactoring branch 2 times, most recently from c52c814 to b071032 Compare May 1, 2025 05:56
@Pankraz76
Copy link
Contributor

Pankraz76 commented May 1, 2025

  • Use modern Java collections API (toList() instead of collect(Collectors.toList()))

Hi folks, please check out attached openrewrite link as its related and some can be done by computer.

This could be supplemented in dedicated PR as there is a migration for this:

Maybe we can team up with as its kind of related. The migration is "free" as done by one click so we can reproduce anytime.

@Pankraz76

This comment has been minimized.

@Pankraz76

This comment has been minimized.

@Pankraz76

This comment has been minimized.

@Pankraz76

This comment has been minimized.

@gnodet
Copy link
Contributor Author

gnodet commented May 2, 2025

its nice to fix this once, but without a computer checking and enforcing this by some tool like checkstyle or rewrite, its not completed.

I don't see where it's done in your PR as it only provides the result of executing the transformation.

@@ -337,7 +335,7 @@ public LocalRepository getLocalRepository() {
@Nonnull
@Override
public Session withLocalRepository(@Nonnull LocalRepository localRepository) {
nonNull(localRepository, "localRepository");
Objects.requireNonNull(localRepository, "localRepository cannot be null");
Copy link
Contributor

@Pankraz76 Pankraz76 May 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current State of NullPointerException Handling

The current implementation around NullPointerException is not ideal, but in context, it's clear what's happening.

Options:

  1. Keep it as-is
    • Works but lacks elegance.
  2. Remove all such checks
    • Simplifies but loses explicit null-check messaging.
  3. Refactor into a dedicated layer
    • Separate the "cannot be null" concern to avoid:
      • DRY violations (repetition)
      • Feature envy (fluff and copy-paste)

Proposal: Dedicated Logging Layer

If improved logging is desired, this concern should be moved to a dedicated utility layer, similar to Apache Maven's approach:

throw new IllegalArgumentException(name + " cannot be null");

Benefits:

  • Contextual clarity: Right now, the check is just a short "non-null" hint.
  • Better debugging: Explicit messaging improves NullPointerException readability.
  • Consistency: Centralized handling avoids duplication.

This change is already reflected in PR #2290.


@@ -134,7 +132,7 @@ public AbstractSession(
List<RemoteRepository> repositories,
List<org.eclipse.aether.repository.RemoteRepository> resolverRepositories,
Lookup lookup) {
this.session = nonNull(session, "session");
Copy link
Contributor

@Pankraz76 Pankraz76 May 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current State of NullPointerException Handling

The current implementation around NullPointerException is not ideal, but in context, it's clear what's happening.

Options:

  1. Keep it as-is
    • Works but lacks elegance.
  2. Remove all such checks
    • Simplifies but loses explicit null-check messaging.
  3. Refactor into a dedicated layer
    • Separate the "cannot be null" concern to avoid:
      • DRY violations (repetition)
      • Feature envy (fluff and copy-paste)

Proposal: Dedicated Logging Layer

If improved logging is desired, this concern should be moved to a dedicated utility layer, similar to Apache Maven's approach:

throw new IllegalArgumentException(name + " cannot be null");

Benefits:

  • Contextual clarity: Right now, the check is just a short "non-null" hint.
  • Better debugging: Explicit messaging improves NullPointerException readability.
  • Consistency: Centralized handling avoids duplication.

This change is already reflected in PR #2290.


@gnodet
Copy link
Contributor Author

gnodet commented May 3, 2025

@Pankraz76 I'm not sure what you aim for with your PRs. How do they differ from this one ? It's fine very fine that you used openrewrite rules, but isn't the result the same at the end ?

@Pankraz76

This comment has been minimized.

Copy link
Contributor

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Use modern Java collections API (toList() instead of collect(Collectors.toList()))" is riskier than the other changes because of the move of mutable to immutable lists. Nine times out of ten this is fine. The tenth time it's a bear to debug. These changes should be pulled out into a separate PR.

The rest could be split, but maybe don't have to be. Nuulable and Nonnull might also call for a separate PR.

@Pankraz76

This comment has been minimized.

@Pankraz76
Copy link
Contributor

Regarding point 2. (and the related point 4.): I consider the IAE more concise than an NPE in case a method argument is passed with null (although not allowed). Compare also with https://discuss.kotlinlang.org/t/why-does-requirenotnull-throw-an-illegalargumentexception/7617/4

Java and Lombok prefer NPE as well.

https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#requireNonNull-T-

https://projectlombok.org/features/NonNull

both valid points. Ideally its just one config-switch to adjust:

image

@gnodet
Copy link
Contributor Author

gnodet commented May 11, 2025

There 's no plan to use Lombok at this point.

@Pankraz76

This comment has been minimized.

Pankraz76

This comment was marked as resolved.

@@ -461,12 +459,12 @@ public org.eclipse.aether.artifact.Artifact toArtifact(ArtifactCoordinates coord

@Override
public void registerListener(@Nonnull Listener listener) {
listeners.add(nonNull(listener));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is dedicated in:

if possible lets merge this first as this is kind of huge.

Pankraz76

This comment was marked as resolved.

@Pankraz76

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants