Thanks for the comments. My responses are inlined...
1. The first is a follow-up
from one of John's initial comments - why is this at the component level and
not the project? All three of the "what would a feature do" actions
that you describe are project level actions and fail in the case of multiple
components per project. Since the majority of the platform is done at the
project level, what is the point of doing it more fine grained? Even though we
support multiple modules per project, we already know that there are several
limitations imposed by this that we can't change. I'd rather just do this at
the project level where it makes sense to put in project properties dialogs,
etc.
<kosta>The problem is what
happens if you do end up with multiple components in a project that are of a
different type… an ejb and a webapp. The set of features applicable to
each is different. Some of the effects of feature application will obviously
mix (like classpath), but some may not (like ui). If we intend to support
multiple components per project, I don’t see any way that we can avoid
associated features at the component level. </kosta>
<cdb>Agreed but this may be an
area we can reduce complexity in R1.0 - meaning, for 1.0 we could have some
restrictions in supported project structure if it helps us with a solid release
in this timeframe</cdb>
<kosta>Are you suggesting that IFeature should be property of a
project instead of a component or are you suggesting that we use natures
instead of features? If you are suggesting that we keep the IFeature concept,
then I don’t see a reduction in complexity. The main difference is
whether (get/add/remove)Feature methods are on IVirtualComponent or something
else like IFlexibleProject. So what are downsides of using natures, ignoring
the multiple components per project issue? (1) Natures don’t support
versioning. We can fake versioning by using the "one-of" capability.
Namely, we could define a natures "j2ee.webapp.13" and "j2ee.webapp.14"
that are one-of "j2ee.webapp" set. That gives us the correct
exclusivity, but loosing a more explicit version concept will limit what we can
do with UI. (2) We would have to somehow mark these natures as "features"
in order for us to know that it’s ok to add and remove them. We certainly
shouldn’t let the user remove the java nature through our interface or for
that matter add an unrelated nature (like PDE). (3) Natures are more difficult
to configure. That’s because natures are added to a project by id. When a
nature id is added to the project, the project instantiates the corresponding
nature class. The configure method (no args) is then called. This means that in
order for the wizard pages to communicate configuration information to the
configure method, they have to use an out-of-band method such as disk. I
specifically designed IFeature interface to avoid this problem. The feature
object is created by the feature-specific wizard page. The wizard populates the
feature object with configuration information and calls addFeature( IFeature )
method. The addFeature method implementation calls the configure method, but at
this point the feature object is carrying all of the config, so no out-of-band
communication is necessary. Not a deal breaker by any means, but natures do
have a more complicated programming model when it comes to this.</kosta>
2. On IFeature there are two
sets of activation methods - configure/deconfigure and activate/deactivate. I
think:
a) We should only have one set, which is called when the feature is
added/removed. If features require additional activation then they can add a
Nature to the project.
<kosta>The activate/deactivate
methods are certainly not critical to this proposal. Just so I understand, if we
don’t have these methods, how would a feature register/derigister a
listener? I don’t think using a nature works, natures only have
configure/deconfigure methods. Like I said, not critical, just gives the
feature writer a well-defined place to do setup and teardown. Otherwise they
have to figure out how to do it on their own. Some do it right. Some
don’t. </kosta>
If
we support this then we'd have to have our own nature on every project which
activated the features, and we could have a performance problem since many
features would not require activation on every workbench startup. We should
leave those issues to the existing platform mechanisms.
<kosta>My understanding is that
we would only support features on WTP projects, which will have our flexible
project model nature… I also don’t think there is a performance
impact. The IFeature implementations will have to be instantiated when
workspace is opened, so the plugin that they are in is going to be loaded
anyway. Calling a no-op activate method would not impact performance.
</kosta>
<cdb>
I do think we need to be careful about the term "WTP project" -
any eclipse project can be adapted to use components, we should consider this
possibility</cdb>
<kosta>You are right. I should have been more careful in the
terms that I used. What I meant to say is that in this proposal, features are a
property of a component and are only available if the flexible project nature
is added to the project.</kosta>
b) Instead of
having a single delegate, I'd vote for something similar to the current runtime
target hander. This decouples the feature implementation from the definition of
the feature and allows extensibility - someone else can come along and provide
additional support or actions to an existing feature.
I can see a design where configure/deconfigure operations are provided
by a chain of delegates. The feature definition might provide the first one,
but someone may come along and add more. Do people care if we stay consistent
with the nature api on this (which has configure/deconfigure methods, not
delegates)?<cdb>
I like the consistency here</cdb>
3. I don't understand the real need for feature groups, and I think this is
something that we could easily add in v1.1 or v2.0 if we start to get a lot of
features.
Not critical. On the other hand it’s real cheap to implement and
has two arguments for it: (1) reduction in verbosity (even in the first
release), and (2) some degree of protection from feature splits for server
adapter implementers. For instance, if we define a feature group
"j2ee-14" and a server adapter specifies that it supports all of the
features in that group then come next release if we decide to split some
features there is no impact on the server adapter.
<cdb> I can see the need for this
in R1.0 especially if they are bundled by server types - this is more of a
convenience</cdb>
4. I assume "one-of-feature" is the same as "feature sets"?
Do we forsee the requirement for real exclusive features in the first release?
If not, a much simpler solution to the problem is that when you create a
component of a specific type you are required to choose (or automatically based
on the J2EE level) a feature with the same name. So if I create an EJB module,
I have to pick one version of the "j2ee.ejb" feature. >From here,
we can show only the sub-features that are supported by this feature. We may
still need to label them as "base features" or have non-component
specific features, but I think those are different concepts than
"one-of".
Yes “one-of-feature” is the same as “feature
sets”. The terminology and capabilities are borrowed directly from
natures. There were several use cases that we came up for this. The two that I
remember of the top of my head is the top level features (web, ejb, etc) and
different web service implementation (doclet, annotations, manual).
5.
One of the requirements we discussed was the ability to have features pick up
their runtime jars from a specific runtime. In some cases even the JDK must
come from the runtime. However, there is no link between them in this spec -
features are free to get their libraries from wherever they choose. I know
Konstantin will cringe :), but one of our requirements is like #2 provided that
the jars are automatically picked up from the user's chosen runtime. Making every
feature to come up with their own way to do this will be very painful to the
user. We need to find a way to support this requirement and keep the existing
function in WTP.
<kosta>Just to be clear, the
thing that we do not like is having the project be associated with a server
runtime. I don’t have any problem with letting a particular feature
implementation associate itself with a runtime. I should have included it in
the spec, but let me try to describe here the way we talked about handling that
use case. WTP would define a feature like "j2ee.webapp". A server
vendor would provide a feature like "websphere.j2ee.webapp" that
would depend on “j2ee.webapp". When the user goes to create a
webapp, they can either choose just “j2ee.webapp”, in which case
they have to do more work to specify where jars are located, etc., or they can
choose “websphere.j2ee.webapp”, in which case they will be prompted
to select a websphere runtime and it’s very similar to how it behaves
right now.</kosta>
<cdb> I
think what Tim was trying to convey was where we are in the cycle, the base
features we will provide will need to be bound to a runtime. The core
features will eventually provide all the required jars/metadata files, but
until then, we need to provide a good user experience that "may" include
binding the component to a specific server. I know this isn't the user
experience you desire, but for R1.0 I'm not sure we have the runway for
anything else.</cdb>
<kosta>As long as we don’t bake that into the api, I have
no problem with this. I just want to make sure we have a clean and unencumbered
path to follow as we expand on IFeature in the following
releases.</kosta>
Is this sufficient or do we need to come up with something else?
Hope this helps and thanks for reviewing the spec.
- Konstantin