Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » Managing API-Leaks
Managing API-Leaks [message #539254] Thu, 10 June 2010 03:51 Go to next message
Daniel Krügler is currently offline Daniel Krügler
Messages: 853
Registered: July 2009
Senior Member
As of Eclipse 3.5.2 the concept of API-leaks has been
added to the API warnings/errors settings. I try to
understand this concept in more detail, because
some of my plug-ins produce these warnings, and I
would prefer to fix my code instead of ignoring
this test. Could someone give me a pointer where
this concept in explained in more detail? I found
only a very short description in

http://www.eclipse-tips.com/tutorials/26-api-tooling-tutoria l

but that doesn't really explain to me, what a non-API
type is. Surely it cannot be as simple as: This is
a type, which is not defined at the same place as
it is used in a public accessible other type, because
otherwise I would get such warnings in much situations
as I observe, e.g. if I have a plugin PA with an exported
public interface

interface IA {

org.eclipse.core.runtime.IStatus foo();

}

I don't get such a warning, even though I would
consider org.eclipse.core.runtime.IStatus as a non-API
type.

On the other hand I *get* this warning in some
situations where I don't understand the reason for this:

a) Plug-in P1 contains a third-party library (e.g.
jgoodies databinding). Selected types of this library
are exported (e.g. type ValueModel). I notice that I
don't get API leak warnings for all my public and
exported types, that use this third-party types, e.g.

interface Bla {

void foo(ValueModel);

}

- so fine, so good.

b) Plug-in P2 depends on plug-in P1 and *rexports* P1.

- also fine

c) Plug-in P3 depends on plug-in P2 and publishes a type
which contains a type from P1:

class Blub {

public void bar(ValueModel vm) {
...
}

}

*Now* I get the warning that the method Blub.bar has a non-API
parameter type ValueModel, but why?

I don't see the difference compared to the previous situation
and I see no way of fixing the problem. The proposed choices are:

1) Add @noreference tag: This is not the right solution, because
this method is supposed to be used by clients.

2) Create a usage-problem filter: I don't see why this should help, it
looks like solution (1), but from the perspective of a client.

Is this a defect in the way, the API leaks are recognized?
If so, I would like to say that it would be really good, if
there would be way to suppress this warning at least locally
(like @SuppressWarning), but there seems to be no way of doing
so. I wouldn't like to switch this setting completly off, so
I'm strongly interessted in alternative workarounds!

Any help is much appreciated,

Daniel
Re: Managing API-Leaks [message #539270 is a reply to message #539254] Thu, 10 June 2010 04:31 Go to previous messageGo to next message
Mariot Chauvin is currently offline Mariot Chauvin
Messages: 174
Registered: July 2009
Senior Member
Hi Daniel,

Daniel Krügler a écrit :
> As of Eclipse 3.5.2 the concept of API-leaks has been
> added to the API warnings/errors settings. I try to
> understand this concept in more detail, because
> some of my plug-ins produce these warnings, and I
> would prefer to fix my code instead of ignoring
> this test. Could someone give me a pointer where
> this concept in explained in more detail? I found
> only a very short description in
>
> http://www.eclipse-tips.com/tutorials/26-api-tooling-tutoria l
>
> but that doesn't really explain to me, what a non-API
> type is. Surely it cannot be as simple as: This is
> a type, which is not defined at the same place as
> it is used in a public accessible other type, because
> otherwise I would get such warnings in much situations
> as I observe, e.g. if I have a plugin PA with an exported
> public interface
>
> interface IA {
>
> org.eclipse.core.runtime.IStatus foo();
>
> }
>

Why do you consider org.eclipse.core.runtime.IStatus as non-API ?
The package does not contain "internal" keyword and is exported.

> I don't get such a warning, even though I would
> consider org.eclipse.core.runtime.IStatus as a non-API
> type.
>
> On the other hand I *get* this warning in some
> situations where I don't understand the reason for this:
>
> a) Plug-in P1 contains a third-party library (e.g.
> jgoodies databinding). Selected types of this library
> are exported (e.g. type ValueModel). I notice that I
> don't get API leak warnings for all my public and
> exported types, that use this third-party types, e.g.
>
> interface Bla {
>
> void foo(ValueModel);
>
> }
>
> - so fine, so good.
>
> b) Plug-in P2 depends on plug-in P1 and *rexports* P1.
>
> - also fine
>
> c) Plug-in P3 depends on plug-in P2 and publishes a type
> which contains a type from P1:
>
> class Blub {
>
> public void bar(ValueModel vm) {
> ...
> }
>
> }
>
> *Now* I get the warning that the method Blub.bar has a non-API
> parameter type ValueModel, but why?
>
> I don't see the difference compared to the previous situation
> and I see no way of fixing the problem. The proposed choices are:
>
> 1) Add @noreference tag: This is not the right solution, because
> this method is supposed to be used by clients.
>
> 2) Create a usage-problem filter: I don't see why this should help, it
> looks like solution (1), but from the perspective of a client.
>
> Is this a defect in the way, the API leaks are recognized?
> If so, I would like to say that it would be really good, if
> there would be way to suppress this warning at least locally
> (like @SuppressWarning), but there seems to be no way of doing
> so. I wouldn't like to switch this setting completly off, so
> I'm strongly interessted in alternative workarounds!
>
> Any help is much appreciated,
>
> Daniel

