Bug 376590 - Private fields with @Inject are ignored by unused field validation
Summary: Private fields with @Inject are ignored by unused field validation
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.8   Edit
Hardware: All All
: P3 normal with 8 votes (vote)
Target Milestone: 4.3 M6   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 391842 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-04-12 09:04 EDT by Sebastian Zarnekow CLA
Modified: 2020-04-26 07:20 EDT (History)
9 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Zarnekow CLA 2012-04-12 09:04:47 EDT
import com.google.inject.Inject;

public class Empty {

	@Inject
	private String unusedButNotFlagged;
	
	private String unusedAnfFlagged;
	
}


This is a regression since bug 365437 was fixed (which is great!)

Fields that are annotated with @Inject but never read should be flagged as unused fields.
Comment 1 Ayushman Jain CLA 2012-04-12 09:16:13 EDT
In light of bug 365437 comment 32 and 33, I'd say this is intentional and not a regression
Comment 2 Sebastian Zarnekow CLA 2012-04-12 09:27:52 EDT
Copied new comment from original ticket to move the discussion to this one here:

The container annotations (@Inject and friends) declare dependencies thus
introduce coupling between components. If these dependencies are unused, the
tool should warn me about that because I have the chance to reduce coupling
simply by removing these unused fields.

There is already a special treatment of @Deprecated (I still get the warning
about unused fields). From my perception it may be useful to make a distinction
between common used annotations that lead to reading or writing a field. Since
@Inject will usually be processed by a writing service, I'd expect a warning if
no client reads that field.
Comment 3 Stephan Herrmann CLA 2012-04-12 12:17:31 EDT
Hm, maybe for @Inject the best way is indeed to make an exception from the exception from the rule.

But on the long run, maintaining an implementation that hard-codes the subtleties of semantics of lots of annotations looks like a battle we cannot win. In bug 365437 making these things configurable by user options was deemed as too arbitrary an approach.

