Leo Simons wrote:><engine> <library dir=".">?
The <library> declaration is simply the declaration of a directory in which you have "jar extension jar files". This is the same notion as the java -Djava.ext.dirs except that it packaged with and only visible within the scope of the classloader (engine) in which it defined.
ah. So the contract is "anything you put in a library dir will be treated with respect to this block/engine as if it were a downloaded optional package".
Path structures inside a classloader defition are problamatic because they result in physical paths in block defintions. This was the reason for the introduction of the <resource> tag - a better approach that uses a logical repository.
hmm. Have you thought about using classworlds? Also, what about using sourceresolve? (...thinking...) This is imo something to tackle as part of a not-so-avalon-specific bundle api.
.xprofile and block.xml -----------------------
I started changing the samples, but it occured to me that the rule is "everything that can be defined in the .xprofile can be overriden inside the <component/> element of a block.xml". What should be added is what the rules are for overriding/merging those, and then the .xprofile settings seperated out. Right?
Not sure if you saying "should be added to the documetation" or "should be added to the implementation".
docs. They're full of samples but I keep getting the feeling the samples don't come close to outlining the scope of actual possibilities, or the limits.
Currently profiles exist only as a facility enabling automated assembly (pre-packaged deployment information). A <component> tag is simply declaring a new profile dynamically.
There have already been requests for things like component directives by reference to a profile (e.g.)
Okay, I thought this was already possible. So a <component/> tag in a block.xml contains a profile defitions, it doesn't customize an existing one.
Where do I find those rules?
There isn't a formal model for rules related to what is and isn't modifiable reative to profiles. I have been thinking about this on and off with respect to the JMX stuff. For everything in the meta-data model (all of the directives) we really need additional information about read versus writable, and probably some additional typing and consttrraint info. The biggest job is dealing with configurations and enabling arbitary configuration data.
yeah, dtds won't work there. There's alternatives like relaxng that might help here though. Regardless of a formal model, how does one discern current limitations of the implementation codebase?
Custom containers -----------------
ok, you confused me even more :D
let me explain a little where I'm going. I have a fortress-based servlet application (say, for example, a scriptable web-based media management catalogus and webradio broadcast system). Now I want to port this application to run inside a merlin (CLI) environment. IE, merlin replaces the servlet engine.
I've extended fortress' DefaultContainer to provide some very specific features (example: it handles communication with the linux ALSA system), so I don't want to just port my components to merlin. I want to embed fortress inside merlin.
I want to develop (example) a graphical swing client that runs inside the same merlin instance and/or remotely. For the local version, I want sm.lookup() calls inside this block to be resolved to my fortress-based container.
So:
.-----------------------------------.
| Merlin |
| |
| -1--------------------- 3 /-----some binary tcp/ip-based call
| | MyFortressContainer |<------/ | that is the equivalent of
| | ------ ------ | | lookup()
| | | C1 | | C2 | | |
| | ------ ------ |<-------- |
| ----------------------- | |
| | |
| -2--------------------- <Redirect>|
| | MyGraphicalClient | | |
| | ------ ------ | | |
| | | C3 | | C4 |-lookup("C1")--| |
| | ------ ------ | |
| ----------------------- |
.-----------------------------------.now, what I want to create here is the box labelled "1"; process labelled "3" does not yet exist but will probably involve a MyRemoteClient. Box labelled "2" will be a more or less standard merlin block, but I might build it (example) using Berin's GuiApp which might mean another embedded fortress instance.
However, my guess is that you want to have the services available from you component as a function of the configuration of the component.
going further, I would like merlin to just poll whether a service is provided by MyFortressContainer. There might be, for example, a QOS assurance built-in that will disable service availability based on instrumentation results, and merlin should just query at lookup time whether a service is available.
A little off-topic but I would recommend using [<repository/>]
"Repository" introduces a load of implications I'm not ready to deal with. My guess is that it will be easier for me to switch from filesystem to repo than the other way around :D
In either case (component or container), if you want to provide the Merlin assembly system with information about available services that are established dynamically.
yes!
The assembly system get this information from Appliance.getServices(). The appliance is a regular component that is supplied with the deplyment information (configuration, etc.). An implementation would use the configuration information (roles files etc. in the Fortrress case) to build the descriptions of the services it is capable providing.
ok, so in merlin-speak, I'm not looking towards providing a Container implementation but an Appliance implementation. Makes me wonder when one would want to provide a custom Container implementation, ever, at all.
<component name="test1" class="tutorial.FortressCallingComponent" activation="startup">
<dependencies> <!-- what does this look like??? --> <dependency key="somethinghostedinfortress" type="Component1"/> </dependencies>
Merlin takes care of dependency resolution automatically. If "test1" needs a service then merlin will take care of resolving that dependency.
well, I don't want it to! Or really, I want to tell it how to take care of that: I want to be able to configure at deployment time (perhaps even runtime) that for some services that MyGraphicalClient asks for, merlin will defer the call to MyFortressContainer.
- what is the minimum contract o.a.a.m.f.FortressContainer should support?
Nothing.
The only real difference [to a component] is that is has access to other appliance instances and as such it can do a lot more dynamic stuff.
ehm. Okay. So it doesn't *have* to do anything but it *can* gain access to any part of the system if it wants to. Got it. However, that raises security questions...and seems to violate IoC.
Clearly, it will not do everything a 'normal' merlin container instance does. For example, it's not going to support stuff like container nesting. It's just going to provide whatever it is that fortress provides.
Which is why it should be declared as a <component>, not <container>. If you declare it as a container then you containment side appliance has additional responsibilities including handling nested components, containers, includes, etc.
Maybe the contract on a <container/> implementation is a bit heavy then?
- what's the deal with the Merlin DefaultContainer and StandardBlock? There's next to no implementation in DefaultContainer, yet this works in 'some' way 'somewhere'.
The DefaultContainer doesn't need to do anything because all of the work is done behind the scenes in StandardBlock.
everytime I read "behind the scenes" it seems to be one of those occurences when the runtime callstack becomes difficult to track in a debugger for lineair minds such as me :D
Throught the Merlin system there is a strict seperation of "containement" concerns from "component". Given that the services that the FortressContainerwould be providing would be a function of its configuration - you are taking about computation that is happening on the container side.
hmm. COP-wise, I want merlin to provide a sandbox containment environment containing my fortress instance, and I want it to route some component lookup calls to this instance, where the "some" is to be dynamically configurable. So from merlin's view, I am talking about computations on both the container and the component sides. Indeed, I am wanting to modify the containment environment.
To make this easy, I have been thinking about putting in place an AbstractAppliance - something that contains default implementations of everything such that all you need to do is grab the supplied configuration and override the following methods:
ServiceDescriptor[] getServices(); Object resolve( Object source, String ref );
The getServices() method would simply build an array of ServiceDescriptors using the information from the configuration supplied to the appliance. The resolve method would return service references based on the fortress implementation.
sounds like sort-of what I need. But isn't this a functional contract identified here, something which deserves to be marked with an interface rather than an abstract base class?
Call it "Container" and we're getting at fortress-compatible terms again :D
What I don't like about this interface is that it presumes that an implementation will have available an enumeration of services that it is able to provide (and implying those will still be able somewhere at any later point in time), which is not the case.
IOW, I have available:
interface Container
{
Object get( String key, Object hint ) throws ServiceException;
boolean has( String key, Object hint );
}but nothing functionally equivalent to
Object[] getAll();
a few pointers would be nice :d
Hope the above helps.
well yeah, but as so often, answers are raising more questions :D
Let me know if you want to go ahead with the appliance approach and I'll refactor things to get in place an AbstractAppliance.
well, uhm, no, that was not the idea...that way I wouldn't learn anything about merlin! (which is the whole point for this exercise, since I already have ripped the plexus cli frontend and wrapped it around fortress, so that works already).
cheers!
- Leo
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
