Skip to content

Comments

Do not emit restriction warning on inherited method#4293

Merged
stephan-herrmann merged 1 commit intoeclipse-jdt:masterfrom
laeubi:do_not_emit_restriction_warning_on_inherited_methods
Oct 25, 2025
Merged

Do not emit restriction warning on inherited method#4293
stephan-herrmann merged 1 commit intoeclipse-jdt:masterfrom
laeubi:do_not_emit_restriction_warning_on_inherited_methods

Conversation

@laeubi
Copy link
Contributor

@laeubi laeubi commented Aug 7, 2025

Currently when we have a type A and it is accessible from package p1, but extends a type B (that is not accessible in package p2) calling any inherited method A.M triggers a restriction warning.

This is undesired because as a caller I never access any restricted code here as A is inherit all public methods from B.

A good example can be found here:

in this example the code in HttpServerManager has a local variable of type Server and calls method stop() on this.

Server server = servers.remove(pid);
if (server != null) {
	try {
		server.stop();
	} catch (Exception e) {
	}
	File contextWorkDir = new File(workDir, DIR_PREFIX + pid.hashCode());
	deleteDirectory(contextWorkDir);
}

this causes the following errors:

Description	Resource	Path	Location	Type
Access restriction: The method 'AbstractLifeCycle.stop()' is not API (restriction on required library 'org.eclipse.jetty.util_12.0.23.jar')	HttpServerManager.java	/org.eclipse.equinox.http.jetty/src/org/eclipse/equinox/http/jetty/internal	line 77	Java Problem

it does not emit such warnings if the method itself is overridden (an example would be server.dump(null, "") that overrides a method in ContainerLifeCycle from the same package) because then the method binding equals the actual binding.

To mitigate this, the class MessageSend now checks if there is an implicit call and sets isExplicitUse=false like it is already done for implicit super constructor calls.

@stephan-herrmann What do you think? Any flaws in my analysis?

@stephan-herrmann
Copy link
Contributor

Short answer: I'm not convinced.

If you look in package p1, there is no such method, right?

If p2 is an internal package, then the owner of that package is allowed to do things like removing public from that method, isn't he?

For such reasons, exporting a class that inherits from an internal class is inherently fragile / breaks encapsulation. And if p2 is not on the clients classpath they will get "The type B cannot be resolved. It is indirectly referenced ..."

@laeubi
Copy link
Contributor Author

laeubi commented Aug 7, 2025

If you look in package p1, there is no such method, right?

Outline tells me something different, also javadoc, code complete,... all tell me Server has a public (inherited) method stop() :-)

If p2 is an internal package, then the owner of that package is allowed to do things like removing public from that method, isn't he?

Given this class is extended by legal consumers this will likely break them as the probably calling or overriding the method, so I don't think it is allowed. Also I don't think a restricted package is necessarily internal. If any public code is referencing this in its API it at least (e.g. extend an abstract class with public methods) leaking that (internal) API to the outside.

For such reasons, exporting a class that inherits from an internal class is inherently fragile / breaks encapsulation

That might be the case, but I don't think that restrictions really make such strong assumption, it just tells you should not directly reference the class.

So now we assume your case of someone really really really wants to remove method X from abstract class A and I have restricted access to A and have legal extenders of B and C, then I still can do that by:

  1. removing X from A
  2. let B + C implement the method X with the old signature

that's why only a direct reference to A is problematic but not through public types B or C ...

@stephan-herrmann
Copy link
Contributor

If you look in package p1, there is no such method, right?

Outline tells me something different, also javadoc, code complete,... all tell me Server has a public (inherited) method stop() :-)

None of them speak of showing the contents of p1. They know about that method because they look into p2, despite the restriction.

Anyway, I have more urgent tasks waiting for me than bending the rules of classpath restrictions.

@laeubi
Copy link
Contributor Author

laeubi commented Aug 8, 2025

And if p2 is not on the clients classpath they will get "The type B cannot be resolved. It is indirectly referenced ..."

But that's why we want it on the classpath and instead using access rules right?

None of them speak of showing the contents of p1. They know about that method because they look into p2, despite the restriction.

I must confess I never have heard about a method belong to a package and I would have not even bothered to ask or change anything if not even the compiler seem to emit a call to p1.A.X() and not to p2.B.X().
Even API tools seem to complain if I remove any inherited method from a public type regardless of it being internal or not (it just complains if you leak an non-API type from a API type what is of course desired).