I wonder, if this information should actually come from additional plug-ins? If JDT/Core would provide an extension point someone can provide a plug-in that knows the rules for DI, someone else do the same for persistence annotations etc.
The point is: you need more than superficial knowledge about an annotation to tell whether it creates a relevant usage relationship. A user option makes it too easy for users to misconfigure (and they'll blame the compiler that it gave wrong advice). A plug-in providing this info via an extension can be reviewed once and for all.

The only downside I can see: this won't directly work for the batch compiler.
Comment 4 Michael Piefel CLA 2012-08-07 02:45:06 EDT
(In reply to comment #1)
> In light of bug 365437 comment 32 and 33, I'd say this is intentional and
> not a regression

I believe it is a regression and the fix for 365437 actually made things worse:

- old behaviour: field is actually used -> just silence the warning

- new behaviour: field is actually unused -> no indication anywhere
Comment 5 Ayushman Jain CLA 2012-08-07 03:16:18 EDT
*** Bug 386692 has been marked as a duplicate of this bug. ***
Comment 6 Ayushman Jain CLA 2012-08-07 04:36:02 EDT
(In reply to comment #4)
> (In reply to comment #1)
> > In light of bug 365437 comment 32 and 33, I'd say this is intentional and
> > not a regression
> 
> [..] the fix for 365437 actually made things
> worse:
It really depends on how you look at things. I would say that the problem of fields being marked as unused even when they're actually used in some way is worse than being silent on unused fields. Ofcourse, its good to have the warning on the above cases to guarantee leaner code, but its not like the code will break at runtime or anything. I still don't know how we can fix this bug to accomodate all the hundreds of annotations people will want to have excluded. And this list will never stop growing!
Comment 7 Michael Piefel CLA 2012-08-08 14:19:51 EDT
(In reply to comment #6)
> I would say that the problem of fields being marked
> as unused even when they're actually used in some way is
> worse than being silent on unused fields.

I agree when you put it that way.

However, you can easily silence the spurious warning once you determined the field is indeed used. I do not have a work-around to accomplish the analysis that I would want to have – yet.

Regarding the possibly infinite number of annotations to consider and to make exceptions for (although I’d say that @Inject, @In and @Autowired should cover a lot of ground), if you want to avoid that, make it configurable.

For me, make the old behaviour an option.
Comment 8 Michael Piefel CLA 2012-09-07 04:52:53 EDT
import javax.annotation.Nonnull;

public class Nulls {
	private String unusedAndFlagged() { return null; }
	
	@Nonnull
	private String usedButNotFlagged() { return ""; }
}


With this example it’s even more obvious that the approach to consider each annotation as use is hurting. I can now trade in null analysis for unused analysis.

You say “And this list will never stop growing!” and you’re quite right. You suppress way too many warnings when it is so easy to suppress the few actually necessary places with @SuppressWarnings.
Comment 9 Stephan Herrmann CLA 2012-10-12 20:37:55 EDT
*** Bug 391842 has been marked as a duplicate of this bug. ***
Comment 10 Stephan Herrmann CLA 2012-12-02 08:41:01 EST
Where do we stand in this discussion?

In bug 383371 comment 48 we have a request to respect @Inject also during null analysis.

If we agree that Guice's @Inject is worth hard-coding special treatment in our analysis, I'd be happy to use that information for both analyses ("unused" and "null") alike.

Brainstorming about the situation I could imagine that we classify the known effect of an annotation into:
1. read/write
2. guaranteed non-null write
3. unknown

Here, @Inject would be classified as (2), right? (Unless Guice is told to tolerate a null value(?)). (2) would *not* prevent "unused" warnings...
Comment 11 Sebastian Zarnekow CLA 2012-12-02 09:00:38 EST
(In reply to comment #10)
> Where do we stand in this discussion?
> 
> In bug 383371 comment 48 we have a request to respect @Inject also during
> null analysis.

Yes, that would be great!

> If we agree that Guice's @Inject is worth hard-coding special treatment in
> our analysis, I'd be happy to use that information for both analyses
> ("unused" and "null") alike.

The solution should allow other to add other annotations (preference?, extension point?), e.g. to cover com.google.inject.Inject and javax.inject.Inject. Other frameworks may use different annotations for that purpose.

> 
> Brainstorming about the situation I could imagine that we classify the known
> effect of an annotation into:
> 1. read/write
> 2. guaranteed non-null write
> 3. unknown
> 
> Here, @Inject would be classified as (2), right? (Unless Guice is told to
> tolerate a null value(?)). (2) would *not* prevent "unused" warnings...


Guice's @Inject has a notion of 'boolean optional()'. option=true implies that that there is no guaranteed non-null write. 

@Inject(optional=true) Type name = new Type();
should be definitely non-null whereas @Inject(optional=true) Type name; is possibly null.

I'd like to see warnings for unused injected fields, so (2) carries the right semantics for my use case. Please note that it is possible to annotate private methods with @Inject which implies that Guice will invoke that methods, so I don't expect an unused warning there.
Comment 12 Stephan Herrmann CLA 2013-02-17 13:36:25 EST
Released for 4.3 M6 via commit fc2bbd994a305724f9f5d9645163d8f7329cd965.

The patch handles both @javax.inject.Inject and @com.google.inject.Inject.
Comment 13 Srikanth Sankaran CLA 2013-03-12 02:26:05 EDT
Verified for 4.3 M6 using Build id: I20130310-2000
Comment 14 Fernando Padilla CLA 2013-08-05 20:18:28 EDT
Could you not support @Autowired too, which is probably also very popular?

org.springframework.beans.factory.annotation.Autowired
Comment 15 Dani Megert CLA 2013-08-06 06:59:41 EDT
(In reply to comment #14)
> Could you not support @Autowired too, which is probably also very popular?
> 
> org.springframework.beans.factory.annotation.Autowired

See bug 386692 comment 3. Bug 386692 should be reopened and then either be closed as WONTFIX or get fixed.
Comment 16 Stephan Herrmann CLA 2020-04-26 07:20:52 EDT
FYI: interested parties may want to join me discussing bug 547451 comment 24.