Hi Jason,
It is implemented and I will check-in over the week-end.
Here is the design:
1. When a ConfigurationData is loaded from a ConfigurationStore, its
dependencies can be altered based on scripts matching the pattern
dependencies-(.*).groovy. Here is the script I have been using to
perform my integration test:
configurationDataBuilder.configure {
addDependency(groupId: "org.springframework", artifactId:
"spring-core", version: "2.0.5", type: "jar")
}
2. When the GBeans of a configuration are loaded, i.e. when a
Configuration instance is created, GBeans can be updated based on
scripts matching the pattern gbeans-(,*).groovy. Here is my
integration test script:
import org.springframework.core.SpringVersion
gbeanDataBuilder.configure {
addGBean(name: 'name', gbean: SpringVersion) {
}
}
Scripts are searched in the configuration directory, i.e. in the same
folder of the META-INF folder of a configuration. This can be easily
changed by implementing a ScriptLocater strategy.
I had to add a groovy dependency to the j2ee-system config which is
not ideal as all the configurations will now see the Groovy classes.
Ideally, I would like to add another configuration where
ConfigurationDataTransformers can be declared and the out-of-the-box
GroovyTransformer can be specified. This is problematic as such a
configuration needs to be started after j2ee-system and before any
other configurations. I could add a dependency to this configuration
on the innermost configuration after j2ee-system.
Another approach would be to improve the isolation of configuration
classloaders, which should also address classloading problems
reported by users and the need to fiddle with hidden-classes
declarations. Assuming that I stick to the current configuration
approach where I declare a GroovyTransformer in j2ee-system, the
improvement I am thinking about is:
1) add a new classloading declaration element, maybe hidden-for-
children, where users can specify a pattern a la hidden-classes.
2) The above declarations are used to build a classloader which
simply delegates to the configuration classloader and filter out
classes matching the hidden-for-children declarations.
3) Children configurations are provided with the above classloader
instead of the configuration classloader.
With this thing in place, I will be able to add a groovy dependency
to j2ee-system w/o having to thing about the impacts to children
configurations as I can hide the groovy classes.
If you want me to check-in "as-is" this scripting stuff and revisit
the implementation as soon as I figure out which of the two
approaches, i.e. add another config or improve classloading
isolation, is the best, then let me know.
Thanks,
Gianny
On 29/10/2008, at 2:21 AM, Jason Warner wrote:
Hi Gianny,
Have you made any progress with this? Are you targeting this for
the 2.2 release (whenever that happens to be)?
Thanks!
On Fri, Oct 17, 2008 at 8:11 PM, Gianny Damour
<[EMAIL PROTECTED]> wrote:
Hi,
I am proposing the following implementation to start with:
1. In the META-INF folder of a config, we scan for files matching
the patterns "dependencies-(.*).groovy" and "extentions-(.*).groovy".
2. We execute the scripts "dependencies-(.*).groovy" which modify
dependencies. For instance, such scripts may look like:
configurationData + dependency(groupId: 'group', artifactId:
'artifact', version: '1.1', type: 'jar', importType: importType) --
add the declared dependency
configurationData - dependency(groupId: 'group', artifactId:
'artifact', version: '1.0', type: 'jar') -- remove the declared
dependency
This gives us the final classloader of the config.
3. We execute the scripts "extentions-(.*).groovy" which update the
GBeans, For instance, such scripts may look like:
gBeanBuilder.configure {
addGBean(BasicNodeInfo) { -- add a GBean
attribute(name: 'node1')
attribute(extendedJMXConnectorInfo: new
BasicExtendedJMXConnectorInfo(...))
reference(referenceName) {
pattern('aPattern')
pattern('aSecondPattern')
}
}
removeGBeansMatching('aPattern')
}
gBeanBuilder.updatedConfigurationData
The implementation of such scripts should be as simple as the
modification of config.xml.
The fact that they are collocated with the configuration they
modify increases cohesion. It would be neat to have such scripts
instead of the native or XStream serializations of config.ser.
Let me know your thoughts?
Thanks,
Gianny
On 16/10/2008, at 11:17 PM, Jason Warner wrote:
While David is more interested in the philosophy, I'd prefer to
know a little bit more about your thoughts on implementation.
Specifically what do you imagine would be involved in defining this
configuration? Would it be as simple as a definition in config.xml?
On Thu, Oct 16, 2008 at 4:08 AM, Gianny Damour
<[EMAIL PROTECTED]> wrote:
Hi David,
You are correct: the underpinning philosophy of these approaches is
to make it easier to modify pre-canned plugins through extension
points.
This may be a good approach to improve further the packaging model
of dependencies and services. Let's say that an end-user wants to
add a connector to the tomcat6 plugin. Instead of using the admin
console or updating his config.xml, he can simply deploy a
cumulative plan. This notion of cumulative plan is the key
differentiator as users can share their cumulative plans "as-is" -
i.e. w/o knowing what the plugin to be modified looks like. To
some extent, providing a plan ready to be deployed instead of
deployment instructions is better for novices.
I will work on the Groovy builder approach and post back more
details as I go.
Thanks,
Gianny
On 16/10/2008, at 10:59 AM, David Jencks wrote:
Hi Gianny,
First, I'd like to make sure I understand the philosophy behind
your proposals. IIUC they both involve the idea of making it easy
to modify an existing plugin rather than making it easy to replace
an existing plugin with a similar one.
Why is this a good idea? My idea has been that we should make it
easier to replace a plugin with a similar one than modify an
existing one, and then we will have the best of all worlds.
All this being said, I think your ideas are both quite
interesting. I'm especially interested in the groovy builder
approach.
I'll be fairly unavailable until next week but might keep thinking
about this anyway.
thanks!
david jencks
On Oct 15, 2008, at 3:46 AM, Gianny Damour wrote:
On 15/10/2008, at 4:16 AM, David Jencks wrote:
That's one of the main missing bits of functionality. Right now
the only way to get the g-p.xml is to use c-m-p or to export the
plugin from a server it's been deployed into, or to do something by
hand with jar packing and unpacking.
The biggest problem here, in my mind, is that jsr88 only wants you
to have one "plan": to deploy something you get to specify the
artifact and one "plan". Our deployment system is built around
jsr88 so we either have to condense the g-p.xml and plan into one
"plan" or abandon jsr88.
At the moment I'm thinking that one satisfactory solution might be
to more or less embed the plan into g-p.xml. Perhaps we could
avoid duplicating most of the dependency info by adding the
<import> element to the dependencies in g-p.xml. I guess we'd
expect a more or less empty <environment> element in the plan and
fill in the dependencies from the g-p.xml when deploying.
I guess another possibility might be to include the info from g-
p.xml in the environment element of the plan.
I've been thinking about this on and off for a long time and don't
have any solution I'm entirely happy with so discussion and more
ideas are more than welcome :-)
Hi,
Another possible solution would be to allow the extension of a
given configuration by other configurations. This could work like
the web.xml fragment mechanism of the upcoming servlet specs which
allows framework libraries to transparently install Web components
to the baseline components defined by the web.xml DD.
When a configuration starts it looks for complementing
configurations whose responsibility is to alter the baseline
configuration. The identification of complementing configurations
could be based on a simple naming convention scheme, e.g. if the
base configuration is org/tomcat6//car then all the configurations
matching the pattern org/tomcat6-transform-DiscriminatorName//car
are identified as complementing configurations.
If there are complementing configurations, then the baseline
ConfigurationData could be passed to them for arbitrary
transformation, e.g. add, update or remove dependencies. An updated
ConfigurationData is passed back and actually loaded by the kernel.
The main drawback of this approach is the added configuration
complexity. The main benefits is that it provides application
server configuration traceability and a mean to perform very simple
changes to a baseline configuration w/o having to redefine in its
entirety the configuration to be slightly changed.
In another thread about scripting language integration, I suggested
an even simpler approach whereby a script is executed to perform
ConfigurationData transformations.
If any of these two options are plausible solutions, then I am
happy to move forward with an implementation.
Thanks,
Gianny
thanks
david jencks
--
~Jason Warner
--
~Jason Warner