Skip to content

[MNG-8696] PathModularizationCache needs to set cache #2219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

elharo
Copy link
Contributor

@elharo elharo commented Apr 2, 2025

…o a public constructor in DefaultDependencyResolverResult. It only hasn't failed yet because we're only passing null for this argument but there's a TODO to change that.

Alternatively, we could remove PathModularizationCache from the DefaultDependencyResolverResult.

…o a public constructor in DefaultDependencyResolverResult
@desruisseaux
Copy link
Contributor

Alternatively, we can make the constructor package-private and add another constructor without the PathModularizationCache argument, which would delegate to the package-private constructor with a null argument.

A few months ago, a started a branch where I tried to reduce the visibility of some Maven internal classes. It required moving some classes to a common package (in this case, we would need to move DefaultProjectBuilder). I did not explored further because of conflict with other changes, but generally I would prefer going in the direction of removing some public items instead of adding more.

@elharo
Copy link
Contributor Author

elharo commented Apr 2, 2025

Yes, if we can move more classes into the same packages we can reduce visibility of a lot of things. Excessive proliferation of subpackages is a major antipattern in Java that leads to excessive visibility. It's probably second only to IDEs that mark classes and methods public by default.

@gnodet
Copy link
Contributor

gnodet commented Apr 3, 2025

The DefaultDependencyResolverResult does not really respect the @Immutable contract which is on Result<REQ>.
It may be better refactored in a different class that would be package protected, contains the addDependency and addOutputDirectory, while the DefaultDependencyResolverResult would be kept immutable.

Copy link
Contributor Author

@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.

PTAL. Took @desruisseaux 's suggestion to make the constructor package-private and add another constructor without the PathModularizationCache argument, which delegates to the package-private constructor with a null argument.

@elharo elharo marked this pull request as ready for review April 19, 2025 13:51
@elharo elharo changed the title PathModularizationCache needs to be public because it's an argument t… [MNG-8696] PathModularizationCache needs to set cache Apr 19, 2025
@elharo elharo requested review from gnodet and desruisseaux April 20, 2025 12:30
DependencyResolverRequest request,
PathModularizationCache cache,
List<Exception> exceptions,
Node root,
int count) {
this.request = request;
this.cache = cache;
if (cache == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This ifelse block could be replaced by this.cache = Objects.requireNonNull(cache). For consistency, we may do the same for other arguments too except root which is nullable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think that's the same. cache is nullable. We need to create a cache if the argument is null, not throw an exception. Null is passed for this argument and we don't want to break those existing usages.

Copy link
Contributor

Choose a reason for hiding this comment

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

The new constructor should replace all the calls to the previous constructor with a null cache. We are sure that the new constructor is invoked outside the package since the old constructor became package-private. So we only need to ensure that the calls inside the package pass a non-null cache, and I think that it is already the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's risky and brittle to allow null caches given the multiple locations that invoke methods on the cache and the lack of test coverage on this class. It is unsafe to allow this field to be null, even if the constructor argument is. Even if it doesn't cause an uncaught NPE now it will in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes I agree, which is why my proposal above was to use Objects.requireNonNull.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I don't want to throw a NullPointerException. We can easily create a cache here..

Copy link
Contributor

Choose a reason for hiding this comment

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

The rational was that a cache created here is of limited use. The intend was to have a session-wide cache, which is why this method was requesting the cache in argument. The creation of a cache in the constructor was only a temporary workaround for the fact that we have not investigated where a session-wide cache should be stored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whatever the intent was, this field is dereferenced without null checks in multiple places. That's dangerous.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I agree that it is dereferenced without null checks, which is why the proposal above was to use Objects.requireNonNull in the constructor. Then, since the constructor become package-private as a result of the change in this pull request, we can easily verify that all invocations of this constructor pass a non-null cache. But anyway, this is not very important. We can leave it as is for now and revisit after we determined where the cache should be stored.

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.

3 participants