Regards,

Mariot
Re: Managing API-Leaks [message #539284 is a reply to message #539270] Thu, 10 June 2010 05:29 Go to previous messageGo to next message
Daniel Krügler is currently offline Daniel Krügler
Messages: 853
Registered: July 2009
Senior Member
On 10.06.2010 10:31, Mariot Chauvin wrote:
> Hi Daniel,
>
> Daniel Krügler a écrit :
>> As of Eclipse 3.5.2 the concept of API-leaks has been
>> added to the API warnings/errors settings. I try to
>> understand this concept in more detail, because
>> some of my plug-ins produce these warnings, and I
>> would prefer to fix my code instead of ignoring
>> this test. Could someone give me a pointer where
>> this concept in explained in more detail? I found
>> only a very short description in
>>
>> http://www.eclipse-tips.com/tutorials/26-api-tooling-tutoria l
>>
>> but that doesn't really explain to me, what a non-API
>> type is. Surely it cannot be as simple as: This is
>> a type, which is not defined at the same place as
>> it is used in a public accessible other type, because
>> otherwise I would get such warnings in much situations
>> as I observe, e.g. if I have a plugin PA with an exported
>> public interface
>>
>> interface IA {
>>
>> org.eclipse.core.runtime.IStatus foo();
>>
>> }
>>
>
> Why do you consider org.eclipse.core.runtime.IStatus as non-API ?
> The package does not contain "internal" keyword and is exported.

Well, I'm trying to understand the *definition* of API-leak.
If above description should be the base of the definition,
this does not explain my actual problem described here (because
the warning is created on types that are not in internal or
not-exported types):

>> I don't get such a warning, even though I would
>> consider org.eclipse.core.runtime.IStatus as a non-API
>> type.
>>
>> On the other hand I *get* this warning in some
>> situations where I don't understand the reason for this:
>>
>> a) Plug-in P1 contains a third-party library (e.g.
>> jgoodies databinding). Selected types of this library
>> are exported (e.g. type ValueModel). I notice that I
>> don't get API leak warnings for all my public and
>> exported types, that use this third-party types, e.g.
>>
>> interface Bla {
>>
>> void foo(ValueModel);
>>
>> }
>>
>> - so fine, so good.
>>
>> b) Plug-in P2 depends on plug-in P1 and *rexports* P1.
>>
>> - also fine
>>
>> c) Plug-in P3 depends on plug-in P2 and publishes a type
>> which contains a type from P1:
>>
>> class Blub {
>>
>> public void bar(ValueModel vm) {
>> ...
>> }
>>
>> }
>>
>> *Now* I get the warning that the method Blub.bar has a non-API
>> parameter type ValueModel, but why?
>>
>> I don't see the difference compared to the previous situation
>> and I see no way of fixing the problem. The proposed choices are:
>>
>> 1) Add @noreference tag: This is not the right solution, because
>> this method is supposed to be used by clients.
>>
>> 2) Create a usage-problem filter: I don't see why this should help, it
>> looks like solution (1), but from the perspective of a client.
>>
>> Is this a defect in the way, the API leaks are recognized?
>> If so, I would like to say that it would be really good, if
>> there would be way to suppress this warning at least locally
>> (like @SuppressWarning), but there seems to be no way of doing
>> so. I wouldn't like to switch this setting completly off, so
>> I'm strongly interessted in alternative workarounds!

