Skip to content
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

METHOD_RETURN_TYPE_CHANGED reported for package-private method promoted to public that changes return type #384

Closed
scordio opened this issue Feb 25, 2024 · 15 comments

Comments

@scordio
Copy link
Contributor

scordio commented Feb 25, 2024

The following package-private method:

Class<T> getType() {
  ...
}

has been promoted to public and changed to:

public Type getType() {
  ...
}

and japicmp reports it as binary incompatible:

Comparing binary compatibility of assertj-core-3.26.0-SNAPSHOT.jar against assertj-core-3.25.3.jar
***! MODIFIED CLASS: PUBLIC org.assertj.core.api.InstanceOfAssertFactory  (not serializable)
	===  CLASS FILE FORMAT VERSION: 52.0 <- 52.0
	GENERIC TEMPLATES: === ASSERT:org.assertj.core.api.AbstractAssert<?,?><?,?>, === T:java.lang.Object
	***! MODIFIED METHOD: PUBLIC (<- PACKAGE_PROTECTED) java.lang.reflect.Type(<- <T>) (<-java.lang.Class(<- <T>)) getType()

Is it a false positive? If yes, I'm happy to submit a fix.

Commit: assertj/assertj@ff01677
CI result: https://github.com/assertj/assertj/actions/runs/8037768330/job/21952981201#step:4:202

@scordio scordio changed the title Change of package-private method reported as binary incompatible METHOD_RETURN_TYPE_CHANGED reported for package-private method promoted to public Feb 25, 2024
@siom79
Copy link
Owner

siom79 commented Feb 25, 2024

But the method return type changed, didn't it? The change of the access modifier is not the problem.

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

Yes, it changed, but it shouldn't be a problem as it was originally package-private, or not?

Or do you have in mind split-package usage?

@garydgregory
Copy link

This seems to duplicate #265

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

@garydgregory the only reason I didn't mention it as a duplicate of #265 is the potential split-package usage of an existing package-private method (my case), while a private one (your case) wouldn't be affected.

@garydgregory
Copy link

OK. It is helpful to know that these two issues are related though.

scordio added a commit to assertj/assertj that referenced this issue Feb 25, 2024
@scordio scordio changed the title METHOD_RETURN_TYPE_CHANGED reported for package-private method promoted to public METHOD_RETURN_TYPE_CHANGED reported for package-private method promoted to public that changes return type Feb 25, 2024
@siom79
Copy link
Owner

siom79 commented Feb 25, 2024

It is a difficult decision.
If you only have the point of view of the users of your library, then every package protected method should not be used (although some users might do it) and it becomes visible for your users with public access.
From a theoretical point of view, changing the return type and the modifier from package protected to public is incompatible with respect to inner package usage.
Back then I have assumed that the accessModifier filter would solve the problem. But it looks like users only see the problem from their users point of view. Do we need a new option to solve this?

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

A separate error that I can exclude in my config would work for me 👍

If there are split-package users that are impacted by this change, it means they are already dancing on the edge of brokenness and we don't provide support for such usage 😉

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

Re-reading your last message, how is accessModifier supposed to be used?

I set it to protected (assuming it means it will analyze only elements that were protected and public before the change?) but I still received a METHOD_RETURN_TYPE_CHANGED error (see assertj/assertj@684063f).

scordio added a commit to assertj/assertj that referenced this issue Feb 25, 2024
@siom79
Copy link
Owner

siom79 commented Feb 25, 2024

I thought about an implementation and as it looks, it might introduce a new concept. The point is that currently the relation between type of change (like e.g. METHOD_RETURN_TYPE_CHANGED) and the incompatibility level was fix (see e.g. here).
Now we need something like METHOD_RETURN_TYPE_CHANGED but because the access modifier also changed to more visible it is not binary incompatible. Not sure how to implement this in a concise way.

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

My rough idea was to approach it in a way similar to #311.

I haven't looked at the code in detail yet, but I trust you can spot better than me whether this is feasible with such a strategy.

@siom79
Copy link
Owner

siom79 commented Feb 25, 2024

Unfortunately it is not that easy, because we need to change the incompatibility for each occurrence. I think we need to change the list of incompatibilities from a pure enum to an object, on which we can change the incompatibility level. :(

siom79 added a commit that referenced this issue Feb 25, 2024
…e of JApiCompatibilityChange to reflect that METHOD_RETURN_TYPE_CHANGED is not incompatible in case the method's visibility increased
@siom79
Copy link
Owner

siom79 commented Feb 25, 2024

Committed the changes mentioned above to a new branch. Will have to sleep a night, before I merge it.

@scordio
Copy link
Contributor Author

scordio commented Feb 25, 2024

Thanks a lot for looking into it!

@siom79
Copy link
Owner

siom79 commented Mar 3, 2024

Fixed with 0.19.0.

@siom79 siom79 closed this as completed Mar 3, 2024
@scordio
Copy link
Contributor Author

scordio commented Mar 3, 2024

Thank you!

scordio added a commit to assertj/assertj that referenced this issue Mar 6, 2024
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

No branches or pull requests

3 participants