Elliot Metsger wrote:
Sorry Ate, everyone, for the delayed response. Life happens, right? :)
Really :)
First I am totally supportive of getting Pluto 2 to work with JS. The
rest is just details :)
Thanks, lets get started ;)
I know there are other projects (uPortal, Sakai) which have migrated to and
embedded (respectively) Pluto 1.1.
Ate Douma wrote:
<snip>
The Pluto 1.0.x object model API (OM)
=====================================
Pluto 1.0.x provided a fully interface based object model to represent
the web and portlet deployment descriptors (web.xml and portlet.xml).
Through factory methods, the Pluto 1.0.x container only used these
interfaces in its implementation. That allowed Jetspeed and other
portals to supply its own
implementation of the OM and use that to provide enhanced features
like database persistence, extended meta data, caching control, etc.
Of course, Pluto 1.0.x also provided its own implementation classes of
the OM and Jetspeed uses these as base classes but provides extended
implementations to
hook them up and into its own backend and management features.
Pluto 1.1.x completely dropped all of this. Instead, a new descriptor
API was provided with a complete new set of classes (no interfaces!)
which are used and
instantiated directly within the container with no factory support or
any other way of extending the current implementation.
As such, the current container only allows usage of the web.xml and
portlet.xml descriptors and features derived from them as provided by
the container.
Furthermore, as the loading and management of the descriptors is now
done directly (and only) by the container itself, there is no way for
Jetspeed to hook into
this process anymore.
Effectively, this means that descriptor persistence, caching, custom
extensions, *standard* support for custom portlet mode or window-state
mapping,
etc. all no longer are possible with the current Pluto container. Not
just for Jetspeed but any portal needing and depending on these features.
Here are my comments on the Descriptor OM. There was an intentional
design decision made with the 1.1 descriptor om: specifically that no
behaviors or responsibilities are attached to model.
I agree with this on general level.
The model is
orthogonal to the behaviors. Restricting the OM to what are essentially
just beans or value objects makes it easy for embedders: they aren't
forced to implement a bunch of interfaces.
Sure, but the way it is implemented now that also is as far as you can go.
The base problem is that creation and management of the descriptor beans is and
can only be done by the container itself.
That makes it very easy if you don't need more then the behavior which *the
container* attaches to them, but expanding beyond that isn't possible.
In my view, the OM *needs* to be defined as interfaces (or you would need again portal provided factories to get hold of concrete instances) and the container
should restrict itself to only using these interfaces.
There is nothing wrong with also providing concrete bean implementations like the current descriptor API does, and *by default* use these through a pluggable
Registry service. Out of the box, the container will then behave exactly as it does now, and this will have no impact for current embedders like uPortal and
Sakai. So its a simple and easy to provide win-win solution for both sides.
And if they want additional
behaviors like persistence they can add them in the portal implementation.
Which is the problem: we can't.
uPortal for example (and Eric correct me if I'm wrong) has a relatively
straight forward model of portlet -windows, -entities, -deployments, and
applications and has a hibernate-based implementation for persisting them.
No. I've looked at uPortal and AFAIK, they do have their own model for things like PortletWindow etc. but that doesn't extend to the deployment descriptor beans
themselves for which the whole management is under control of the Pluto container only.
The uPortal model objects are somewhat "attached" to the Pluto interaction, but for example the PortletWindow interface is itself wrapped inside the Pluto
container to *override* specific behavior like for getting the ServletContext. The fact Pluto needs this is based on its own Registry and PortletContext
management implementation which cannot be replaced at the moment.
And as Eric Dalquist also mentioned, providing our own PortletContext
implementation isn't possible at all (and we definitely do need that).
A little off topic, I think there improvments that need to be made to
the descriptor impl - Eric Dalquist has some good ideas. The goal there
being to load the descriptor impl from the webapp classloader instead of
having to pollute a shared classloader with the descriptor impl and all
of its dependencies.
Sure, that will probably work fine for us too, only the portal itself will need
that in its classloader AFAIK.
The Pluto 1.1.x/2.0 PortletContextManager, PortletDescriptorRegistry
and PortletServlet
=======================================================================================
With the switch to Pluto 1.1.x, the container added control and
management of the above mentioned deployment descriptors and fully
integrated them with the
container interaction which now depend on this management
*implementation*, and also hooked that up on the portlet application
context.
This means that now you need a separate container instance for each
portlet application and that the container itself loads and manages
the descriptors.
I'm not sure what you mean here. Generally the pluto container, along
with the descriptor api and impl are deployed in a shared classloader,
so you only need one instance.
The classes are shared yes, but multiple instances need to be created.
AFAIK now a separate instance of the PortletContainer is needed for each portlet application as it needs to be initialized with a ServletContext. This is needed
I think because the Registry and PortletContext managers are scoped to the ServletContext as well.
Also, interaction with the container now requires the use of the Pluto
provided PortletServlet (although that one possibly can be extended)
as it is tied to the
PortletContextManager directly (which in turn is tied to the
PortletDescriptorRegistry).
What about Jetspeed providing its own "PortletServlet" implementation.
The portlet servlet is pretty simple, initing the portlet, fixing up the
request and response and dispatching to the container.
Of course, we could even extend the Pluto PortletServlet for that end.
The problem is though, the current Pluto PortletServlet is completely tied to
the concrete PortalAdministrationService and PortletContextManager.
And as the container itself also requires the usage of these classes (not
interfaces) there is no point (yet) to do so.
You'll need to
have the assembler use your servlet implementation when assembling web.xml.
Jetspeed currently uses its own deploy-tool both for offline and runtime "infusion" of portal agnostic portlet applications which allows us to support "hot"
deployment of portlet applications in Jetspeed.
It might be interesting to evaluate how much overlap there is between the Pluto assembler and our deploy-tool component and see if we can join efforts to
provide a generic solution which can be used both by Pluto and Jetspeed?
Besides the obvious problem that this effectively blocks delegating
management of the context and descriptors for the portal, it also
forces the usage and
interaction with portlets to the Pluto provided implementation.
For instance, Pluto delegates interaction to each portlet through a
separate instance of its PortletServlet, while Jetspeed currently has
its own more generic
JetspeedContainerServlet which is not tied to a single portlet. The
Jetspeed solution allows for dynamically enabling/adding portlets (as
defined in
portlet.xml) without any need to rewrite the web.xml. But using the
Pluto PortletServlet requires changing the web.xml (and thus reloading
the context) to do so.
Normally the container will sit in a shared classloader, so there is
only a single instance of PortletServlet in a JVM.
No. A single instance for each reference in each web.xml, so at least one for
each portlet application, and for the default pluto container one for each
portlet.
When PortletServlet
is initialized, it registers the available portlets with the
RegistryService.
The Registry Service is an interface and a portal can have its own
implementation. You can dynamically register new portlets on the
registry service.
The PortletRegistryService is implemented by the Pluto PortletContextManager
which is used as a static singleton instance,
PortletContextManager.getManager().
This PortletContextManager is directly referenced by the Pluto PortletServlet. Additionally, itself directly references the PortletDecriptorRegistry, also as
static singleton instance. And finally, the Pluto PortletContainerImpl and the PortletEntityImpl also directly reference this static instance.
So, it currently is impossible to provide our own implementation of these
services, which I meant by these not being proper SPI but merely API services.
In my opinion, the static references to these service implementations need to
be replaced by interface references only to be able to provide our own.
Only then it makes sense to provide our own Jetspeed PortletServlet and/or
extend the Pluto PortletServlet.
The Pluto 1.1.x service provider interfaces (SPI)
=================================================
Although the new Pluto SPI (comprising of the
RequiredContainerServices and OptionalContainerServices) generally
provides a nice and simple interface to plugin
portal specific implementations, certain features available with Pluto
1.0.x are no longer available.
With Pluto 1.0.x, critical components as the PortletContext and
PortletWindow were accessed by the container through factory classes.
These no longer exist and the pluto container directly instantiates
its own implementations for these components.
Jetspeed however very much depends on its own extensions of these
components to provide support for features like parallel rendering,
clustering and attaching
additional meta data (or even preferences) to a PortletWindow or
PortletEntity.
Additionally, while Pluto 1.0.x allowed managing multiple
PortletWindows for a PortletEntity, this *Portlet Spec* feature has
been removed from the current
Pluto 1.1.x/2.0 container.
Lastly, not all of services referenced through these SPI interfaces
are only accessed through it.
For instance, the OptionalContainerService.getPortletRegistryService()
is by default implemented by the PortletContextManager. But, this
implementation is very
much directly used (as static instance even) within the container.
Effectively, the interface is now only an API portals might use, but
it cannot be replaced
and thereby cannot be regarded as a proper SPI interface anymore.
Let me come back on this issue, I need to look at the code a bit more to
understand. I do see where PCM is used instead of the interface. It
may be easy to switch to using the interface. E.g. PortletContainerImpl
already has a reference to OptionalContainerServices so looking up the
Registry Service by interface instead of instantiating PCM directly
should be doable. There may be classloader issue.
In general there should be a way to inject the impl that you require. If
there isn't a way, there's definintly a problem that we need to
design/code a solution to.
Cool, I think we'll be able to get to a proper solution for this.
Solution
========
I gotta run now but I'd like to take some more time and reply in more
detail, icluding commenting on the solution.
Thanks Ate and JS team for bringing these issues up!
Elliot
Thanks Elliot,
Regards,
Ate
As indicated earlier, solving the above issues such that Pluto 2.0 can
be made embeddable again, in Jetspeed or other portals, needs to be
done in a way which
maintains backwards compatibility for current Pluto 1.1.x users.
Although we don't have a clear proposal for this, our current idea is to:
- define new OM interfaces to be implemented by the current descriptor
api classes
- enhance the OptionalContainerServices SPI to provide additional
services for loading and managing the deployment descriptors
- enhance the OptionalContainerServices SPI to provide additional
services for accessing components like PortletContext, PortletWindow etc.
- refactor the container implementation to only use the OM interfaces
- refactor the container implementation to only use the SPI provided
services and no longer directly binding to its service implementations
When done properly, the above changes should still allow using the
current implementation without any functional or even technical
consequence.
Now, the above changes will mean a lot of work and lots of testing as
well to make sure everything remains working as expected.
We, as primary Jetspeed committers have much at stake here so we are
definitely willing to help out and do much of the grunt work.
And of course, we will have a large amount of work to do at Jetspeed
Portal side as well: all our Pluto Factory implementations have become
useless, all Pluto
OM packages (and some interfaces) have changed, and we will need to
provide new implementations for the Pluto SPI container services.
For our implementations of the Pluto SPI container services, we will
definitely look at the current Pluto provided implementations and
where possible try to
make use of them as much as possible. To that end, we will probably
also need to be able to hook in our own extensions which might require
some additional
refactoring but should not result in functional or technical changes
of the default Pluto services.
Note: we want to migrate to Pluto 2.0 for our next Jetspeed 2.2
release. But, for that release we'll stick to only using the JSR-168
container features.
Then, for the following major release, version 2.3 which we currently
have scheduled sometime this summer, we will provide full JSR-286
compliance.
So, our initial goal is to get Pluto 2.0 working again with Jetspeed-2
but stick to our current features.
This all is clearly not something which can be done or will be ready
overnight, nor possible to do all by ourselves.
But we do need to start resolving this ASAP so it won't hold up the
release of both Pluto 2.0 and Jetspeed 2.2 longer than needed.
As said: the above proposal is still just an idea. And of course how
to do all this, is fully open for debate and we are very interested in
hearing the opinions
of other committers and community members (also from other portals
embedding Pluto 1.1.x).
So please, provide feedback and ideas how to solve these issues. And
suggestions for alternative solutions will very much appreciated too!
With kind regards,
Dennis Dam
David Sean Taylor
Ate Douma