- Daniel
Re: Managing API-Leaks [message #539327 is a reply to message #539254] Thu, 10 June 2010 08:27 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Daniel Krügler wrote:
> As of Eclipse 3.5.2 the concept of API-leaks has been
> added to the API warnings/errors settings. I try to
> understand this concept in more detail, because
> some of my plug-ins produce these warnings, and I
> would prefer to fix my code instead of ignoring
> this test. Could someone give me a pointer where
> this concept in explained in more detail? I found
> only a very short description in

An API leak is an API class with a method that uses or returns an
internal class (one in a package marted x-internal:=true)


>
> interface IA {
>
> org.eclipse.core.runtime.IStatus foo();
>
> }
>
> I don't get such a warning, even though I would
> consider org.eclipse.core.runtime.IStatus as a non-API
> type.

right, org.eclipse.core.runtime is not marked x-internal, so it is
public API and should not generate a warning.


> a) Plug-in P1 contains a third-party library (e.g.
> jgoodies databinding). Selected types of this library
> are exported (e.g. type ValueModel). I notice that I
> don't get API leak warnings for all my public and
> exported types, that use this third-party types, e.g.
>
> interface Bla {
>
> void foo(ValueModel);
>
> }
>
> - so fine, so good.
>
> b) Plug-in P2 depends on plug-in P1 and *rexports* P1.
>
> - also fine

What's the manifest statement for P1? You mean it re-exports it in the
Require-Bundle statement?

In general, we recommend against re-exporting API. It has implications
that make managing plugin versions complicated.

ex: P1 1.0.0, P2 re-exports P1 and is 1.0.0
next release: new API makes P1 1.1.0. Now P2 must be moved to 1.1.0
despite no change.

The rule of thumb is require bundles (or import package) for all of the
types you need.

Of course the advantage to a re-export is that's the only require bundle
your consumers will need. If you can manage that and the restrictions
are acceptable, then maybe it's OK for you.

>
> c) Plug-in P3 depends on plug-in P2 and publishes a type
> which contains a type from P1:
>
> class Blub {
>
> public void bar(ValueModel vm) {
> ...
> }
>
> }
>

