Hi all, getting started on my e-mail backlog. Still have to finish reading this thread (on avalon-dev), but I saw some complaints about having to remember contracts that make no sense (they do make sense but that's not the point I want to make ;).
Well, you don't have to remember anything if you really don't want to. Below some sample code that allows you to not think about most contracts at all. This code itself adheres to avalon contracts (in 4.1 not the distant future) and it should run (though untested) in just about all containers. You could expand on this code a little more by keeping a list of services in the code, then getting each service from the servicemanager and throwing it into the context. You could also serialize all possible context values and put those in the configuration, retrieve all configuration entries and put them into the context using urns, etc. You could be forced to use some other logging setup (let us assume you want to use commons-logging), so you add some code into initialize() that checks if commons logging is available, then gets the commons-logger from the factory, puts it into a protected property, and wraps it as an o.a.a.f.l.Logger and stuffs it into m_logger. You could be forced to work within a container where ServiceManager and JNDI concepts are not merged, and you want them to be. So you create a JNDIAwareServiceManager and replace the DefaultServiceManager in the example code below with that one. etc etc. You can customize all you want. Now throw the finished class and assorted utility code into an lazy-avalon-framework-hack.jar, add it to the classpath of all your apps (ie drop into phoenix's lib/ directory). tadah: instant braindead lifecycle support. What you loose is the granularity, efficiency, clarity, etc. You're also loosing proper seperation of concerns (for example, what you want in the JNDI case is a modified container/service manager that is JNDI-aware), but it's mostly braindead simple to do. Just to show it is quite easy to circumvent most of the though contracts imposed on you by avalon and do things your way. cheers, - Leo Simons /** * For those that hate typing "implements" and that don't want the * lifecycle granularity, here's a simple (untested!) class that gets * rid of it all for you. There's a bit of error-checking left to be * done and some trivial services to implement, but otherwise this is * usable. */ public abstract class AbstractService implements LogEnabled, Contextualizable, Configurable, Servicable, Initializable, Startable, Disposable extends AbstractLogEnabled { // use these in your components to access relevant info protected Logger m_logger; protected Configuration m_configuration; protected Context m_context; protected ServiceManager m_serviceManager; // you could check these in a runner thread you create protected boolean m_initialized = false; protected boolean m_started = false; protected boolean m_stopped = false; protected boolean m_disposed = false; // lifecycle interfaces public void enableLogging( Logger logger ) { m_logger = logger; } public void configure( Configuration configuration ) throws ConfigurationException { m_configuration = configuration; } public void contextualize( Context context ) throws ContextException { m_context = context; } public void service( ServiceManager serviceManager ) throws ServiceException { m_serviceManager = serviceManager; } public void initialize() throws Exception { // throw 'services' based on other lifecycle steps into // services LoggingService ls = new DefaultLoggingService( m_logger ); ConfigurationService confs = new DefaultConfigurationService( m_configuration ); ContextService contexts = new DefaultContextService( m_context ); DefaultServiceManager sm = new DefaultServiceManager( m_serviceManager ); sm.put( ls.ROLE, ls ); sm.put( confs.ROLE, confs ); sm.put( contexts.ROLE, contexts ); // throw everything into the same context DefaultContext c = new DefaultContext( m_context ); c.put( "configuration", m_configuration ); c.put( "services", m_serviceManager ); c.put( "log", m_logger ); // call chosen convenience method initialize( sm ); initialize( c ); m_initialized = true; } public void start() throws Exception { m_started = true; } public void stop() throws Exception { m_stopped = true; } public void dispose() { m_disposed = true; } /** * has access to all lifecycle resources; you can override this * to access everything through a context mechanism */ public void initialize( Context c ) throws Exception { /* empty default implementation */ } /** * has access to all lifecycle resources; you can override this * to access everything through a service mechanism */ public void initialize( ServiceManager sm ) throws Exception { /* empty default implementation */ } } example component that doesn't care for thinking about its lifecycle: interface MyService { public final static ROLE = "MyService"; public String businessMethod(); } class MyServiceImpl extends AbstractService implements MyService { MyServiceB myServiceB; public MyComponent() {} public void initialize( Context c ) throws Exception { super(); // don't need to do this. already done // m_logger = (Logger)c.get( "logger" ); // don't need to do this. already done // m_serviceManager = (ServiceManager)c.get( "services" ); // want a different name! sm = (ServiceManager)c.get( "services" ); myServiceB = (MyServiceB)sm.lookup(MyServiceB.ROLE); } public String businessMethod() { return "what are you doing for christmas this year?"; } } -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>