| Summary: | [compiler][null] Enum implementing Google Guava interface can never successfully compile. | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Sascha Goldsmith <saish> |
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> |
| Status: | CLOSED WONTFIX | QA Contact: | Stephan Herrmann <stephan.herrmann> |
| Severity: | normal | ||
| Priority: | P3 | CC: | amj87.iitr, natros, stephan.herrmann |
| Version: | 4.2 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | stalebug | ||
The code snippet you pasted is syntactically wrong. The correct snippet should be something like this:
public enum BrokenEnum implements com.google.common.base.Predicate<String>
{
INSTANCE { // notice this
public boolean apply(@javax.annotation.Nullable final String value)
{
return true;
}
@Override
public boolean equals(@javax.annotation.Nullable final Object target)
{
return super.equals(target);
}
} // notice this
}
Basically with your snippet if you use null-annotations you will get the error you wrote in the comment, which is completely valid. But without null annotations also, you will get another error on the same line, but this time it'll be the parser error.
If you want to use null annotations, where javax.annotation.Nullable, etc are configured as the null annotations, you will have to configure null related warnings to "warning" or "ignore" to make this code compile. Otherwise, you can follow the conventions of using the parent declared annotation, or use JDT's default annotations in place of javax.annotation.Nullable
(In reply to comment #1) > The code snippet you pasted is syntactically wrong. The correct snippet should > be something like this: Oops sorry, I didn;t notice the ';' after INSTANCE in your snippet. So your snippet is indeed valid. But somehow I cannot reproduce it using the same build. When I turn off null annotations (By un-checking the option "Enable annotation based null analysis" in the Errors/warnings page), the warning goes away. I think in your case the problem is project-specific settings are different from workspace settings. Can you right click your project and navigate to Properties>Java>Compiler>Errors/warnings and then un-check the null annotations option? The error should go away Ofcourse in the presence of annotation based analysis the error is valid. You can use the suggested quick fix (Add suppress warnings) to get rid of the error. Thank you for the quick reply. I have indeed configured Eclipse to use the nullability annotations from javax.annotation. This seems to be the root cause of my current problem.
However, I would like to point out two things:
1. Shouldn't developers (and Eclipse) use the JSR-based annotations? Why would one use Eclipse-specific annotations when a standard exists for this very purpose? (Especially in light of the fact that using these annotations causes the issues described above).
2. While moving the setting from error warning, the problem can be solved; however, I now have to add an additional @SuppressWarnings("null") to the top of the class to eliminate the new warning. The main downside to this is losing the enforcement of the null check in other areas of the code (e.g., other violations of incompatible nullness constraints).
Perhaps this issue cannot really be solved. It would be nice to enforce via an error setting areas of the code where incompatible nullness constraints exist. However, the combination of an enum and an implementing an interface that already exists on java.lang.Object with an additional null constraint cannot be solved without doing so it appears.
I do want to express that I love the idea of annotation-based static checking by Eclipse. It is a great addition.
If there is anything else I can do to test solutions, please let me know.
Saish
FYI: The above is true whether I have project-specific or environment-wide preferences set as described. Whether annotation-based settings are enabled or not does not seem to matter, it is rather the reporting level that you set (e.g., warning/error) regardless of whether the checkbox for annotations is selected.
This paragraph: Perhaps this issue cannot really be solved. It would be nice to enforce via an error setting areas of the code where incompatible nullness constraints exist. However, the combination of an enum and an implementing an interface that already exists on java.lang.Object with an additional null constraint cannot be solved without doing so it appears. is confusing. To rephrase, it would be nice to be able to: 1. Use the JSR javax.annotation annotations. 2. Leave the setting as error so that the project cannot build with an incompatible nullness constraint. 3. Somehow find a solution for the case where an enum implements an interface which itself has added a nullness constraint to a method of java.lang.Object (or presumably java.lang.Enum). I guess one solution would be to abandon the enum. Or convince Google it was a mistake in Guava to add nullability constraints to interfaces with signatures matching java.lang.Object. Saish (In reply to comment #3) > Thank you for the quick reply. I have indeed configured Eclipse to use the > nullability annotations from javax.annotation. This seems to be the root cause > of my current problem. > > However, I would like to point out two things: > > 1. Shouldn't developers (and Eclipse) use the JSR-based annotations? Why > would one use Eclipse-specific annotations when a standard exists for this very > purpose? (Especially in light of the fact that using these annotations causes > the issues described above). You can totally use any annotation as null annotation as long as you configure it properly in the preferences page. I just recommended using JDT annotations as a workaround to your issue, not as a general strategy. Now Let me try to rephrase what you're saying - "I understand that the warning is legal. I want null analysis to be able to detect all such cases but I want an exemption for this particular method." I don't see how we can solve this problem through the tooling. > FYI: The above is true whether I have project-specific or environment-wide > preferences set as described. Whether annotation-based settings are enabled or > not does not seem to matter, it is rather the reporting level that you set > (e.g., warning/error) regardless of whether the checkbox for annotations is > selected. I don't understand this. You're saying that you get the error (or warning) even when you un-check the "enable annotation based null analysis" on the project specific settings? I can't see this happening and this is not the way the settings work. As soon as you un-check the master option all sub-options are greyed out and there's no way you can get any error relating to null annotations. Perhaps you can attach your project here and we can point out what's missing. (In reply to comment #3) > 1. Shouldn't developers (and Eclipse) use the JSR-based annotations? Why > would one use Eclipse-specific annotations when a standard exists for this very > purpose? (Especially in light of the fact that using these annotations causes > the issues described above). JSR 305 is *not* an approved standard, see bug 385440 comment 3 for an expanded version of this statement. Conceptually, I see three possible levels where this situation should be improved: 1. Enum.equals should declare its parameter as @Nullable, either Oracle will do this one day, or our future mechanism from bug 331651 will help out. 2. Google should avoid mentioning @Nullable in their interface but let clients specify this via annotations on the type argument (see bug 385440 comment 8) - requires JSR 308, though. 3. JDT may revisit some situations of mixing annotated and un-annotated code, perhaps to the end that some more problems can be configured individually. The category of this current bug would be s.t. like "Unannotated method overrides method with null annotations". A new option re (3) should come with an explicit note that ignoring such warnings is unsafe, because the @Nullable parameter signals that passing null is fully safe, whereas the un-annotated method has not been checked if it fulfills this contract. (In reply to comment #5) > (In reply to comment #3) > > Thank you for the quick reply. I have indeed configured Eclipse to use the > > nullability annotations from javax.annotation. This seems to be the root cause > > of my current problem. > > > > However, I would like to point out two things: > > > > 1. Shouldn't developers (and Eclipse) use the JSR-based annotations? Why > > would one use Eclipse-specific annotations when a standard exists for this very > > purpose? (Especially in light of the fact that using these annotations causes > > the issues described above). > You can totally use any annotation as null annotation as long as you configure > it properly in the preferences page. I just recommended using JDT annotations > as a workaround to your issue, not as a general strategy. > Fair enough. > Now Let me try to rephrase what you're saying - "I understand that the warning > is legal. I want null analysis to be able to detect all such cases but I want > an exemption for this particular method." > > I don't see how we can solve this problem through the tooling. > There are all sorts of preferences where the presence of external code is taken into account. For example, looking at whether an exception is declared in an overriding method when determining whether a warning should be issued for an unused exception. At lease in principle, something similar could be provided here. "Ignore null annotations in third-party JAR files." Or something similar. No? > > FYI: The above is true whether I have project-specific or environment-wide > > preferences set as described. Whether annotation-based settings are enabled or > > not does not seem to matter, it is rather the reporting level that you set > > (e.g., warning/error) regardless of whether the checkbox for annotations is > > selected. > > I don't understand this. You're saying that you get the error (or warning) even > when you un-check the "enable annotation based null analysis" on the project > specific settings? I can't see this happening and this is not the way the > settings work. As soon as you un-check the master option all sub-options are > greyed out and there's no way you can get any error relating to null > annotations. Perhaps you can attach your project here and we can point out > what's missing. Ok. I just reimported the project, and the behavior is as you described. So, my apologies, please disregard that portion of the post. Saish (In reply to comment #7) > Conceptually, I see three possible levels where this situation should be > improved: > > 1. > Enum.equals should declare its parameter as @Nullable, either Oracle will do > this one day, or our future mechanism from bug 331651 will help out. > > 2. > Google should avoid mentioning @Nullable in their interface but let clients > specify this via annotations on the type argument (see bug 385440 comment 8) - > requires JSR 308, though. > > 3. > JDT may revisit some situations of mixing annotated and un-annotated code, > perhaps to the end that some more problems can be configured individually. The > category of this current bug would be s.t. like "Unannotated method overrides > method with null annotations". > > A new option re (3) should come with an explicit note that ignoring such > warnings is unsafe, because the @Nullable parameter signals that passing null > is fully safe, whereas the un-annotated method has not been checked if it > fulfills this contract. Option #2 would seem the best, but there would be no way to ensure that API designers choose the right course (or choose to leave legacy annotations in for consistency or backward compatibility). Perhaps option #4 would be to include an additional preference such as "ignore nullness annotations in third-party libraries". Or perhaps a more refined preference which would do the same but allow the user to list packages or package wildcards to ignore nullness annotations? Saish No time for this at present! This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
Build Identifier: 20120614-1722 If you implement any of Google Guava's interfaces that declare an equals method as follows: boolean equals(@Nullable Object target) You can never compile successfully for an enum. The equals() method is final due to the enum itself. However, Guava has specified @Nullable for an equals method that conflicts with the normal one from Object, and Eclipse does not allow you to compile this. There seems to be no way out of this dilemma. Even turning off null annotation analysis completely does not make the compiler error go away. Example: public enum BrokenEnum implements com.google.common.base.Predicate<String> { INSTANCE; public boolean apply(@javax.annotation.Nullable final String value) { return true; } /** * Without adding this method, I get an error from Eclipse: * * "The method equals(Object) from Enum<BrokenENum> cannot implement the corresponding method * from Predicate<String> due to incompatible nullness contstraints." * * Note, this is because Google Guava has declared a method equals(@Nullable Object). * * However, since this is an enum, I cannot provide my own implementation of Object#equals. * Hence, I am completely stuck with an Eclipse fatal compiler error I can neither disable * nor resolve. */ @Override public boolean equals(@javax.annotation.Nullable final Object target) { return super.equals(target); } } Any version of Google Guava after 11 will demonstrate this issue. Reproducible: Always Steps to Reproduce: 1.Add Google Guava 12.0 to your classpath. 2.Attempt to compile the above class. 3.