If P2 re-exports P1 correctly and ValueModel is public API in your P1
manifest (what does its export package statement look like in P1) then
this might be an API tooling bug (if it was public API when used in P2
and P2 correctly re-exports P1 then it should be public API in P3). You
should open a bug.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: Managing API-Leaks [message #539391 is a reply to message #539327] Thu, 10 June 2010 11:21 Go to previous messageGo to next message
Daniel Krügler is currently offline Daniel Krügler
Messages: 853
Registered: July 2009
Senior Member
On 10.06.2010 14:27, Paul Webster wrote:
> Daniel Krügler wrote:
>> As of Eclipse 3.5.2 the concept of API-leaks has been
>> added to the API warnings/errors settings. I try to
>> understand this concept in more detail, because
>> some of my plug-ins produce these warnings, and I
>> would prefer to fix my code instead of ignoring
>> this test. Could someone give me a pointer where
>> this concept in explained in more detail? I found
>> only a very short description in
>
> An API leak is an API class with a method that uses or returns an
> internal class (one in a package marted x-internal:=true)

OK, thanks for that definition.

>> interface IA {
>>
>> org.eclipse.core.runtime.IStatus foo();
>>
>> }
>>
>> I don't get such a warning, even though I would
>> consider org.eclipse.core.runtime.IStatus as a non-API
>> type.
>
> right, org.eclipse.core.runtime is not marked x-internal, so it is
> public API and should not generate a warning.

With above definition in mind, this makes sense, yes (I only
mentioned this example to show that the word API-leak is not
necessarily self-explanatory. In some sense the definition of
interface IA shown above depends on a type that is not provided
by the same plug-in, thus we have some indirect dependency
leaking from org.eclipse.core.runtime).

>> a) Plug-in P1 contains a third-party library (e.g.
>> jgoodies databinding). Selected types of this library
>> are exported (e.g. type ValueModel). I notice that I
>> don't get API leak warnings for all my public and
>> exported types, that use this third-party types, e.g.
>>
>> interface Bla {
>>
>> void foo(ValueModel);
>>
>> }
>>
>> - so fine, so good.
>>
>> b) Plug-in P2 depends on plug-in P1 and *rexports* P1.
>>
>> - also fine
>
> What's the manifest statement for P1? You mean it re-exports it in the
> Require-Bundle statement?

The manifest-entry of P1 (which originally exports the third-party
packages are):

Export-Package: com.jgoodies.binding,
[..]
com.jgoodies.binding.value,

where package com.jgoodies.binding.value is the "container" of type
ValueModel mentioned above. Specifically, there is no internal
marker for the package.

The manifest entry of P2 (the re-exporter plug-in) is as follows:

Require-Bundle: P1;visibility:=reexport,

where P1 is the plug-in of P1.

And finally plug-in P3 has the following entry

Require-Bundle: P2

> In general, we recommend against re-exporting API. It has implications
> that make managing plugin versions complicated.

This is new to me. According to earlier reasoning, re-exporting
helps when you are refactoring your plugins. E.g. if I split the
functionality of Pa into two plug-ins Pa1 and Pa2 and I don't want
to break dependent plug-ins which have the entry

Require-Bundle: Pa

Thus, I consider re-exporting as an essential tool if a lot of
plug-in express there dependencies via "Require-Bundle". (We could
start now a discussion, that using "Require-Bundle" instead of
"Import-Package" is also bad style, but I don't do that here.
Fact is, that the majority of Eclipse-plug-ins still use this
mechanism and it also has some advantages)

> ex: P1 1.0.0, P2 re-exports P1 and is 1.0.0
> next release: new API makes P1 1.1.0. Now P2 must be moved to 1.1.0
> despite no change.

I agree that this may happen, but we have no additional version
requirements added.

> The rule of thumb is require bundles (or import package) for all of the
> types you need.
>
> Of course the advantage to a re-export is that's the only require bundle
> your consumers will need. If you can manage that and the restrictions
> are acceptable, then maybe it's OK for you.

This is my current position in the examples where my problem occurs.

>> c) Plug-in P3 depends on plug-in P2 and publishes a type
>> which contains a type from P1:
>>
>> class Blub {
>>
>> public void bar(ValueModel vm) {
>> ...
>> }
>>
>> }
>>
>
> If P2 re-exports P1 correctly and ValueModel is public API in your P1
> manifest (what does its export package statement look like in P1) then
> this might be an API tooling bug (if it was public API when used in P2
> and P2 correctly re-exports P1 then it should be public API in P3). You
> should open a bug.

This seems to indicate a bug, then. I will produce a simplified test
example and if I can reproduce this, I will create a bugzilla entry.

Thanks for your help,

