Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Plugin Development Environment (PDE) » Is it possible to substitute a bundle's class with another one coming from a fragment?
Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68094] Tue, 14 July 2009 12:06 Go to next message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Hi dear community,

I'm trying to substitute a class from a bundle I'm not allowed to
modify. I've tried using fragments, but with no result.

What I did was to create in the fragment a package with the same name as
the host bundle's target package where the class is contained. That
didn't work.

I've read also about the "import your exported" best practice. Not sure
If I understood it correctly: the OSGi runtime would import those
packages from other bundles, even when it's present in the declaring
bundle? Assuming this is right, I modified the fragment's MANIFEST to
include these "import your exported" packages. It didn't work either :(

Any tips on how to solve this?

Cheers,
Víctor.
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68110 is a reply to message #68094] Tue, 14 July 2009 18:57 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: eclipse-news.rizzoweb.com

Víctor Roldán Betancort wrote:
> Hi dear community,
>
> I'm trying to substitute a class from a bundle I'm not allowed to
> modify. I've tried using fragments, but with no result.
>
> What I did was to create in the fragment a package with the same name as
> the host bundle's target package where the class is contained. That
> didn't work.
>
> I've read also about the "import your exported" best practice. Not sure
> If I understood it correctly: the OSGi runtime would import those
> packages from other bundles, even when it's present in the declaring
> bundle? Assuming this is right, I modified the fragment's MANIFEST to
> include these "import your exported" packages. It didn't work either :(
>
> Any tips on how to solve this?

Try creating a Feature Patch (available in the New Project wizard); my
understanding is that a feature patch can be used to "patch" or replace
some part of an existing feature.

Hope this helps,
Eric
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68139 is a reply to message #68110] Wed, 15 July 2009 09:58 Go to previous messageGo to next message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Hi Eric,

thanks for your tip. Comments below:

Eric Rizzo escribió:
> Víctor Roldán Betancort wrote:
>> Hi dear community,
>>
>> I'm trying to substitute a class from a bundle I'm not allowed to
>> modify. I've tried using fragments, but with no result.
>>
>> What I did was to create in the fragment a package with the same name
>> as the host bundle's target package where the class is contained. That
>> didn't work.
>>
>> I've read also about the "import your exported" best practice. Not
>> sure If I understood it correctly: the OSGi runtime would import those
>> packages from other bundles, even when it's present in the declaring
>> bundle? Assuming this is right, I modified the fragment's MANIFEST to
>> include these "import your exported" packages. It didn't work either :(
>>
>> Any tips on how to solve this?
>
> Try creating a Feature Patch (available in the New Project wizard); my
> understanding is that a feature patch can be used to "patch" or replace
> some part of an existing feature.
>
> Hope this helps,
> Eric

I'm not sure this suits my needs. First, would need to create a feature
for the bundle to patch, since there isn't any defined for it. Second,
the feature patch look more like a forking a bundle, I would have to
include in the feature patch the modified version of the bundle to
patch. In the end I'll be maintaining a modified version of the whole
bundle. I would like to "complement" that bundle instead.

My situation is the following. The bundle is created by some colleague.
I'm can't modify his work (lets say, for bureaucratic reasons). That
bundle is shared among my colleagues in their workspaces. I can't ask
them to use my forked version. Instead, when they fetch the bundles that
conform my part of the work, they'd be also obtain a patch for another
bundle (this latter now being under my control).

Once the bureaucratic reasons expire, I'll be able to open a enhancement
request over that host bundle, and then discard the fragment patch or
whatever it shall be.

Is there any known hack to substitute code?

Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68150 is a reply to message #68139] Wed, 15 July 2009 12:41 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: ekkehard.gentz-software.de

a very good description how to use Patch Fragments you'll find here:
http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html

ekke

