This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
this causes multiple warnings in the code. The must be repaired one by one. The steps I did: * Create a class which implements an interface (and extends an abstract class) * Use Alt-Ins to select the methods. * The generation proceeds as expected; however, the override annotation is not generated which triggers multiple warnings because of the missing override.
What build are you using? What is your source level? Seems to work fine for me.
*** Issue 124205 has been marked as a duplicate of this issue. ***
dev build 200801061200 Project with JDK6-level source compatibility Invoking code-complete on an abstract class (i.e. AbstractList) adds the @Override annotation per method. Attempting the same thing on an interface (i.e. Set) results in methods without the @Override annotation. This seems like a pretty clear-cut bug. If the source-level compatibility is set to JDK6 and above interfaces should get @Override as well.
Since it has been marked as a duplicate of this issue, I'm adding my comments from issue 124205 here, as it actually represents a somewhat broader view of the general issue: On the one hand, the "Implement all abstract methods" hint generates methods with an @Override annotation. On the other hand, for an implementation of an abstract method no "Add @Override annotation" hint is shown, and the I- in-green-circle editor annotation is shown rather than the O-in-green-circle one. I beliebe this is inconsistent. Java allows @Override annotations on methods implementing abstract methods, but not on methods implementing interface methods. This is somewhat controversial, and I suppose that's the reason why the "I" editor annotation and no "Add @Override annotation" hint is shown for methods implementing abstract methods. (This must have changed quite late in the 6.0 dev builds, I think.) But then the "Implement all abstract methods" hint shouldn't generate @Override annotations either. Pick one policy, and stick with it throughout the editor. Since it's a contentious issue whether @Override annotations belong on methods that implement abstract methods, you might want to make the policy configurable and add a corresponding flag in the Options.
Two separate problems, IMO: I. Adding @Override annotations I tried to make sure that the Java editor produces the @Override annotations on all methods it can. The change is in Mercurial changeset id: db947d77f4ca (will be public on my next push to shared repository). The change is mostly adding tests, the semantics remains as it was. The situation is as follows: -the behavior and meaning of java.lang.Override changed between JDK 5 and JDK 6 - see: http://blogs.sun.com/ahe/entry/override the Java editor produces @Override annotations based on the current source level - when the source level == "1.6", @Override annotation is generated on all methods (including methods from interfaces) (should be safe, JDK 5 compiler will not accept source level == "1.6"). For source level == "1.5", it adds @Override annotation only at the methods coming from a superclass. The "Add @Override annotation" hints should behave in the same way. To my current knowledge, the Java editor does the best it can: the @Override annotations are generated on all places where they could be without causing compilation errors. If you have a case they are not, please open a new bug with very exact steps to reproduce. The problem with the "Source/Binary Format" combo in the J2SE Project customizer is that this combo actually does not set the source level to "1.6", it only changes the "target level" to "1.6", but there is no way for the Java editor to react on this change. I am passing this to the J2SE Project to resolve this. II. "I" and "O" annotations I think this is quite independent on the @Override annotation - method override is defined in JLS 8.4.8.1, and method that overrides an abstract method is said to implement it. The "I" appears for methods that implement other methods, "O" for methods that do not implement at least one method, but override at least one method. I think that this behavior is consistent.
Basing the editor's behavior on the source level (javac.source) is not really correct, I believe. This is because javac's behavior does not actually depend on the specified source level: javac 1.6 uses the 1.6 semantics even with - source 1.5. So wouldn't it be more appropriate to look at the javac (or JDK) version?
I am afraid that I do not see any "fully correct" solution. The current is the best I know. Basing the decision on the instance of the javac used to build the project will not work - the project with source level 1.5 can be switched from JDK6 to JDK5 (without any warning), and the already generated @Override annotations would cause build failures (the same holds for sharing the project through a VCS).
I don't see the same ambiguity that you two do. The way I see it it's very simple: 1) Switching the source level from 1.6 to 1.5 won't change existing @Override and compilation errors may occur. This is okay and I doubt any users would expect otherwise. Put it another way, if they hand-coded some 1.6-specific code they won't expect Netbeans to magically change their code. 2) I believe it is appropriate to use the project source level instead of javac level because what we are essentially saying is that "This project can be compiled under JDK XXX". It doesn't matter that on the current machine your 1.6 compiler will accept @Override that 1.5 won't. What matters is that Netbeans is saying that any code that *it* generates will be able to compile under JDK 1.5 and to the best of its ability it will try to guarantee that any code *you* wrote is also 1.5-compliant (but the latter doesn't have to be 100%).
gtzabari: thats what I was trying to say, I guess.
I've changed the behavior of project customizers, the Java 6 source/binary format sets both the java.csource and the javac.target to 1.6. Commit: 3c1577e4ccfa
jlahoda, you wrote: "I tried to make sure that the Java editor produces the @Override annotations on all methods it can." I would strongly prefer that @Override annotations be only produced when not having an annotation would otherwise result in a warning. Doing this would not be in conflict with what the original reporter wanted. Reopening for reconsideration.
matthies, Under which conditions does Netbeans apply @Override which would not otherwise produce a warning?
gtzabari: When generating implementations of abstract methods. (E.g. perform "Implement all abstract methods" on "class Test extends AbstractList { }".) Maybe there are other cases, not sure at the moment. It seems to me that the following three should always coincide (in the "if-and-only-if" sense): - Warning shown when no @Override annotation present. - Green "(O)" gutter annotation shown (as opposed to "(I)" or no annotation). - @Override annotation added when auto-generating method. Couldn't all three delegate to the same logic internally?
I still think that the "green O/I" means something different than the @Override annotation - the "green O" means "you are overriding an existing body", "green I" means "you are implementing an abstract method" (if both is true, "green O" should win). One can use the @Override annotation on a method that implements abstract method from the superclass. As of JDK6, one can annotate with @Override even method that implements a method from interface. I will extended the Add @Override annotation hint to cover the above scenario correctly.
jlahoda: Are you saying that "green I" will produce a warning/hint too? Because I'd absolutely, positively hate that. ;) FWIW, here's some rationale (which may or may not convince): 1) There are three cases were I add @Override: a) I'm overriding an existing method body either with a new method body, or with an abstract declaration (basically "un-implementing" the method). b) I'm overriding an abstract or interface method declaration with another abstract or interface method declaration that has a different signature (because of type variable instantiation and/or because of return type specialization). Here the @Override is helpful to check that the new signature actually matches the different signature from the supertype. IMO enabling this for interfaces is the real improvement in JDK 6. c) I'm declaring a method of java.lang.Object in an interface, usually to document additional requirements for implementations of the interface (cf. java.util.Collections.equals() for example). With the exception of b), this is exactly "green O". Adding @Override in other than these cases just increases the visual clutter, as far as I'm concerned. 2) There's a certain category of nested classes (that I happen to code quite frequently) that just consists of a small number of "green I" method implementations with one-line method bodies. For such nested classes, adding @Override annotations would significantly increase the line count (or line length when placed on the same line as the method signature - but that doesn't play well with automatic formatting anyway), making them much less succinct, reducing readability. 3) In the coding style I'm used to, polymorphic methods are commonplace, and use of interfaces is quite pervasive. As a result, the great majority of method implementations is of the "green O/I" kind, but only a small fraction of those is of the "green O" kind. Adding @Override to all "green O/I" methods would make @Override rather meaningless, since the great majority of method implementations would end up having it. Adding @Override only in the cases outlined in 1), on the other hand, highlights the method declarations that require higher-than-usual attention. 4) Earlier NB versions with JDK 5 added @Override warnings on methods implementing abstract methods from abstract classes, and (even worse) on abstract methods that just repeat an abstract or interface method in a super type. I found that to be highly annoying, and was much relieved when NB later on limited warnings to the "green O" case. Adding warnings for "green I" cases would create significantly more warnings than this earlier version already created!
matthies, I'm afraid I disagree with you. @Override is supposed to be used anytime you override a method or implement an interface method to avoid the following type of user-error: 1) MouseAdapter implements all interface methods using an empty body 2) User comes along and extends MouseAdapter but makes a typo in his declaration 3) Instead of the user method getting invoked, the no-op MouseAdapter method gets invoked instead This was a very common user error, especially for users defining anonymous classes which extends MouseAdapter. @Override ensures that users get a compile-time error if they think they are overriding a method but they are not. You seem to be misunderstanding what @Override is meant for. It isn't there for the user's sake but rather for the compiler's. It's there to communicate a compile-time requirement.
gtzabari: I don't think we disagree here. I'm all for having warnings on methods that actually override an existing method implementation, and hence for automatic adding of @Override in that situation. The warning in that case basically means "Do you really intend to override/disable the inherited implementation?". The @Override annotation then expresses that intent "Yes, I'm intentionally overriding/disabling the inherited implementation", and the compiler verifies that this expressed intent matches the reality. This corresponds to your MouseAdapter example, where the existing no-op implementations are being overridden (or at least are intended to be overriden - as you say users can get it wrong). What I'm against, on the other hand, is adding warnings to mere implementations ("green I"), that is where no existing method implementation is being overridden. In other words where the method in the super type is either declared abstract or is a not-yet-implemented interface method. Here the warning would effectively say "Are you sure you want to implement this method?", which appears pretty silly to me. A typo in that situation wouldn't get unnoticed either, because this would cause a compile error that the method is unimplemented (in the first non-abstract class). In addition, I'd be in favor of adding warnings when specializing return types, like in: interface Foo { List<? extends Foo> children(); ... } interface Bar extends Foo { ArrayList<? extends Foo> children(); ... } // probably not intended interface Baz extends Foo { List<? extends Baz> children(); ... } // probably makes sense Such warnings would mean "Did you really mean to specialize the return type of that method?" (childrens of Bar might actually still be just Foos). And an @Override annotation would mean "Yes, I'm doing this intentionally." But, I don't think that warnings are appropriate for the following cases (and hence @Override annotations shouldn't be generated there either) (some required 'public' modifiers omitted): A) interface Foo { int f(); ... } class FooImpl implements Foo { int f() { ... } ... } // please no warning here B) abstract class Foo { abstract int f(); ... } class FooImpl extends Foo { int f() { ... } ... } // please no warning here C) class Foo { int f() { ... } ... } abstract class Bar extends Foo { abstract int f(); ... } // do warn here class BarImpl extends Bar { int f() { ... } ... } // please no warning here D) interface Foo<T> { T f(); ... } interface Bar extends Foo<Integer> { Integer f(); ... } // please no warning here, but: interface Baz extends Foo<Number> { Integer f(); ... } // ok to warn here interface Qux<T extends Number> extends Foo<T> { T f(); ... } // please no warning here either E) interface Foo<T> { T f(); ... } abstract class Bar implements Foo<Integer> { abstract Integer f(); ... } // please no warning here, but: abstract class Baz implements Foo<Number> { abstract Integer f(); ... } // ok to warn here abstract class Qux<T extends Number> implements Foo<T> { abstract T f(); ... } // please no warning here either F) abstract class Foo<T> { abstract T f(); ... } abstract class Bar extends Foo<Integer> { abstract Integer f(); ... } // please no warning here, but: abstract class Baz extends Foo<Number> { abstract Integer f(); ... } // ok to warn here abstract class Qux<T extends Number> extends Foo<T> { abstract T f(); ... } // please no warning here either I hope that's comprehensive enough. ;)
The only counter-example I can think of (but maybe there are others) is if a concrete class implements an interface or abstract method which subsequently gets removed in a later revision. If the method has an @Override annotation you would get a compilation error which would notify you the method should be removed, which seems like a good thing. The only catch is that this use-case is rare in practice. Can anyone think of another?
gtzabari: With regard to your counter-example: The method shouldn't necessarily be removed. It should only be removed if it was only accessed through the interface/abstract super class. But there may also be direct clients of the concrete class. Also, not removing the method doesn't break anything. In the worst case, it's just dead code. I wouldn't appreciate a warning on something just for the remote possibility that it might eventually become dead code ;). Even actual dead code (unused private methods) isn't considered worth a warning, just a different highlighting.
moving opened issues from TM <= 6.1 to TM=Dev
*** Issue 134249 has been marked as a duplicate of this issue. ***
I'd like to bump this issue. Can we get a consensus on this and get it fixed for 6.5? The consensus I hope for is: - Only methods with "green O" (as opposed to "green I") without an @Override annotation should generate a warning. If this consensus cannot be reached, then the behavior for "green I" should be configurable. - In the absence of a warning, methods with "green I" without an @Override annotation may still generate a hint for adding an @Override annotation. - Auto-generation of @Override annotations (e.g. when auto-generating missing implementations of abstract methods) should only occur for methods where a missing @Override annotation would otherwise cause a warning. See my comment from Apr 1 11:54:33 for some rationale.
For warnings, would be be possible to automatically add the @Override annotation for all methods instead of requiring you to go one by one.
@cwebster: Not considering each method individually would pretty much defeat the purpose of the warnings, wouldn't it? Incidentally this proves the point that there should be no warnings on mere implementations ("green I"), because there is really nothing to warn about there. A warning is appropriate when you disable an existing implementation by overriding without documenting that intent with an @Override annotation.
I'm lost. What are we expected to do?
I would vote for inserting @Override whenever Alt-Ins is used to implement or override a method and is allowed by the compiler.
@jbecicka: I'll try to recap: 1) There are cases (the "green I" methods) where missing @Override annotations cause warnings to be generated where, according to what I've written previously, no warnings should be generated. 2) There are cases where automatic code generation generates @Override annotations although the absence of those annotations would not cause warnings. 3) The behavior of 1 depends on the javac.source setting, but the project properties dialog doesn't allow this to be chosen independently from the javac.target setting. This is sometimes a problem. With regard to 1, here are some cases where NetBeans with javac.source=1.6 generates warnings where IMHO it shouldn't: interface Foo { void f(); } class FooImpl implements Foo { public void f() { } } abstract class Foo2 { abstract void f(); } class Foo2Impl extends Foo2 { public void f() { } } interface Foo3<T> { T f(); } interface Bar3 extends Foo3<Integer> { Integer f(); } See my comments from April 1 for a richer set of test cases. With regard to 2, for example "Implement all abstract methods" generates @Override annotations pretty much wherever an @Override annotation is legal for the javac.source setting, disregarding whether not doing so would cause a warning or not. In particular it generates an @Override annotation in the follwing case although with javac.source=1.5 the absence of an @OVerride annotation would NOT cause a warning: abstract class Foo2 { abstract void f(); } class Foo2Impl extends Foo2 { } To answer your actual question, here is what I would expect, or at least very much hope for, to be done: 1) Restrict warnings caused by the absence of an @Override annotation to methods with a "green O". Don't warn on "green I" methods. 2) Auto-generate @Override annotations only in thoses cases where their absence would cause a warning. 3) If the resulting behavior still depends on the javac.source setting (I'm not 100% sure whether it would), make that a separate setting from javac.target in the project properties dialog. Optionally / nice to have: 4) Still provide an "Add @Override Annotation" hint on "green I" methods. Make this an option under Options -> Java Code -> Hints. To be totally clear, by "hint" I mean a non-warning light bulb that only shows up when placing the caret on the respective method declaration. 5) For those who really really want warnings for "green I" methods, provide an option for that. (Note that this implies different behavior for javac.source=1.5 vs. javac.source=1.6.) 6) There are certain "green I" cases that can arguably be considered to constitute overriding in a certain sense. The first case is narrowing a return type via covariant return types, e.g.: interface Foo4 { Number f(); } interface Bar4 extends Foo4 { Integer f(); } The second case is instatiation of type parameters, e.g.: interface Foo5<T> { T f(); } interface Bar5 extends Foo5<Integer> { Integer f(); } And lastly there is the sort-of combination of both of the above by narrowing type parameters, e.g.: interface Foo6<T> { T f(); } interface Bar6<T extends Number> extends Foo6<T> { T f(); } Options (separate ones) could be provided to cause warnings for those cases as well. If any of those optional warnings (5, 6) are provided, make sure that auto-generation (2) pays attention to those options. Ideally, generation of warnings and auto-generation of @Override annotations should simply invoke the same underlying program logic to decide whether to warn/auto-generate.
matthies, Does the warning on missing @Override come purely from Netbeans or does javac/JLS play any part of this? If the latter hints/warns that implemented methods should have an @Override annotation then I would say you should also file a RFE against javac.
gtzabari: The warnings are purely a NetBeans feature. The javac documentation is completely silent about the possibility of such warnings, and javac with all warnings turned on (-Xlint) doesn't generate any warnings for absent @Override annotations. The JLS only defines where @Override annotations are legal. That doesn't mean that it makes sense to put @Override annotations everywhere the JSL allows it, or that not putting an @Override annotation in a place where the JSL allows one necessarily warrants a warning.
Okay so I agree with your assessment.
Slight correction: I wrote that the JLS defines where @Override annotations are legal. Well actually, the JLS doesn't do that. The relevant section [JLS:9.6.1.4] is pretty vague, and the "Discussion" part even says something which isn't true anymore for javac 1.6 (regardless of source level!): "Note that if a method overrides a method from a superinterface but not from a superclass, using @Override will cause a compile-time error." Obviously this has changed with JDK6. As a side note, what is interesting is what follows: "The rationale for this is that a concrete class that implements an interface will necessarily override all the interface's methods irrespective of the @Override annotation, and so it would be confusing to have the semantics of this annotation interact with the rules for implementing interfaces." This comment is completely right, and it's even more confusing to get warnings about a missing @Override annotation in those "will necessarily override (really: implement) anyway" cases. End side note. Where @Override annotations are legal is actually specified by the JDK Javadocs [JDK6:Override]: "Indicates that a method declaration is intended to override a method declaration in a superclass. If a method is annotated with this annotation type but does not override a superclass method, compilers are required to generate an error message." This specification matches the actual javac behavior when one applies the JLS' definition of "override" in [JLS:8.4.8.1] (which, counter-intuitively, encompasses "implements"). References: [JLS:9.6.1.4] http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.6.1.4 [JDK6:Override] http://java.sun.com/javase/6/docs/api/java/lang/Override.html [JLS:8.4.8.1] http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.1
Just double checking: will this make it into Netbeans 6.5 as the Target Milestone states? I hope so... At the very least please stop warning about missing @Override for methods that implement an interface as matthies mentioned.
I would hope so too, but currently it doesn't look like it... :(
Is there any prospect on this being fixed in the near future, or will this slip by 6.7 as it did 6.1 and 6.5? I'm asking because this issue is still a continuous annoyance.
Changing summary text to reflect the more general topic this issue has grown into.
*** Issue 162258 has been marked as a duplicate of this issue. ***
If I got this issue right(with a lot of comments). Still reproducible with 6.7m3, no overrride annotaion is added to implemented methods and no override hindt. For abstract methods @Override is added during generation but no "override hint" if @override is deleted. For other methods (not abstract) both hint and @Override generation is present.
sergeyp: To recapitulate, the goals are: 1) Warnings about a missing @Override annotation should appear only on methods that have a "green O" and where the currenct javac.source setting allows an @Override annotation. 2) Auto-generation of @Override annotations should only occur on methods where a missing @Override annotation would otherwise cause a warning. With regard to goal 1, the editor currently also shows warnings for "green I" methods, at least with javac.source=1.6, which it shouldn't. See previous comments for examples. With regard to goal 2, for example "Implement all abstract methods" currently generates @Override annotations pretty much wherever an @Override annotation is legal for the javac.source setting, disregarding whether not doing so would cause a warning or not. This is currently the case for javac.source=1.5, and, assuming goal 1 being met, also for javac.source=1.6. Other refactorings or functions that generate method declarations might also be affected. Again, see previous comments for examples. So, what needs to be done? The following: i) Restrict warnings caused by the absence of an @Override annotation to methods with a "green O". Don't warn on "green I" methods. ii) Restrict auto-generation of @Override annotations to those cases where their absence would cause a warning. Since you mentioned abstract methods, please note that the desired behavior, i.e. "green I" vs. "green O" does not depend on the abstractness of the overriding method, but only on the abstractness of the overridden method. In particular, an abstract method can override a non-abstract method, in which case the overriding method is "green O", although it is abstract.
I just found a strange @Override behaviour that looks like a bug to me. Steps to reproduce: * Created a java class ( in my case with idlj ) that overrides some methods. * An editor hint is shown that I should add the @Override annotation and I do it. * Now the class does not compile anymore and throws "method does not override a method from its superclass". The problem is that my Default JVM and so the initial JVM for the project is 1.5. When I switch the Project JVM to 1.6, compilation works. But the hint should not appear when @Override is not supported
Still no progress it seems.
On second thought, I now see the point of @Override on methods that implement interface methods. If a user implements a method that gets removed from the interface in the future, the @Override annotation will notify him of unused code. Granted, this use-case is extremely rare (methods are rarely removed from interfaces) but I see the point. I'm retracting my original vote. I'm not against or for this feature request. If there is sufficient demand, consider making this behavior configurable so end-users can decide for themselves.
(In reply to comment #29) > javac with all warnings turned on (-Xlint) doesn't generate any > warnings for absent @Override annotations. But it probably should, and in the future it might. FWIW, in C# the override keyword is mandatory, and this applies even to implementations of abstract methods: http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx The designers of C# wished to avoid the kinds of problems that occur in Java programs due to the lack of syntactic notation for a method which intentionally matches the signature of a method in a supertype. @Override is an attempt to retroactively move Java in the same direction.
The override keyword is not mandatory per se in C#/.NET. If you leave it out, and there exists a matching inherited method, then the current method behaves like it was defined with the new keyword. In other words, there will be two different methods with the same name and matching signature. So in C#, "new" is the default. This is why C# generates a warning, because the current method will not override the super-class method, unlike the programmer might assume. In Java, on the other hand, such a method will always override the super-class method, whether there is an @Override annotation or not.
Just a few observations with regard to gtzabari's previous comment: - The interface method being removed doesn't necessarily mean that the code is unused. There can be existing client code that calls the method directly, not through the interface. - Unused methods occur all the time, whether they implement an interface method or not. Unused methods that don't implement an interface method (and never did) probably occur a lot more frequently, and there's no annotation that would notify about them. - A notification about unused code is certainly nice, but it shouldn't cause a compiler error (as the @Override annotation is required to do). I still think that @Override annotations do not make much sense on methods that do not override a super-class implementation.
Maybe it's worth repeating my main point in this whole argument: I _do_ like having a warning when a method that is overriding a super-class implementation is missing an @Override annotation, so that I don't accidentally override (= disable) an existing implementation where I thought I was just implementing an abstract method. My understanding is that this was also the original intent of the @Override annotation. However, when there is a warning not only in the overriding case, but also in the implementing case, then quite obviously the annotation won't able to serve this purpose any more. It won't be warning against accidental overrides any more; in particular if the IDE "helpfully" fills in @Override annotations in either case.
My interpretation of @Override is "the method I am annotating only exists for the sole purpose of overriding/implementing the super method. If it no longer does this, please issue a compiler error as I need to revisit the existence of this method". matthies, can you think of a counter-example when you wouldn't want to revisit an overriding/implementing method when its corresponding super method was missing? <rant> On the topic of warnings vs errors, I've had a long history of negative experiences with the C++ warning system. Many of the warnings were false-positives and too many developers happily ignored them. One of the things I loved about Java was that you either got an error or nothing at all. I am not too fond of the warning system added in Java5. Most of the time it warns me about problems that aren't my fault (many Generics design problems have no workarounds except to suppress them). </rant>
@gtzabari: Our debate is only about the implementing case. No argument about the overriding case. So, about removing abstract methods: This should happen rarely, as removing the method breaks compatibility for clients of the interface (or abstract class). Therefore, in general this can only be done for interfaces that are private to a module or project. In such cases, I usually run "Find Usages" (including "Find Overriding Method") within the project before I actually remove the method, so I can revisit the implementations and (more importantly) the call sites. But the real point is that orphaned implementations are not critical to the correctness of a progran. They might constitute dead code, but their existence doesn't cause bugs in the program. Accidentally overriding a super-class implementation, on the other hand, is very likely to cause bugs. And as I wrote previously, mandating @Override annotations on both overrides and mere implementations breaks the annotation's ability to warn against such cases.
matthies, You make a good point, as always :) I'm in favor of allowing users to configure @Override for abstract classes separately from @Override for interfaces.
Set target-milestone of open issue to TBD (was < 7.3, f.e. 6.8), so the issue doesn't get lost.
Set target-milestone of open issue to TBD (was < 7.3, f.e. 6.8), so the issue doesn't get lost. This time the target milestone is really set.
This old bug may not be relevant anymore. If you can still reproduce it in 8.2 development builds please reopen this issue. Thanks for your cooperation, NetBeans IDE 8.2 Release Boss
Still relevant in current dev build.