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.

Bug 205151 - @ProjectServiceProvider useless on multiple service types when one is handled by LookupMerger and other is impl
Summary: @ProjectServiceProvider useless on multiple service types when one is handled...
Status: RESOLVED WONTFIX
Alias: None
Product: projects
Classification: Unclassified
Component: Generic Infrastructure (show other bugs)
Version: 7.1
Hardware: All All
: P3 normal (vote)
Assignee: Jesse Glick
URL:
Keywords: API
Depends on:
Blocks: 53058 200050
  Show dependency tree
 
Reported: 2011-11-15 14:10 UTC by Denis Anisimov
Modified: 2012-06-15 06:12 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Failing tests (2.08 KB, patch)
2011-12-07 21:07 UTC, Jesse Glick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Denis Anisimov 2011-11-15 14:10:40 UTC
Sometimes classes annotated with @ProjectServiceProvider as several services 
are not available in the project lookup.
I cannot localize this issue with exact steps to reproduce but here are my steps:
1) Create some class. F.e. SomeClass.java
2) Annotate it with @ProjectServiceProvider,
use two services and some project type.
In my case this is:

import org.netbeans.spi.project.ui.ProjectOpenedHook;

@ProjectServiceProvider(service={SomeClass.class,ProjectOpenedHook.class}, projectType = 
    "org-netbeans-modules-java-j2seproject")
public class SomeClass extends ProjectOpenedHook {

// ...... impl of the ProjectOpenedHook

}

3) Write some code that tries to lookup SomeClass in the project lookup :
project.getLookup().lookup(SomeClass.class)

The return value is null. SomeClass instance is not available in the lookup.
At the same time the SomeClass instance is loaded and invoked 
as ProjectOpenedHook instance. So the problem is only with instance of 
SomeClass service.

It seems this issue is either specific to the ProjectOpenedHook class which is 
loaded on the project initialization or more generic problem with several 
services using in the annotation. I didn't check it.

All works fine in case when SomeClass functionality is divided 
between two different classes with service=SomeClass.class and 
service=ProjectOpenedHook.class .
Comment 1 Jesse Glick 2011-12-05 15:39:13 UTC
Not sure what is going wrong for you. @PSP is used on dozens of classes in various project types, a number of which specify multiple service types. If you narrow it down to a test case please reopen.
Comment 2 Denis Anisimov 2011-12-05 16:01:59 UTC
(In reply to comment #1)
> Not sure what is going wrong for you. @PSP is used on dozens of classes in
> various project types, a number of which specify multiple service types. If you
> narrow it down to a test case please reopen.

The bug description contains exact example when @PSP doesn't work.
I'm  pretty sure that in most cases it works fine. I confirmed it here when 
two different classes are used instead of one f.e.
But this specific case is handled incorrectly .
As I said I don't know is it specific to ProjectOpenedHook service or some
different cases.
Comment 3 Jesse Glick 2011-12-07 21:07:23 UTC
Traced this back to a bug in Lookups.exclude. The documentation claims that "for an object not to be excluded, there has to be an inheritance path between the queried class and the actual class of the instance, that is not blocked by any of the excluded classes". In this case

Object
|
ProjectOpenedHook <-- excluded
|
C <-- queried & actual

yet the object is excluded.
Comment 4 Jesse Glick 2011-12-07 21:07:54 UTC
Created attachment 113937 [details]
Failing tests
Comment 5 Jesse Glick 2011-12-07 21:11:24 UTC
The workaround is to not register the implementation class in the 'service' list of @ProjectServiceProvider; it will not work in case the other service is covered by a LookupMerger. Anyway registering the implementation class this way is poor style; better to define a (possibly internal) API interface, listing the things that outside code might want to call, then implement and register that interface.
Comment 6 Jaroslav Tulach 2011-12-12 10:06:56 UTC
Probably I just improve the documentation. Lookup is based on inheritence, it cannot have result for C while not having results for its supertypes.
Comment 7 Jesse Glick 2011-12-12 20:43:50 UTC
Any technical reason why not? If this will not be fixed properly, then I will be forced to make the processor for @PSP just refuse to permit such a registration, since it would not work anyway. Incompatible but I guess project types will adapt to the change.

In the longer term, it may be possible to rewrite the implementation of createCompositeLookup to not delegate to "standard" Lookup impls at all and just directly service particular lookup templates, though I am unsure what this might break. Bug #200500 is related, as is bug #201893 comment #5.
Comment 8 Jaroslav Tulach 2012-05-21 10:50:01 UTC
Clarified in ergonomics#731c48c4a78c.

Btw. rather than inventing own implemementation of lookup and running a TCK against it, you can create new factory method in Lookups to cover your behavior.
Comment 9 Jesse Glick 2012-05-21 13:39:46 UTC
Not in fact fixed, just now documented to be broken at a lower level. Until the composite lookup can be rewritten, have to somehow prevent this situation from arising, so project type developers do not waste time figuring out what went wrong. Simplest fix would be to make @PSP's processor reject an attempt to register a class under two types in a subtype relationship, in case some LookupMerger might be handling the supertype. Determining at compile time whether such a LM exists may be difficult; might be able to issue a runtime exception instead, which would preserve compatibility for registrations not involving LM.
Comment 10 Quality Engineering 2012-05-23 09:11:58 UTC
Integrated into 'main-golden', will be available in build *201205230300* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/731c48c4a78c
User: Jaroslav Tulach <jtulach@netbeans.org>
Log: #205151: Clarified the behavior - one cannot query for subclasses of excluded classes
Comment 11 Jesse Glick 2012-06-13 19:50:40 UTC
Issuing a compile-time warning: core-main #2e0f2715649c
Comment 12 Quality Engineering 2012-06-15 06:12:35 UTC
Integrated into 'main-golden', will be available in build *201206150001* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/2e0f2715649c
User: Jesse Glick <jglick@netbeans.org>
Log: Issuing warning for @PSP cases possibly affected by #205151.