Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » e4 Best Practice to avoid extension points
e4 Best Practice to avoid extension points [message #1716232] Wed, 02 December 2015 11:27 Go to next message
Hauke Fuhrmann is currently offline Hauke FuhrmannFriend
Messages: 30
Registered: January 2015
Member
Hi there,

I quite often have the use case to register some resources in my
application, where I use custom extension points of E3. I might store
some meta-information with the resources such my client can load and use
the resources in some way.

What is the best-practice to work with such information in E4? I
understand that to register Java Classes, the best way is to use
OSGi-services, which I successfully do. However, for any other arbitrary
resources, it would be too much to create an OSGi-Service that publishes
the file by means of Java code.

Is there some other mechanism? E.g. has the e4 Application model some
storage for arbitrary data which I can contribute in some fragment? Or
is there some mechanism in the Manifest?
Or is the e3-extension-mechanism still the main way to do it, even in a
pure E4-Application?

Cheers,
Hauke
Re: e4 Best Practice to avoid extension points [message #1716235 is a reply to message #1716232] Wed, 02 December 2015 11:55 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6566
Registered: July 2009
Senior Member
Hi,

I'm certainly biased because I'm on my "Get rid of all Framework stuff
in my business code trip" and Extension Points don't have a place there
because:
* to read them you need to use Equinox APIs
* it is an Equinox only API (although in theory it can be used on other
OSGi-Container I think nobody really tried that)

In contrast to that DS is subject to injection (you can even let the
framework inject you a list of OSGi-Services but that requires an
extension not shipped as part of plain e4)

In the e4 framework we introduced 2 extension points and looking back I
totally regret that and I'd like to get rid of them (in reality they'll
never go away but will get deprecated).

I would definately use DS eg in e(fx)clipse we are registering CSS-Files
through DS and with the help of @Component annotations this even easier
than with extension points.

Tom

On 02.12.15 12:27, Hauke Fuhrmann wrote:
> Hi there,
>
> I quite often have the use case to register some resources in my
> application, where I use custom extension points of E3. I might store
> some meta-information with the resources such my client can load and use
> the resources in some way.
>
> What is the best-practice to work with such information in E4? I
> understand that to register Java Classes, the best way is to use
> OSGi-services, which I successfully do. However, for any other arbitrary
> resources, it would be too much to create an OSGi-Service that publishes
> the file by means of Java code.
>
> Is there some other mechanism? E.g. has the e4 Application model some
> storage for arbitrary data which I can contribute in some fragment? Or
> is there some mechanism in the Manifest?
> Or is the e3-extension-mechanism still the main way to do it, even in a
> pure E4-Application?
>
> Cheers,
> Hauke
Re: e4 Best Practice to avoid extension points [message #1716240 is a reply to message #1716235] Wed, 02 December 2015 12:17 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2787
Registered: July 2012
Senior Member
I totally agree with Tom that Extension Points shouldn't be used with E4 applications. Declarative Services are much better in doing these things. Additionally to the facts Tom already provided, you also need to consider that Extension Points have a 1 to many relation, while services have a many-to-many relation.

Regarding the resource question, I'm not sure what kind of resources you are talking about. But using the annotations as Tom said, it is really easy to setup a service that provides the resource (e.g. file). So at first it feels a bit overengineered compared to Extension Points, but from my experience you will benefit from it in terms of performance, usability and clearer code.
Re: e4 Best Practice to avoid extension points [message #1716242 is a reply to message #1716240] Wed, 02 December 2015 12:31 Go to previous messageGo to next message
Hauke Fuhrmann is currently offline Hauke FuhrmannFriend
Messages: 30
Registered: January 2015
Member
Hi Tom and Dirk,

thanks for your opinions. Gives me some arguments to discuss with my
colleagues.

One colleague just mentioned this:
What do you think about the "provide-capabilities" and
"require-capabilities" of OSGi >=4.3
http://wiki.osgi.org/wiki/Provide-Capability

From first looks you can attach any arbitrary key-value pairs with a
capability such as

Provide-Capability: css-resource; path=mypath

Instead of consuming it by some Require-Capability I guess you could
read that information through the OSGi-API.
Looks quite similar to what Extension Points do...

Any opinion?

Cheers,
Hauke
Re: e4 Best Practice to avoid extension points [message #1716284 is a reply to message #1716242] Wed, 02 December 2015 16:59 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2787
Registered: July 2012
Senior Member
You want to misuse capabilities to transport configuration values? I would not suggest this.

Have you looked into the configuration admin? Maybe that fits your needs. http://wiki.osgi.org/wiki/Configuration_Admin
Re: e4 Best Practice to avoid extension points [message #1716303 is a reply to message #1716284] Wed, 02 December 2015 18:45 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6566
Registered: July 2009
Senior Member
I have to agree with Dirk - don't start abusing capabilities. And I
repeat don't introduce any OSGi-Deps in your code.

Tom

On 02.12.15 17:59, Dirk Fauth wrote:
> You want to misuse capabilities to transport configuration values? I
> would not suggest this.
> Have you looked into the configuration admin? Maybe that fits your
> needs. http://wiki.osgi.org/wiki/Configuration_Admin
Re: e4 Best Practice to avoid extension points [message #1716384 is a reply to message #1716303] Thu, 03 December 2015 12:21 Go to previous messageGo to next message
Gernot Krause is currently offline Gernot KrauseFriend
Messages: 22
Registered: June 2014
Junior Member
Hi!

I have a general question: If I replace extension points by services how do I manage that a plugin registers a functionality at the service?

In my case for example I have an RCP application with a base plugin A. Here I want to load and parse data from different files into my application. I can define a IParseDataService and let it be injected into my LoadDataFileHandler. Whenever the user selects a file the file is passed to the service and the service should then select the right parser based on the file's type or file extension.

The parsers for each file type are provided by other plugins (B,C,D, ...). Using a service that selects the right parser requires that each plugin B, C, D, ... registers its specific parser at the service. But which class of the plugins is responsible for this? I am looking for something like an Activator. Is it done by a model processor or a model addon in E4? I mean whenever one of the plugins is loaded (or one of its classes) the parser needs to be registered, doesn't it? And removed when plugin is stopped.

Is this reasonable?

Thanks,
Gernot.
Re: e4 Best Practice to avoid extension points [message #1716405 is a reply to message #1716384] Thu, 03 December 2015 14:11 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6566
Registered: July 2009
Senior Member
No no activator is required (or if you ask me violates a good design),
but you use DS.

@Component
public class ParserComponent {
private List<Parser> parserList = new ArrayList<>();

@Reference(cardinality=ReferenceCardinality.MULTIPLE,
policyOption=ReferencePolicyOption.GREEDY)
public void registerParser(Parser parser) {
synchronized(parserList) {
parserList.add(parser);
}
}

public void unregisterParser(Parser parser) {
synchronized(parserList) {
parserList.remove(parser);
}
}


public Optional<DomainObject> parseFile(String file) {
Optional<Parser> parser
synchronized(parserList) {
parser = parserList.stream()
.filter( p -> p.test(file) ).findFirst();
}
return parser.map( p -> p.parse(file) );
}
}

In your code you write:

public class MyUI() {
@Inject
ParserComponent component;

void bla() {
component.parseFile( "helloworld.xml" ).ifPresent(
this::updateUI );
}

void updateUI(DomainObject o) {
}
}


Just to sum this up there's even cooler stuff you can do with the Help
of context functions, ... but this is hard to explain in newsgroup
postings and even blogs and you'd have to invite me to your company for
a workshop ;-)

I've some slideware uploaded from my latest presentations on e4 architecture
*
https://www.eclipsecon.org/europe2015/sites/default/files/slides/JavaFX%20APIs_0.pdf
*
https://www.eclipsecon.org/europe2015/sites/default/files/slides/JavaFX%20Smart%20Code%20Econ_0.pdf

Where the 2nd one present the so called TypeProvider infrastructure who
even supports the usage of DI in your service layer but once more
describing how you implement and use this kind of thing is out-of-scope
in none face to face discussion.

Tom

On 03.12.15 13:21, Gernot Krause wrote:
> Hi!
>
> I have a general question: If I replace extension points by services how
> do I manage that a plugin registers a functionality at the service?
>
> In my case for example I have an RCP application with a base plugin A.
> Here I want to load and parse data from different files into my
> application. I can define a IParseDataService and let it be injected
> into my LoadDataFileHandler. Whenever the user selects a file the file
> is passed to the service and the service should then select the right
> parser based on the file's type or file extension.
>
> The parsers for each file type are provided by other plugins (B,C,D,
> ...). Using a service that selects the right parser requires that each
> plugin B, C, D, ... registers its specific parser at the service. But
> which class of the plugins is responsible for this? I am looking for
> something like an Activator. Is it done by a model processor or a model
> addon in E4? I mean whenever one of the plugins is loaded (or one of its
> classes) the parser needs to be registered, doesn't it? And removed when
> plugin is stopped.
>
> Is this reasonable?
>
> Thanks,
> Gernot.
>
Re: e4 Best Practice to avoid extension points [message #1716406 is a reply to message #1716405] Thu, 03 December 2015 14:14 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6566
Registered: July 2009
Senior Member
Oh and the guy responsible for getting all that up and running is
org.eclipse.equinox.ds which implements the Extender Pattern.

What this OSGi-Bundle does is that it observes all bundles that come and
go, looks at their MANIFEST.MF (search there for the
ServiceComponent-Header) files and registers all of them in the
OSGi-Service registry.

Tom

On 03.12.15 15:11, Tom Schindl wrote:
> No no activator is required (or if you ask me violates a good design),
> but you use DS.
>
> @Component
> public class ParserComponent {
> private List<Parser> parserList = new ArrayList<>();
>
> @Reference(cardinality=ReferenceCardinality.MULTIPLE,
> policyOption=ReferencePolicyOption.GREEDY)
> public void registerParser(Parser parser) {
> synchronized(parserList) {
> parserList.add(parser);
> }
> }
>
> public void unregisterParser(Parser parser) {
> synchronized(parserList) {
> parserList.remove(parser);
> }
> }
>
>
> public Optional<DomainObject> parseFile(String file) {
> Optional<Parser> parser
> synchronized(parserList) {
> parser = parserList.stream()
> .filter( p -> p.test(file) ).findFirst();
> }
> return parser.map( p -> p.parse(file) );
> }
> }
>
> In your code you write:
>
> public class MyUI() {
> @Inject
> ParserComponent component;
>
> void bla() {
> component.parseFile( "helloworld.xml" ).ifPresent(
> this::updateUI );
> }
>
> void updateUI(DomainObject o) {
> }
> }
>
>
> Just to sum this up there's even cooler stuff you can do with the Help
> of context functions, ... but this is hard to explain in newsgroup
> postings and even blogs and you'd have to invite me to your company for
> a workshop ;-)
>
> I've some slideware uploaded from my latest presentations on e4 architecture
> *
> https://www.eclipsecon.org/europe2015/sites/default/files/slides/JavaFX%20APIs_0.pdf
> *
> https://www.eclipsecon.org/europe2015/sites/default/files/slides/JavaFX%20Smart%20Code%20Econ_0.pdf
>
> Where the 2nd one present the so called TypeProvider infrastructure who
> even supports the usage of DI in your service layer but once more
> describing how you implement and use this kind of thing is out-of-scope
> in none face to face discussion.
>
> Tom
>
> On 03.12.15 13:21, Gernot Krause wrote:
>> Hi!
>>
>> I have a general question: If I replace extension points by services how
>> do I manage that a plugin registers a functionality at the service?
>>
>> In my case for example I have an RCP application with a base plugin A.
>> Here I want to load and parse data from different files into my
>> application. I can define a IParseDataService and let it be injected
>> into my LoadDataFileHandler. Whenever the user selects a file the file
>> is passed to the service and the service should then select the right
>> parser based on the file's type or file extension.
>>
>> The parsers for each file type are provided by other plugins (B,C,D,
>> ...). Using a service that selects the right parser requires that each
>> plugin B, C, D, ... registers its specific parser at the service. But
>> which class of the plugins is responsible for this? I am looking for
>> something like an Activator. Is it done by a model processor or a model
>> addon in E4? I mean whenever one of the plugins is loaded (or one of its
>> classes) the parser needs to be registered, doesn't it? And removed when
>> plugin is stopped.
>>
>> Is this reasonable?
>>
>> Thanks,
>> Gernot.
>>
>
Re: e4 Best Practice to avoid extension points [message #1716416 is a reply to message #1716406] Thu, 03 December 2015 15:14 Go to previous message
Brian de Alwis is currently offline Brian de AlwisFriend
Messages: 876
Registered: January 2012
Senior Member

I'm late to the game, but contrary to Tom and Dirk, I love extension points. Extension points are declarative, non-executable data and are great for separating the producers from consumers.

To deal with Tom's concern on extension points, separate your configuration code (how things are wired together based on the data from the extensions) from your "business" code / behaviour. You want to do that for good testing purposes anyways. Don't embed knowledge of the registry within your business.

Brian.


Eclipse Platform committer. Ask me about Eclipse support, training, and consulting.
Previous Topic:Validate plug-ins: Missing Constraint on bundle
Next Topic:Null Worbench after changing bundle configurations
Goto Forum:
  


Current Time: Mon Sep 28 06:40:24 GMT 2020

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

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

Back to the top