Daniel Fagerstrom wrote:
Guido Casper wrote:
Ralph Goers wrote:
In short, the fact that Cocoon is just a bunch of parts that get configured is one of Cocoon's major strengths. However, the current configuration is pretty easy to understand and modify. If the replacement container makes the configuration more complex and less understandable that will really hurt the acceptance of the product.
TBH I always thought that DI moves some complexity from Java code to configuration. But I think that there is an overall gain in simplicity and transparence. If I look at Butterfly's applicationContext.xml it's quite straight forward IMHO.
Guido
I also took a look at Butterfly's applicationContext.xml and did some reading about Spring. I would say that the Spring configuration file looks straight forward from a component developer point of view. But for a Cocoon application developer, possibly without detailed knowledge about the internals of the components and of Cocoon and possibly not even beeing a Java programmer, the Spring configuration file will be much harder to understand and modify.
In the current Cocoon configuration file, you just connect component names to class paths and supply configuration data. In Spring you must as well supply wiring information about how the component is connected to other components thru setters. You need to describe the life cycle, if there are any initialization and destruction methods of the component and the names of them. You need to describe the life style, if it is e.g. a thread safe or poolable component.
IMO, the main problem with the Cocoon configuration file ATM, is its size, not its actual content. From a content POV it gives a rather nice SOC. Migrating to Spring style configuration files would give us a beast that application developers would not dare to go near as it mixes component configuration data with detailed knowledge about the dpeendencies, the life cycle and the life style of the component.
Using Spring style configuration files would make Cocoon rather fragile. I mean, it is a well known problem with property based dependency injection (the favoured style in Spring), that it is hard to know if the component is completely initialized yet. What happens if a user happen to remove a property dependency injection or a destruction attribute from the configuration file, or happens to forget to add them while using a newer version of the component.
While I agree with your concerns, I think a DI container can _potentially_ bring a lot in this area. The current problem with Cocoon's xconf file is that it is really free-form, and the variety of the components makes writing an XML grammar to check it near to impossible. Furthermore, each component picks up the information it needs in the configuration it is given and silently ignores what it doesn't care about (including typos of otherwise valid configurations!).
Combine this with the fact that docs are often incomplete and you have a good overview of why I most often go reading code of the configure() method to know what a component expects, and also why many users start shuddering when they have to change something in cocoon.xconf.
Now with DI, components have to be JavaBeans and their configuration has to be formally described using methods. The JavaBeans framework has been providing lots of interesting features for years to introspect classes and provide users with meaningful information for them to setup their objects (remember the good old BeanBox?). Each class can also provide its own BeanInfo object where it further describes its expectations with some additional human-oriented data.
What this means is DI allows us to:
- formally check the configuration file
- automatically produce the configuration documentation for each component (with the distinction of "preferred" and "expert" properties as defined by FeatureDescriptor [1])
- write tools to assist users in setting up the system.
Now you're right that leaving to non-technical users the responsibility to wire components will frighten a lot of them and may endanger the stability of the system. I raised this issue in the past. But there are some solutions to this.
A first solution is to leverage the BeanContext API [2] as a container-agnostic interface to perform some lookup-based wiring. We can then consider that only values of primitive types are configurable through the configuration file. That's roughly what we have today, but still somehow hardcodes the wiring of dependencies.
A second one is to have a layered configuration system: a built-in configuration file (possibly one for each component or for each "module" that we currently call "blocks") defines some default values and wirings for component properties, along with their lifestyle and lifecycle. The user-written configuration file then simply overrides some of these default values. That allows to have a running Cocoon with an empty configuration file (all defaults are used) while allowing users to override the properties they need to, feel the need to depending on their knowledge.
How does that sound?
<snip/>
Now what IMO is important is inter-block component handling. That will get us new and much needed functionality in form of "real blocks". And refactoring Cocoon to use Spring will not help us a bit in geting in this direction, AFAIU, as we need class loader isolation for that. And there are no containers featuring class loader isolation out there, except for Pier's one, IIUC.
Intra and inter-blocks are different concerns, but they are both discussed here because we have the opportunity to have a unified way of writing components in a container-independent way, which the death of Avalon makes a must have for Cocoon.
Sylvain
[1] http://java.sun.com/j2se/1.4.2/docs/api/java/beans/FeatureDescriptor.html
[2] http://www.anyware-tech.com/blogs/sylvain/archives/000141.html
-- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
