Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 329940 - Should detect recursive calls to ServiceFactory.getService
Summary: Should detect recursive calls to ServiceFactory.getService
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: 3.7   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 normal with 1 vote (vote)
Target Milestone: 3.7 M4   Edit
Assignee: BJ Hargrave CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 325409
  Show dependency tree
 
Reported: 2010-11-10 14:13 EST by Thomas Watson CLA
Modified: 2013-11-10 22:31 EST (History)
2 users (show)

See Also:
tjwatson: review+


Attachments
Patch to detect recursion, log an error and return null. (5.25 KB, patch)
2010-11-11 17:13 EST, BJ Hargrave CLA
no flags Details | Diff
fix + apifilter for new osgi API (6.19 KB, patch)
2010-11-11 17:32 EST, Thomas Watson CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Watson CLA 2010-11-10 14:13:34 EST
Currently if a ServiceFactory causes a recursive call into itself during getService the framework allows it.  This usually leads to endless recursion and a stack overflow.

At least two other framework implementations that I know of prevent this (Apache Felix and Prosyst).  In both cases they detect the recursive call, fire an error event and return null.  I don't think the spec mandates this behavior but it seems reasonable.
Comment 1 BJ Hargrave CLA 2010-11-11 17:13:12 EST
Created attachment 182940 [details]
Patch to detect recursion, log an error and return null.

I think we should detect recursive calls to the ServiceFactory. There is little point in no handling this since the thread/VM will fail with stack overflow.

This patch will detect the recursion, log an error and return null to the caller. A new ServiceException type is defined by OSGi as well.
Comment 2 Thomas Watson CLA 2010-11-11 17:32:03 EST
Created attachment 182941 [details]
fix + apifilter for new osgi API

Same patch but with an additional filter for API tooling to ignore the additional OSGi API.
Comment 3 Thomas Watson CLA 2010-11-11 17:32:54 EST
+1

BJ release when ready.
Comment 4 BJ Hargrave CLA 2010-11-11 20:54:34 EST
Released the updated patch with some comment corrections.
Comment 5 Thomas Watson CLA 2010-11-12 09:04:53 EST
BJ, in the OSGi bug and in comment 1 you mention that the framework should log an error.  My interpretation is that means a FrameworkEvent of type ERROR should be published.  In the fix you use a WARNING.  Should it be an ERROR event?
Comment 6 BJ Hargrave CLA 2010-11-12 09:40:49 EST
(In reply to comment #5)
> BJ, in the OSGi bug and in comment 1 you mention that the framework should log
> an error.  My interpretation is that means a FrameworkEvent of type ERROR
> should be published.  In the fix you use a WARNING.  Should it be an ERROR
> event?

Hmmm. I guess it should be an error. I copied the code from the service==null test which only logs a warning. Why is that not an error also?
Comment 7 Thomas Watson CLA 2010-11-12 09:53:41 EST
(In reply to comment #6)
> Hmmm. I guess it should be an error. I copied the code from the service==null
> test which only logs a warning. Why is that not an error also?

A strict reading of BundleContext.getService(ServiceReference<S>) indicates the null case should result in an ERROR also:

<javadoc>
If the service object returned by the {@code ServiceFactory} object is {@code null}, not an {@code instanceof} all the classes named when the service was registered or the {@code ServiceFactory} object throws an exception, {@code null} is returned and a Framework event of type {@link FrameworkEvent#ERROR} containing a {@link ServiceException} describing the error is fired.
</javadoc>

Perhaps we thought a null case was not really an ERROR on the ServiceFactory's part.  The ServiceFactory may have decided to blacklist some bundle and not grant it access to its own service.  Should we really log an error in that case?
Comment 8 BJ Hargrave CLA 2010-11-12 10:38:56 EST
(In reply to comment #7)
> A strict reading of BundleContext.getService(ServiceReference<S>) indicates the
> null case should result in an ERROR also:
> 

I guess all three tests should publish an ERROR per the javadoc. Note, I just redid that text for OSGi 4.3 so it does differ from 4.2.

<4.2 javadoc>
If the service object returned by the ServiceFactory object is not an instanceof all the classes named when the service was registered or the ServiceFactory object throws an exception, null is returned and a Framework event of type FrameworkEvent.ERROR containing a ServiceException describing the error is fired. 
</4.2 javadoc>

The 4.2 text only referred to the instanceof test. I updated the javadoc for 4.3 due to OSGi-bug 1781.
Comment 9 Thomas Watson CLA 2010-11-12 10:54:41 EST
I agree based on the new javadoc interpretation that ERROR should be used in all three cases.  But I still wonder if a factory returning null really is an Error condition or if a Warning is more appropriate in that case.
Comment 10 BJ Hargrave CLA 2010-11-12 11:24:43 EST
(In reply to comment #9)
> I agree based on the new javadoc interpretation that ERROR should be used in
> all three cases.  But I still wonder if a factory returning null really is an
> Error condition or if a Warning is more appropriate in that case.

The contract for ServiceFactory.getService is to return a service object. Null is not a service object but it is a choice by the factory to decline to return a service object. We could update the javadoc to declare returning null to be a warning, while an exception or recursion or an object not implementing all the named types is an error.