- Daniel
Re: Managing API-Leaks [message #539529 is a reply to message #539391] Fri, 11 June 2010 04:23 Go to previous messageGo to next message
Daniel Krügler is currently offline Daniel Krügler
Messages: 853
Registered: July 2009
Senior Member
On 10.06.2010 17:21, Daniel Krügler wrote:
> On 10.06.2010 14:27, Paul Webster wrote:

[..]

>> If P2 re-exports P1 correctly and ValueModel is public API in your P1
>> manifest (what does its export package statement look like in P1) then
>> this might be an API tooling bug (if it was public API when used in P2
>> and P2 correctly re-exports P1 then it should be public API in P3). You
>> should open a bug.
>
> This seems to indicate a bug, then. I will produce a simplified test
> example and if I can reproduce this, I will create a bugzilla entry.

After some hours of attempting to reproduce the problem I finally
found the source of the problem: Once again it was due to one of the
very nasty *caching* errors of Eclipse. I needed to

a) Delete the API-leak-warning from the "Problems" view.

b) Clean the corresponding plug-in, where the ill-placed
API leak warning occurred.

I must assume that at some point of the compilation of my plug-ins
a false detection of the API leak test occurred and this leak
assignment was never cleared. Note that it didn't help to clean
or to close the project alone (I tried that several times) - You
*must* manually clean the warning from the "Problems" view yourself - puuuh!

Nevertheless thanks for your time explaining the API-leak warning,

- Daniel
Re: Managing API-Leaks [message #539581 is a reply to message #539391] Fri, 11 June 2010 08:25 Go to previous message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Thank you for answering my questions (even though it turned out to be a
clean that was needed :-)

As you found out, your stuff is all correct.

Daniel Krügler wrote:
>> In general, we recommend against re-exporting API. It has implications
>> that make managing plugin versions complicated.
>
> This is new to me. According to earlier reasoning, re-exporting
> helps when you are refactoring your plugins. E.g. if I split the
> functionality of Pa into two plug-ins Pa1 and Pa2 and I don't want
> to break dependent plug-ins which have the entry
>
> Require-Bundle: Pa

Your reasoning makes sense, and in the end it comes down to
consumability. As you mentioned later, there are advantages to offering
your consumers one bundle they need to use in order to consume your
functionality. It turned out to cause problems in the long run in the
platform UI case, but that's probably an extreme case in the other
direction.

>
> Thus, I consider re-exporting as an essential tool if a lot of
> plug-in express there dependencies via "Require-Bundle". (We could
> start now a discussion, that using "Require-Bundle" instead of
> "Import-Package" is also bad style, but I don't do that here.
> Fact is, that the majority of Eclipse-plug-ins still use this
> mechanism and it also has some advantages)
>

I too still consider Require-Bundle the most effective way to use other
bundle functionality.

Import Package has fine granularity, but it comes with a *huge* cost in
build complexity, versioning complexity, and just plain understanding.

I need to use org.eclipse.ui 3.6 ... OK, I understand that.

I need to use org.eclipse.ui.actions 3.6, org.eclipse.ui.menus 1.1
(corresponds to 3.6 release) and org.eclipse.ui.handlers 3.4
(corresponds to 3.6 release) ... doh!

Import packages is useful in a number of situations. In the platform,
we use Import-Package to use the com.ibm.icu.util stuff. That way RCP
packages can swap out com.ibm.icu for com.ibm.icu.base (which provides
the same classes, but just as pass-through to the JRE thus reducing the
footprint by ~4Meg).

But even though I personally would recommend Require-Bundle over
Import-Package, I would still also recommend requiring the bundles that
provide the API directly, except in the case where you expect to be
providing a small library for consumption and consider your 3 or 4
bundle split an implementation detail.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Previous Topic:problem exporting a plugin
Next Topic:Link a custom EditorInput to a resource type
Goto Forum:
  


Current Time: Tue Sep 02 10:09:25 EDT 2014

Powered by FUDForum. Page generated in 0.01775 seconds