And while it makes perfectly sense for a deprecated method to be checked "at the source" I don't get the rationale for an access restriction and even the code seem to indicate with a TODO that actually there is something to improve rather than to bend here

// TODO (maxime) consider separating concerns between deprecation and access restriction.
// Caveat: this was not the case when access restriction funtion was added.
if (isExplicitUse && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
// note: explicit constructors calls warnings are kept despite the 'new C1()' case (two
// warnings, one on type, the other on constructor), because of the 'super()' case.
ModuleBinding module = method.declaringClass.module();

So I went to the code and checked the callers of the method and found this place, as the exact same is used for implicit constructor calls in ExplicitConstructorCall where it decides depending on the context if such warning should be emitted.

Then I looked at the compiler documentation here and it tells me

Each directory or file can specify access rules for types between '[' and ']' (e.g. [-X] to forbid access to type X, [~X] to discourage access to type X, [+p/X:-p/*] to forbid access to all types in package p but allow access to p/X).

so it always talks about types not methods of a package. Also please note that there is a type checking also in place with isTypeUseDeprecated(TypeBinding type, Scope scope) what is perfectly fine and sensible to me, so if we assume that any parametertype of the method would reference a restricted type that would and should emits a warning.

Anyway, I have more urgent tasks waiting for me than bending the rules of classpath restrictions.

I really don't want to bend any rules or waste your time, in fact I really appreciate your insights and got the feeling in the past we found some good solutions that are beneficial for the IDE story in general even though the path not always was a direct one.

But then I don't understand your recommendation here, as this example shows why PDE currently can not effectively use access restriction rules to mitigate the problem. In OSGi one always "opens" packages not types or methods, that mean if I export Type T from package p I can access T and all its public methods without a problem (assuming no restricted Type X is used a parameter or return type). So now for PDE we have the problem that an access is not only restricted by the used type T and its package but by what methods are actually called on an instance of T.

So I really would appreciate any guidance here, because this is one of the problems I really like getting solved as it is highly confusing, requires manual fixing by the user and makes the tooling look brittle compared to other solutions. If it helps I would be fine with even introduce a new restriction type, but as explained above it does not feel right and seems a bit of an overkill here.

@stephan-herrmann
Copy link
Contributor

I see one source of confusion in the fact that packages are used as modules, whereas they don't have a clear specification of what are its dependencies and its API - this sounds like an underspecified concept.

My intuition about the API of a package is: all public stuff that you can find in .java files in the package's directory. This gives the following nice guarantee: if a change in any of these files passes compilation of the current artifact, then the change is legal.

Your intuition takes inheritance into consideration, which may have its own advantages.

In case of differing intuitions I prefer to work from specifications. So were can we look for precise answers?

(1) If your example were embedded in a JPMS module which only exports one of its packages, then - much to my surprise - clients of that module are allowed to invoke a method that is declared in a non-exported package. (I haven't checked where in JLS this is defined, but ecj and javac do agree here). Point in favor of considering inheritance.

(2) Next question: Which tool will detect illegal changes in a non-exported package? Assuming that the method in question is not used within the artifact, compilation will not see any problem. Will API tools complain about changes in internal packages, if there is a class in a public package inheriting from the internal one?

Ergo: (1) sets a precedent for selecting your intuition over mine, but (2) needs to be answered regarding API tools, to determine if a change in the ecj implementation can cause bad surprises. The change would allow clients to rely on methods that are declared in a restricted package. If that is so, then who / what would protect that client from incompatible changes? Will API tools put that method under the rules of exported API?

@stephan-herrmann
Copy link
Contributor

BTW, did you check the history of those tests in AccessRestrictionsTests that are failing with your change? Perhaps that history would reveal the reasoning behind the current implementation?

@laeubi
Copy link
Contributor Author

laeubi commented Aug 9, 2025

BTW, did you check the history of those tests in AccessRestrictionsTests that are failing with your change? Perhaps that history would reveal the reasoning behind the current implementation?

Yes I need to further investigate and see what cases are not covered correctly by my naive change here. Also there is a difference between forbidden references and discouraged reference and I need to check what applies here.

@laeubi
Copy link
Contributor Author

laeubi commented Aug 9, 2025

If your example were embedded in a JPMS module which only exports one of its packages, then - much to my surprise - clients of that module are allowed to invoke a method that is declared in a non-exported package.

I wanted to verify this as well but as I'm not a JPMS expert I was not fully able to came up with an example, so thanks for doing this experiment. I think this is because of the same reason as it "works" for OSGi, as it is only classloader visibilty.

So when we have restricted Type A and public type B and I can load B then I can access all inherited public methods from A through a call to the type B so even if there is A.x() I can always access it like B.x() and also with reflection this method will be returned from B.class.getMethods() including anything inherited but only public. In contrast B.class.getDeclaredMethods() will not include them (there will likely be a JLS explaining it better) but have e.g. protected (and private and so on) (==aka restricted access).

So let it be good or bad, from a restriction point of view I never access anything that is restricted that is not restricted by reflection as well (I need access to A.class to get the restricted (non public) method handles). So I would argue, everything that can be legally accessed through reflection without requiring the specific type should be allowed when it comes to restrictions (but JDT itself is sometimes confused as seen here and here).

Next question: Which tool will detect illegal changes in a non-exported package?

One thing about the usage of restricted package is, that it not necessarily mean they are not exported, but currently not imported so in some cases I can gain access to these packages of course. So currently "the tool" is the compiler (what leads to a problem if one wants to use javac for example see here) so apart from API tools this is of course an important aspect, as otherwise one would fail at runtime (you don't really want API tools for that!).

Will API tools complain about changes in internal packages, if there is a class in a public package inheriting from the internal one?

Now API tools complicates things a lot (and where we can not fully rely on the compiler anymore):

  1. For not imported packages we use forbidden access rules (but of course you can import them and they are on the classpath)
  2. We have so called "provisional API" that are packages that are exported (but you should not use them 🙈) so technically they can be imported (but should not 🙈🙈) except for "friends" (🙈🙈🙈) and we use discouraged access rules if not a friend import them
  3. Then a type can be marked as @NoExtend, @NoReference, @NoImplement, @NoInstantiate ... so actually we would need a way to not restrict packages but a single type
  4. You can probably already guess, we can have @NoReference not only on types but methods or fields so one would need restrictions not only on a type but even on the method level (like @Deprecated)

So API tools will need to detect a lot of more case here and some are not discoverable from the raw manifest data.

You can find a list of message one would expect here:

https://github.com/eclipse-pde/eclipse.pde/blob/master/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties

and it complains about as much as is externally visible (except it is marked as @NoReference)

@stephan-herrmann
Copy link
Contributor

Now API tools complicates things a lot ...

I can imagine a lot of complexity there, but I wouldn't require all of that to be sorted out, before continuing here. 😄

All I'm asking is this: when ecj will (per this issue) legalize access to a method that is declared in a restricted package, this will introduce a maintenance risk, unless API tools will locally detect changes that may break unsuspecting clients. Does API tools detect changes in restricted packages (not exported, or exported x-internal, or such), that may affect clients? For this we don't even need to consider restrictions due to a missing import in the client, I'm only asking about restrictions that are visible at the provider side.

@laeubi
Copy link
Contributor Author

laeubi commented Aug 9, 2025

Its quite hard to find a suitable example but:

  1. If I extends a "non API type" in a public package API tools warns me

Description Resource Path Location Type
BundleDefaultsScope extends non-API type AbstractScope BundleDefaultsScope.java /org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences line 41 API Usage Problem

so we can say for sure I got warned that I do something nasty, so whatever goes wrong after that fall into the category "you got warned!"

  1. I recently fixed a case of such API leak here and it resulted in some downstream errors here Do not leak internal API into public packages eclipse-equinox/equinox#1066 so changes in the type hirachy (even though no change in the API) is detected and I remember @HeikoKlare had has also issues in SWT with API tools being picky when changing even internal details (but I'm not sure what exactly it was about)
  2. For API types from other (public) packages it of course always complains anyways.

So I think because API tools forbids that public types extend non public ones, the described problem (I inherit a public method from a non API type and later want to remove that method) should not arise as it is illegal at the first place.

For the case that I extend a public type (and simply do not import the package) there is also no problem as API tools will complain because the base class is part of a public API.

@laeubi
Copy link
Contributor Author

laeubi commented Aug 9, 2025

@stephan-herrmann I have now adjusted the first failing test001() in the following way:

  • if method is accessed through inheritance of public type X2 it is okay
  • if method is accessed through a direct call on restricted type X1 it is not okay

if we can agree on that being the right thing, I'll look into the other failures (but they look similar).

@HeikoKlare
Copy link

I remember HeikoKlare had has also issues in SWT with API tools being picky when changing even internal details (but I'm not sure what exactly it was about)

We had two issues in the recent past of which you probably mean the first:

@laeubi
Copy link
Contributor Author

laeubi commented Aug 20, 2025

@HeikoKlare thanks for the reference, did you open already corresponding issues at PDE?
@stephan-herrmann whats you opinion on the matter as described in #4293 (comment) ? Can we proceed here? It would really be great to get this resolved (in one way or the other) as it is really annoying and often hard to understand for the users.

@laeubi
Copy link
Contributor Author

laeubi commented Sep 1, 2025

@stephan-herrmann any chance to get an agreement here? I think it would be good to be merged as early as possible in the release cycle.

@laeubi laeubi force-pushed the do_not_emit_restriction_warning_on_inherited_methods branch from abcd475 to 4301208 Compare September 16, 2025 07:18
@laeubi
Copy link
Contributor Author

laeubi commented Sep 16, 2025

@stephan-herrmann I now rebased and adjusted all testcases here, so from my side it would be ready to be submitted for inclusion in M1.

@laeubi laeubi force-pushed the do_not_emit_restriction_warning_on_inherited_methods branch from fafcdb3 to 3d38e39 Compare September 27, 2025 04:09
@laeubi
Copy link
Contributor Author

laeubi commented Sep 29, 2025

@stephan-herrmann build is finally green, so I think this would be ready to go if we can conclude on this. As this would really improve user experience in the tooling it would be great to make progress here and as both OSGi and JPMS agree here it sounds the right thing to do for me.

@laeubi
Copy link
Contributor Author

laeubi commented Oct 9, 2025

@stephan-herrmann can we continue here for maybe get this into M2? Would be highly appreciated!

@stephan-herrmann
Copy link
Contributor

I was about to be convinced that the change shouldn't hurt, but just upon reviewing test changes this took me back all the way to https://bugs.eclipse.org/bugs/show_bug.cgi?id=76266, which has this description:

When inheriting a public member from a restricted type, through a legal type, it should be diagnosed as an access violation as well (even though no direct reference to restricted type)

So finally we know that the "undesired" behavior was implemented intentionally exactly that way. And Philipe is an engineer whose judgement I like to follow until proven wrong.

From #4293 (comment) :

If I extends a "non API type" in a public package API tools warns me

This also gives a hint that we are trying to address a problem which in a perfect world should never arise.

So let's step back one more time:

  • I understand that the existing warning can be surprising
  • Other than this surprise, does it create any hard problems that are blocking development in any way?
  • If cross-API-boarder inheritance cannot be avoided, isn't the following a reasonable recommendation?
    • If an API class inherits methods from a non-API class, that are meaningful to clients, it may acknowledge this by overriding each such method containing nothing but a super call. With this gesture the API class "owns" the method, and by owning it is entitled to share it with clients.
  • JPMS decided differently, but with JPMS the compiler allows several things that will actually blow up at runtime, so being more conservative than JPMS could be an advantage.

@stephan-herrmann
Copy link
Contributor

From #4293 (comment)

When removing overwritten methods already provided by Object (equals, hashCode), API tools complain ...

At least this will not cause and "restriction" warnings from ecj, as Object is not and cannot be restricted. 😄

@stephan-herrmann
Copy link
Contributor

Its quite hard to find a suitable example but:

  1. If I extends a "non API type" in a public package API tools warns me

Description Resource Path Location Type
BundleDefaultsScope extends non-API type AbstractScope BundleDefaultsScope.java /org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences line 41 API Usage Problem

so we can say for sure I got warned that I do something nasty, so whatever goes wrong after that fall into the category "you got warned!"

This doesn't actually address the issue I raised. I was asking whether the event of modifying any "semi-API" method (lives in a restricted package but is exposed to the world through a subclass) would cause any tool to shout and tell the developer, that this change may break clients?

The fact that the tool has already shouted before, doesn't help the client who will be broken, if no specific error is raised at the event of the method change.

@laeubi
Copy link
Contributor Author

laeubi commented Oct 18, 2025

So finally we know that the "undesired" behavior was implemented intentionally exactly that way. And Philipe is an engineer whose judgement I like to follow until proven wrong.

I do not want to prove anyone wrong, an maybe it would be worth to add Philipe then here to join the discussions but this was 20 years ago so maybe things have changed in the meanwhile, but what I really miss here is the actual use-case to solve?

So apart from theoretical cases we might want to solve with Access restrictions, what is the practical example where it becomes useful?

  1. Java Reflection can not make any use of it and assume it as unrestricted
  2. JPMS handle it the same
  3. OSGI package import semantic is working the same
  4. It is against developers intuition of the topic (and the bug that introduces this does not give any rationale nor is it described in any documentation)

So who we really benefit here? Who will use this feature if PDE + Tycho will need to drop it because it is practically unusable?

I understand that the existing warning can be surprising

It is not surprising (despite the fact its an error), it is wrong and unintended from the users point of view, there is nothing that ever judge the warning nor is the solution (adding unrelated packages) in any way helpful or required.

Other than this surprise, does it create any hard problems that are blocking development in any way?

Yes it does, the whole purpose of why we use this feature is to prevent developers to use types (!) that can not be accessed at runtime and will fail. Due to the nature of the problem, that it occurs on top of the class file it is completely disturbing and hard to give good guidance for the tooling so usually people have to intervene manually and are annoyed that we require them to do things that are completely useless.

Even worse, a perfectly working code can suddenly break e.g. because an overridden method is removed or we clean up unused packages: It works in some cases and in other gives strange error then, depending on what methods the user calls.

If cross-API-boarder inheritance cannot be avoided, isn't the following a reasonable recommendation?

That's completely unreasonable (beside it bloats the code and the classfile and maybe have runtime performance implications)

  1. See very beginning, I don't know any actual case that is treated like this, so I highly doubt I can convince anyone out there writing a library to always override all methods, its often hard enough to convince them to add OSGi metadata at the first place, now asking them to do this because of JDT has an counterintuitive restriction model will simply make them think I'm insane.
  2. We often need to to wrap existing libraries, so now having to rewrite the classfiles instead of just the manifest (what creates enough churn on its own) ...
  3. Whenever the "restricted" type gets a new method it becomes immediately visible to the client and most often these are APIs independent of the consumer it needs to be overridden and I need a new library release. So this would tightly couple consumers and providers to specific versions.

JPMS decided differently, but with JPMS the compiler allows several things that will actually blow up at runtime, so being more conservative than JPMS could be an advantage.

As said nothing blows up at runtime (beside that it makes it harder for the resolver to resolve packages that are never used), we just use usual java classloader visibility.

The fact that the tool has already shouted before, doesn't help the client who will be broken, if no specific error is raised at the event of the method change.

That's a completely different story and restriction warnings do not solve this because:

  1. either I get a warning and then simply import that package --> done
  2. I get not warning as I have not called the method, it still might break me depending on what this is used, e.g. public methods might be called in other ways, as part of implemented interfaces, reflection through frameworks, binding to a scripting and so on.

The point is we have tools to restrict "semi API" on methods and this is completely vendor (PDE) specific thing that has no meaning to OSGi or the runtime, so nothing will break if you use such restricted method or fields.

@stephan-herrmann
Copy link
Contributor

Wow, the disconnect runs deeper than I thought. In an attempt to debug the discussion I will answer in small increments.

Easiest first:

I understand that the existing warning can be surprising

It is not surprising (despite the fact its an error), ...

If we are speaking of the same thing, then it's each project's choice to configure this diagnostic to Error/Warning/Info/Ignore, in two separate options for "forbidden" and "discouraged". Since it's not a mandatory error (as those that are defined in JLS) I suggest to use the term warning in a generic way, knowing that warnings can be promoted or demoted in severity by the user.

While I'm in favor of zero-warnings policies, there are means for coping with a small number of exceptions, like @SuppressWarnings.

But as the PR headline speaks of "warning", this might be a simple misunderstanding, perhaps when you wrote "error" you were referring to something else?

@stephan-herrmann
Copy link
Contributor

Next we should perhaps clarify which situation we are discussing: A client invokes a method that is declared in a class B, superclass of API class A. Possible reasons why this could be a problem:

  1. B is defined in a non-API package
  2. both packages are API, but the client imports only the package of A, not the package of B

I thought we are speaking of (1) but when you speak of adding unnecessary imports, this sounds more like (2). Again, I might be misunderstanding why you speak of adding more package imports.

@laeubi
Copy link
Contributor Author

laeubi commented Oct 18, 2025

If we are speaking of the same thing, then it's each project's choice to configure this diagnostic to Error/Warning/Info/Ignore, in two separate options for "forbidden" and "discouraged".

And here it starts to getting wrong already, you assume that is a deliberate choice of the user but its not.
While these would work for a very small scale maybe its completely unmanageable for any larger setup with hundreds of libraries used not talking about the effort to do it "right".

So here a tool is needed (PDE) to translate between OSGi world and JDT world, and it is not a question of choice but correctness, if I do not import a package of a type than it is an error without doubt. But calling a method on a public and imported type is neither an error nor a warning.

So let it be a warning or an error is not that important to me, usually it leads to a compile error.

@stephan-herrmann
Copy link
Contributor

I had falsely assumed that an explicit package import would add safety.
Seeing it silencing the error without fixing it is a relevant piece of information.

To explain more: I had been looking for ways how tools enforce more explicit contracts, in the hope that those contracts help detecting misconfigurations. In that I failed to see, that a component may require X version 1.0, but still be compiled against X version 1.1 with no complaints, thus illegally using version 1.1 features. Whether or not that should be allowed opens another can of worms, which should not be opened here (is that the pde-bot thing?). This implies that problems caused by uncoordinated software evolution cannot easily be detected just looking at one set of components, but are better detected by version comparison.

With this I'm willing to go back to MR pragmatics.

@laeubi can you provide a message to adopters that will inform them about this design change in the release notes?

@laeubi
Copy link
Contributor Author

laeubi commented Oct 24, 2025

Yes, for certain classes of errors, compilers give guarantees (assuming you don't bypass the compiler by reflection, replacing classes after compilation etc):

But exactly that is happening here, the situation you created is a bit like Compiling with Java 11 JDK with a source compliance of 8 and don't using the target option... The compiler can simply not know that at runtime some calls will fail.

One might argue the compiler can still warn you if it would do an further analysis assuming an implicit target option, but this would be likely a different tool (and there are tools for this!)

And like the JVM rechecks much of what the compiler already checked, I expect runtimes like OSGi to raise alarm, so the distinction tool vs. runtime is not so relevant. A good runtime will protect against certain classes of errors, too.

The problem is it can't if the meta-data is wrong! Assume I compile a class as compliance 11, then would edit the class file and replace the version with the one for 8 with an hex editor... no good thing could come from this.

For the same OSGi (runtime) must assume the metadata in manifest is correct what is the whole purpose of it, so it does not need to analyze the classfiles for example you need to state in the Manifest what is the minimal java version you want to run with.

Now it comes to the point that PDE (compile time) historically has leaned to the so-called "Manifest-first" that is a developer usually writes the manifest (I'm working on help the developer to get some errors/warning here eclipse-pde/eclipse.pde#1926 if they likely do things wrong), so we need more tools (e.g API tools) that need more data (e.g the baseline) to provide further assistance / checks at "tool time" as we all tend to make mistakes.

@laeubi
Copy link
Contributor Author

laeubi commented Oct 24, 2025

@stephan-herrmann I proposed a N&N entry here

also squashed, rebased and added a reference to this discussion in the commit message.

Currently when we have a type A and it is accessible from package p1,
but extends a type B (that is not accessible in package p2) calling any
inherited public method A.M triggers a restriction warning.

This is undesired because as a caller I never access any restricted code
here as A is inherit all public methods from B.

See eclipse-jdt#4293 for a
discussion about that topic.
@laeubi laeubi force-pushed the do_not_emit_restriction_warning_on_inherited_methods branch from 4c239dd to 7153d9b Compare October 24, 2025 05:41
@stephan-herrmann
Copy link
Contributor

@stephan-herrmann I proposed a N&N entry here

Two suggestions:

  • don't claim that your intuition is the only intuition, the change replaces one consistent interpretation with another one.
  • please mention the impact on implementors of org.eclipse.jdt.core.IClasspathContainer - they may want to revisit what access restrictions they are generating. They have been relying on the existing logic for decades.

also squashed, rebased and added a reference to this discussion in the commit message.

thanks.

Copy link
Contributor

@stephan-herrmann stephan-herrmann left a comment

Choose a reason for hiding this comment

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

In the end the discussion produced some relevant observations which lessen the severity of my worries of changing a long standing design.
Let's go.

@stephan-herrmann stephan-herrmann merged commit 545483d into eclipse-jdt:master Oct 25, 2025
13 checks passed
@stephan-herrmann stephan-herrmann added this to the 4.38 M3 milestone Oct 25, 2025
@stephan-herrmann
Copy link
Contributor

if you want errors for your case then you need to setup API tool checks good luck with that

That wasn't so hard. Result: it doesn't detect the need to increment any version due to method added to a super class. Neither when inheriting from a class of another bundle, nor when inheritance is from a different package of the same bundle.

=> one more tool to be updated in order to consistently support inherited methods as API of the subclass.

@laeubi
Copy link
Contributor Author

laeubi commented Oct 25, 2025

Does it detect other problems? It is not that easy to setup often to give good results, that's why I wrote the tycho-baseline check :-)

Also API tools is often not that good at detect package-version increments, I recently added some support but there is maybe still things to fix. In this case it could be that API tools is happy because you increased the bundle version already :-\

@laeubi
Copy link
Contributor Author

laeubi commented Oct 25, 2025

Two suggestions:

Do you like to suggest a change in that PR? I can then just apply it to the entry, I'm open for any changes.

@stephan-herrmann
Copy link
Contributor

Does it detect other problems? It is not that easy to setup often to give good results,

It reported quite a number of other bugs I injected.

Also API tools is often not that good at detect package-version increments, I recently added some support but there is maybe still things to fix. In this case it could be that API tools is happy because you increased the bundle version already :-\

I played with several variants of versioning, none brought the desired warning relating to package q.

@stephan-herrmann
Copy link
Contributor

Two suggestions:

Do you like to suggest a change in that PR? I can then just apply it to the entry, I'm open for any changes.

you can do that, it's your feature :)

@laeubi
Copy link
Contributor Author

laeubi commented Oct 25, 2025

Two suggestions:

Do you like to suggest a change in that PR? I can then just apply it to the entry, I'm open for any changes.

you can do that, it's your feature :)

I'm quite bad ad writing N&N entries but will try to improve that..

iloveeclipse added a commit to iloveeclipse/eclipse.jdt.core that referenced this pull request Oct 26, 2025
stephan-herrmann added a commit to stephan-herrmann/eclipse.jdt.debug that referenced this pull request Oct 26, 2025
Due to eclipse-jdt/eclipse.jdt.core#4293 ecj
no longer warnigs about using a method inherited from a deprecated type
iloveeclipse pushed a commit to eclipse-jdt/eclipse.jdt.debug that referenced this pull request Oct 26, 2025
Due to eclipse-jdt/eclipse.jdt.core#4293 ecj
no longer warnigs about using a method inherited from a deprecated type
SougandhS added a commit to eclipse-jdt/eclipse.jdt.debug that referenced this pull request Nov 13, 2025
* Don't listen to thread termination, listen to target termination

For whatever reason original change added listener on thread termination
and not on target termination event, and for whatever reason it wasn't
noticed during review.

Fixing that. HCR dialog should only close automatically if the debug
target is terminated, not if some thread in the target is terminated.

Fixes #792

* Extended support for in-line chained lambdas

Allow users to put a lambda entry breakpoint on a selected lambda if
line contains multiple chained lambda expressions.

Fixes : #732

Co-authored-by: Andrey Loskutov <loskutov@gmx.de>

* Enable "Collapse" stack frames by default

Fixes #796

* Remove @SuppressWarnings annotation no longer raised by ecj

Due to eclipse-jdt/eclipse.jdt.core#4293 ecj
no longer warnigs about using a method inherited from a deprecated type

* Remove @SuppressWarnings annotation no longer raised by ecj, take 2

Fixes remaining `@SuppressWarnings("deprecation")` annotations flagged
as unnecessary by
eclipse-jdt/eclipse.jdt.core#4564

See eclipse-jdt/eclipse.jdt.core#4553

* React to new info warnings from ecj (#802)

Add @deprecated to members of truly deprecated classes
+ most classes have a replacement for a long time already
+ still in use and no replacement specified:
  - JavaSourceLocationWorkbenchAdapterFactory

* Disable breakpoint  Entry&Exit toggle actions for lambda breakpoints (#803)

Enabling exit will make debugger suspend at random lambdas and by default lambda method breakpoints are already enabled

---------

Co-authored-by: Andrey Loskutov <loskutov@gmx.de>
Co-authored-by: Stephan Herrmann <stephan.herrmann@berlin.de>
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