Víctor Roldán Betancort schrieb:
> Hi Eric,
>
> thanks for your tip. Comments below:
>
> Eric Rizzo escribió:
>> Víctor Roldán Betancort wrote:
>>> Hi dear community,
>>>
>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>> modify. I've tried using fragments, but with no result.
>>>
>>> What I did was to create in the fragment a package with the same name
>>> as the host bundle's target package where the class is contained.
>>> That didn't work.
>>>
>>> I've read also about the "import your exported" best practice. Not
>>> sure If I understood it correctly: the OSGi runtime would import
>>> those packages from other bundles, even when it's present in the
>>> declaring bundle? Assuming this is right, I modified the fragment's
>>> MANIFEST to include these "import your exported" packages. It didn't
>>> work either :(
>>>
>>> Any tips on how to solve this?
>>
>> Try creating a Feature Patch (available in the New Project wizard); my
>> understanding is that a feature patch can be used to "patch" or
>> replace some part of an existing feature.
>>
>> Hope this helps,
>> Eric
>
> I'm not sure this suits my needs. First, would need to create a feature
> for the bundle to patch, since there isn't any defined for it. Second,
> the feature patch look more like a forking a bundle, I would have to
> include in the feature patch the modified version of the bundle to
> patch. In the end I'll be maintaining a modified version of the whole
> bundle. I would like to "complement" that bundle instead.
>
> My situation is the following. The bundle is created by some colleague.
> I'm can't modify his work (lets say, for bureaucratic reasons). That
> bundle is shared among my colleagues in their workspaces. I can't ask
> them to use my forked version. Instead, when they fetch the bundles that
> conform my part of the work, they'd be also obtain a patch for another
> bundle (this latter now being under my control).
>
> Once the bureaucratic reasons expire, I'll be able to open a enhancement
> request over that host bundle, and then discard the fragment patch or
> whatever it shall be.
>
> Is there any known hack to substitute code?
>
> Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68162 is a reply to message #68150] Wed, 15 July 2009 15:31 Go to previous messageGo to next message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Ekke,

really interesting post. I tried and it worked, indeed.

However, I still have the same problem: It requires to maintain a
modified version of the host bundle.

After investigating a bit, I considered creating my own ClassLoadingHook
extension, and substituting the byte code of the target class with the
one from the corrected one (I'll be probably using ASM or something like
that).

Cheers,
Víctor.

ekke escribió:
> a very good description how to use Patch Fragments you'll find here:
> http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html
>
> ekke
>
> Víctor Roldán Betancort schrieb:
>> Hi Eric,
>>
>> thanks for your tip. Comments below:
>>
>> Eric Rizzo escribió:
>>> Víctor Roldán Betancort wrote:
>>>> Hi dear community,
>>>>
>>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>>> modify. I've tried using fragments, but with no result.
>>>>
>>>> What I did was to create in the fragment a package with the same
>>>> name as the host bundle's target package where the class is
>>>> contained. That didn't work.
>>>>
>>>> I've read also about the "import your exported" best practice. Not
>>>> sure If I understood it correctly: the OSGi runtime would import
>>>> those packages from other bundles, even when it's present in the
>>>> declaring bundle? Assuming this is right, I modified the fragment's
>>>> MANIFEST to include these "import your exported" packages. It didn't
>>>> work either :(
>>>>
>>>> Any tips on how to solve this?
>>>
>>> Try creating a Feature Patch (available in the New Project wizard);
>>> my understanding is that a feature patch can be used to "patch" or
>>> replace some part of an existing feature.
>>>
>>> Hope this helps,
>>> Eric
>>
>> I'm not sure this suits my needs. First, would need to create a
>> feature for the bundle to patch, since there isn't any defined for it.
>> Second, the feature patch look more like a forking a bundle, I would
>> have to include in the feature patch the modified version of the
>> bundle to patch. In the end I'll be maintaining a modified version of
>> the whole bundle. I would like to "complement" that bundle instead.
>>
>> My situation is the following. The bundle is created by some
>> colleague. I'm can't modify his work (lets say, for bureaucratic
>> reasons). That bundle is shared among my colleagues in their
>> workspaces. I can't ask them to use my forked version. Instead, when
>> they fetch the bundles that conform my part of the work, they'd be
>> also obtain a patch for another bundle (this latter now being under my
>> control).
>>
>> Once the bureaucratic reasons expire, I'll be able to open a
>> enhancement request over that host bundle, and then discard the
>> fragment patch or whatever it shall be.
>>
>> Is there any known hack to substitute code?
>>
>> Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #68175 is a reply to message #68150] Wed, 15 July 2009 18:22 Go to previous message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Finally managed to solve doing the following:

1. created a ClassLoadingHook
2. It intercepts the loading of the classes to be patched
3. Using ASM, it generates the byte code for the modified version and
its returned when calling:

org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook.processC lass(String,
byte[], ClasspathEntry, BundleEntry, ClasspathManager)


However, now my problem is the ASM jar file, which I included in the
fragment's classpath (Bundle-ClassPath) is not properly in runtime, and
when loading classes from it I get a ClassNotFoundException. I fixed it
by including ASM source code in the fragment, but it is not a solution I
really like.

Am I missing anything here? What should be done to properly make a jar
library be included in the host's classpath?

Cheers,
Víctor.


ekke escribió:
> a very good description how to use Patch Fragments you'll find here:
> http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html
>
> ekke
>
> Víctor Roldán Betancort schrieb:
>> Hi Eric,
>>
>> thanks for your tip. Comments below:
>>
>> Eric Rizzo escribió:
>>> Víctor Roldán Betancort wrote:
>>>> Hi dear community,
>>>>
>>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>>> modify. I've tried using fragments, but with no result.
>>>>
>>>> What I did was to create in the fragment a package with the same
>>>> name as the host bundle's target package where the class is
>>>> contained. That didn't work.
>>>>
>>>> I've read also about the "import your exported" best practice. Not
>>>> sure If I understood it correctly: the OSGi runtime would import
>>>> those packages from other bundles, even when it's present in the
>>>> declaring bundle? Assuming this is right, I modified the fragment's
>>>> MANIFEST to include these "import your exported" packages. It didn't
>>>> work either :(
>>>>
>>>> Any tips on how to solve this?
>>>
>>> Try creating a Feature Patch (available in the New Project wizard);
>>> my understanding is that a feature patch can be used to "patch" or
>>> replace some part of an existing feature.
>>>
>>> Hope this helps,
>>> Eric
>>
>> I'm not sure this suits my needs. First, would need to create a
>> feature for the bundle to patch, since there isn't any defined for it.
>> Second, the feature patch look more like a forking a bundle, I would
>> have to include in the feature patch the modified version of the
>> bundle to patch. In the end I'll be maintaining a modified version of
>> the whole bundle. I would like to "complement" that bundle instead.
>>
>> My situation is the following. The bundle is created by some
>> colleague. I'm can't modify his work (lets say, for bureaucratic
>> reasons). That bundle is shared among my colleagues in their
>> workspaces. I can't ask them to use my forked version. Instead, when
>> they fetch the bundles that conform my part of the work, they'd be
>> also obtain a patch for another bundle (this latter now being under my
>> control).
>>
>> Once the bureaucratic reasons expire, I'll be able to open a
>> enhancement request over that host bundle, and then discard the
>> fragment patch or whatever it shall be.
>>
>> Is there any known hack to substitute code?
>>
>> Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #599352 is a reply to message #68094] Tue, 14 July 2009 18:57 Go to previous message
Eric Rizzo is currently offline Eric RizzoFriend
Messages: 3070
Registered: July 2009
Senior Member
Víctor Roldán Betancort wrote:
> Hi dear community,
>
> I'm trying to substitute a class from a bundle I'm not allowed to
> modify. I've tried using fragments, but with no result.
>
> What I did was to create in the fragment a package with the same name as
> the host bundle's target package where the class is contained. That
> didn't work.
>
> I've read also about the "import your exported" best practice. Not sure
> If I understood it correctly: the OSGi runtime would import those
> packages from other bundles, even when it's present in the declaring
> bundle? Assuming this is right, I modified the fragment's MANIFEST to
> include these "import your exported" packages. It didn't work either :(
>
> Any tips on how to solve this?

Try creating a Feature Patch (available in the New Project wizard); my
understanding is that a feature patch can be used to "patch" or replace
some part of an existing feature.

Hope this helps,
Eric
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #599369 is a reply to message #68110] Wed, 15 July 2009 09:58 Go to previous message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Hi Eric,

thanks for your tip. Comments below:

Eric Rizzo escribió:
> Víctor Roldán Betancort wrote:
>> Hi dear community,
>>
>> I'm trying to substitute a class from a bundle I'm not allowed to
>> modify. I've tried using fragments, but with no result.
>>
>> What I did was to create in the fragment a package with the same name
>> as the host bundle's target package where the class is contained. That
>> didn't work.
>>
>> I've read also about the "import your exported" best practice. Not
>> sure If I understood it correctly: the OSGi runtime would import those
>> packages from other bundles, even when it's present in the declaring
>> bundle? Assuming this is right, I modified the fragment's MANIFEST to
>> include these "import your exported" packages. It didn't work either :(
>>
>> Any tips on how to solve this?
>
> Try creating a Feature Patch (available in the New Project wizard); my
> understanding is that a feature patch can be used to "patch" or replace
> some part of an existing feature.
>
> Hope this helps,
> Eric

I'm not sure this suits my needs. First, would need to create a feature
for the bundle to patch, since there isn't any defined for it. Second,
the feature patch look more like a forking a bundle, I would have to
include in the feature patch the modified version of the bundle to
patch. In the end I'll be maintaining a modified version of the whole
bundle. I would like to "complement" that bundle instead.

My situation is the following. The bundle is created by some colleague.
I'm can't modify his work (lets say, for bureaucratic reasons). That
bundle is shared among my colleagues in their workspaces. I can't ask
them to use my forked version. Instead, when they fetch the bundles that
conform my part of the work, they'd be also obtain a patch for another
bundle (this latter now being under my control).

Once the bureaucratic reasons expire, I'll be able to open a enhancement
request over that host bundle, and then discard the fragment patch or
whatever it shall be.

Is there any known hack to substitute code?

Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #599380 is a reply to message #68139] Wed, 15 July 2009 12:41 Go to previous message
Eclipse UserFriend
Originally posted by: ekkehard.gentz-software.de

a very good description how to use Patch Fragments you'll find here:
http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html

ekke

Víctor Roldán Betancort schrieb:
> Hi Eric,
>
> thanks for your tip. Comments below:
>
> Eric Rizzo escribió:
>> Víctor Roldán Betancort wrote:
>>> Hi dear community,
>>>
>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>> modify. I've tried using fragments, but with no result.
>>>
>>> What I did was to create in the fragment a package with the same name
>>> as the host bundle's target package where the class is contained.
>>> That didn't work.
>>>
>>> I've read also about the "import your exported" best practice. Not
>>> sure If I understood it correctly: the OSGi runtime would import
>>> those packages from other bundles, even when it's present in the
>>> declaring bundle? Assuming this is right, I modified the fragment's
>>> MANIFEST to include these "import your exported" packages. It didn't
>>> work either :(
>>>
>>> Any tips on how to solve this?
>>
>> Try creating a Feature Patch (available in the New Project wizard); my
>> understanding is that a feature patch can be used to "patch" or
>> replace some part of an existing feature.
>>
>> Hope this helps,
>> Eric
>
> I'm not sure this suits my needs. First, would need to create a feature
> for the bundle to patch, since there isn't any defined for it. Second,
> the feature patch look more like a forking a bundle, I would have to
> include in the feature patch the modified version of the bundle to
> patch. In the end I'll be maintaining a modified version of the whole
> bundle. I would like to "complement" that bundle instead.
>
> My situation is the following. The bundle is created by some colleague.
> I'm can't modify his work (lets say, for bureaucratic reasons). That
> bundle is shared among my colleagues in their workspaces. I can't ask
> them to use my forked version. Instead, when they fetch the bundles that
> conform my part of the work, they'd be also obtain a patch for another
> bundle (this latter now being under my control).
>
> Once the bureaucratic reasons expire, I'll be able to open a enhancement
> request over that host bundle, and then discard the fragment patch or
> whatever it shall be.
>
> Is there any known hack to substitute code?
>
> Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #599387 is a reply to message #68150] Wed, 15 July 2009 15:31 Go to previous message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Ekke,

really interesting post. I tried and it worked, indeed.

However, I still have the same problem: It requires to maintain a
modified version of the host bundle.

After investigating a bit, I considered creating my own ClassLoadingHook
extension, and substituting the byte code of the target class with the
one from the corrected one (I'll be probably using ASM or something like
that).

Cheers,
Víctor.

ekke escribió:
> a very good description how to use Patch Fragments you'll find here:
> http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html
>
> ekke
>
> Víctor Roldán Betancort schrieb:
>> Hi Eric,
>>
>> thanks for your tip. Comments below:
>>
>> Eric Rizzo escribió:
>>> Víctor Roldán Betancort wrote:
>>>> Hi dear community,
>>>>
>>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>>> modify. I've tried using fragments, but with no result.
>>>>
>>>> What I did was to create in the fragment a package with the same
>>>> name as the host bundle's target package where the class is
>>>> contained. That didn't work.
>>>>
>>>> I've read also about the "import your exported" best practice. Not
>>>> sure If I understood it correctly: the OSGi runtime would import
>>>> those packages from other bundles, even when it's present in the
>>>> declaring bundle? Assuming this is right, I modified the fragment's
>>>> MANIFEST to include these "import your exported" packages. It didn't
>>>> work either :(
>>>>
>>>> Any tips on how to solve this?
>>>
>>> Try creating a Feature Patch (available in the New Project wizard);
>>> my understanding is that a feature patch can be used to "patch" or
>>> replace some part of an existing feature.
>>>
>>> Hope this helps,
>>> Eric
>>
>> I'm not sure this suits my needs. First, would need to create a
>> feature for the bundle to patch, since there isn't any defined for it.
>> Second, the feature patch look more like a forking a bundle, I would
>> have to include in the feature patch the modified version of the
>> bundle to patch. In the end I'll be maintaining a modified version of
>> the whole bundle. I would like to "complement" that bundle instead.
>>
>> My situation is the following. The bundle is created by some
>> colleague. I'm can't modify his work (lets say, for bureaucratic
>> reasons). That bundle is shared among my colleagues in their
>> workspaces. I can't ask them to use my forked version. Instead, when
>> they fetch the bundles that conform my part of the work, they'd be
>> also obtain a patch for another bundle (this latter now being under my
>> control).
>>
>> Once the bureaucratic reasons expire, I'll be able to open a
>> enhancement request over that host bundle, and then discard the
>> fragment patch or whatever it shall be.
>>
>> Is there any known hack to substitute code?
>>
>> Maybe I could take a look also at byte-code manipulation frameworks....
Re: Is it possible to substitute a bundle's class with another one coming from a fragment? [message #599395 is a reply to message #68150] Wed, 15 July 2009 18:22 Go to previous message
Victor Roldan Betancort is currently offline Victor Roldan BetancortFriend
Messages: 524
Registered: July 2009
Senior Member
Finally managed to solve doing the following:

1. created a ClassLoadingHook
2. It intercepts the loading of the classes to be patched
3. Using ASM, it generates the byte code for the modified version and
its returned when calling:

org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook.processC lass(String,
byte[], ClasspathEntry, BundleEntry, ClasspathManager)


However, now my problem is the ASM jar file, which I included in the
fragment's classpath (Bundle-ClassPath) is not properly in runtime, and
when loading classes from it I get a ClassNotFoundException. I fixed it
by including ASM source code in the fragment, but it is not a solution I
really like.

Am I missing anything here? What should be done to properly make a jar
library be included in the host's classpath?

Cheers,
Víctor.


ekke escribió:
> a very good description how to use Patch Fragments you'll find here:
> http://konigsberg.blogspot.com/2009/06/patch-fragments-redux .html
>
> ekke
>
> Víctor Roldán Betancort schrieb:
>> Hi Eric,
>>
>> thanks for your tip. Comments below:
>>
>> Eric Rizzo escribió:
>>> Víctor Roldán Betancort wrote:
>>>> Hi dear community,
>>>>
>>>> I'm trying to substitute a class from a bundle I'm not allowed to
>>>> modify. I've tried using fragments, but with no result.
>>>>
>>>> What I did was to create in the fragment a package with the same
>>>> name as the host bundle's target package where the class is
>>>> contained. That didn't work.
>>>>
>>>> I've read also about the "import your exported" best practice. Not
>>>> sure If I understood it correctly: the OSGi runtime would import
>>>> those packages from other bundles, even when it's present in the
>>>> declaring bundle? Assuming this is right, I modified the fragment's
>>>> MANIFEST to include these "import your exported" packages. It didn't
>>>> work either :(
>>>>
>>>> Any tips on how to solve this?
>>>
>>> Try creating a Feature Patch (available in the New Project wizard);
>>> my understanding is that a feature patch can be used to "patch" or
>>> replace some part of an existing feature.
>>>
>>> Hope this helps,
>>> Eric
>>
>> I'm not sure this suits my needs. First, would need to create a
>> feature for the bundle to patch, since there isn't any defined for it.
>> Second, the feature patch look more like a forking a bundle, I would
>> have to include in the feature patch the modified version of the
>> bundle to patch. In the end I'll be maintaining a modified version of
>> the whole bundle. I would like to "complement" that bundle instead.
>>
>> My situation is the following. The bundle is created by some
>> colleague. I'm can't modify his work (lets say, for bureaucratic
>> reasons). That bundle is shared among my colleagues in their
>> workspaces. I can't ask them to use my forked version. Instead, when
>> they fetch the bundles that conform my part of the work, they'd be
>> also obtain a patch for another bundle (this latter now being under my
>> control).
>>
>> Once the bureaucratic reasons expire, I'll be able to open a
>> enhancement request over that host bundle, and then discard the
>> fragment patch or whatever it shall be.
>>
>> Is there any known hack to substitute code?
>>
>> Maybe I could take a look also at byte-code manipulation frameworks....
Previous Topic:diagnose plugin hang
Next Topic:Semantic highlighting
Goto Forum:
  


Current Time: Thu Mar 28 17:07:00 GMT 2024

Powered by FUDForum. Page generated in 0.03446 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top