Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 83003 invoked from network); 25 Apr 2003 10:43:32 -0000 Received: from exchange.sun.com (192.18.33.10) by daedalus.apache.org with SMTP; 25 Apr 2003 10:43:32 -0000 Received: (qmail 13108 invoked by uid 97); 25 Apr 2003 10:45:27 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@nagoya.betaversion.org Received: (qmail 13101 invoked from network); 25 Apr 2003 10:45:27 -0000 Received: from daedalus.apache.org (HELO apache.org) (208.185.179.12) by nagoya.betaversion.org with SMTP; 25 Apr 2003 10:45:27 -0000 Received: (qmail 82760 invoked by uid 500); 25 Apr 2003 10:43:29 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 82747 invoked from network); 25 Apr 2003 10:43:28 -0000 Received: from main.gmane.org (80.91.224.249) by daedalus.apache.org with SMTP; 25 Apr 2003 10:43:28 -0000 Received: from list by main.gmane.org with local (Exim 3.35 #1 (Debian)) id 1990ew-0003fU-00 for ; Fri, 25 Apr 2003 12:42:26 +0200 X-Injected-Via-Gmane: http://gmane.org/ To: commons-dev@jakarta.apache.org Received: from news by main.gmane.org with local (Exim 3.35 #1 (Debian)) id 1990ev-0003fJ-00 for ; Fri, 25 Apr 2003 12:42:25 +0200 From: Leo Simons Subject: Re: Query: Hosting Avalon Components Date: Fri, 25 Apr 2003 12:43:24 +0200 Lines: 184 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@main.gmane.org User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: en-us, en In-Reply-To: Sender: news X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N up-front summary: first answers to technical questions, next post will be about "management". "avalon components" are interface/class pairs distinguished (practically speaking) from normal beans by a dependency on avalon-framework.jar. They are perfectly usuable outside of an avalon container as long as you do a little work and include avalon-framework.jar or do some extra work while building the component. Henri Yandell wrote: > What's an Avalon component? Something that implements the Initable, > Startable stuff? [I'm sketchy on Avalon] sort-of. In practical terms, what we call "avalon component" /usually/ has an interface, implementation of that interface, and additionally implementation of some of those "lifecycle interfaces" inside avalon-framework.jar. avalon-framework.jar sorta is to Component-Oriented Programming what java.lang (+ commons-lang ;) is to OOP. example: public interface MyService { String ROLE = MyService.class.getName(); Object doStuff(); } public class MyClass implements MyService, Servicable // Serviceable lives in avalon-framework.jar { private MyPrereqService prereqService = null; public void service( ServiceManager sm ) { this.prereqService = (MyPrereqService)sm.lookup( MyPrereqService.ROLE ); } protected MyPrereqService getPrereqService() { return this.prereqService; } public void doStuff() { getPrereqService().doSomething( /* ... */ ); /* ... */ } } > I can see that it doesn't make any sense to host an Avalon component in > Jakarta Commons if it's only useful in an Avalon container, this is almost never the case for a properly built component, though you often need to do some extra work. COP-By-Wrapping --------------- This is the most common usecase today. You have a utility bean (say, commons-digester) which you want to be able to transparently use in an avalon-based environment. Last time we talked about this here, I think I wrote a full sample wrapper around commons-digester. Many avalon devs code all of their commercial/home-grown projects this way. Roll-Your-Own-Container ----------------------- A minimal use-once "avalon container" is equivalent to a few lines of code in your calling class. Code example which allows you to use MyClass just by importing avalon-framework.jar: // ... somewhere DefaultServiceManager sm = new DefaultServiceManager(); // lives in avalon-framework MyPrereqService prereq = new MyPrereqServiceImpl(); sm.put( MyprereqService.ROLE, prereq ); MyService my = new MyClass(); ContainerUtil.service( my, sm ); // lives in avalon-framework // .... somewhere, cont'd COP-Is-Optional --------------- What we are seeing more and more is components which are /optionally/ avalonized. For example, you can put the above code snippet into the getPrereqService to have a component "be its own container", in fact it is a completely reusable bean again: public class MyClass implements MyService, Servicable // Serviceable lives in avalon-framework.jar { private MyPrereqService prereqService = null; public void doStuff() { getPrereqService().doSomething( /* ... */ ); /* ... */ } public void service( ServiceManager sm ) { this.prereqService = (MyPrereqService)sm.lookup( MyPrereqService.ROLE ); } protected MyPrereqService getPrereqService() { if( this.prereqService != null ) return this.prereqService; else this.startup(); } private void startup() { DefaultServiceManager sm = new DefaultServiceManager(); // lives in avalon-framework MyPrereqService prereq = new MyPrereqServiceImpl(); sm.put( MyprereqService.ROLE, prereq ); MyService my = new MyClass(); ContainerUtil.service( this, sm ); // lives in avalon-framework } } the only difference a client will see between a component coded like this and a regular bean is the need to put avalon-framework.jar on the classpath: // ... somewhere MyService myService = new MyClass(); myService.doStuff(); // Just Works(tm) // ... somewhere, contd the cost for this flexibility is a compile-time dependency on the MyPrereqServiceImpl inside MyClass, as opposed to merely on the work interface, but the coupling can be isolated, or seperated out into a utility jar. Concrete Example ---------------- Berin's question popped up in relation to components which are used inside cocoon and other projects which live in avalon-excalibur cvs atm. http://cvs.apache.org/viewcvs.cgi/avalon-excalibur/store/src/java/org/apache/excalibur/store/impl/MemoryStore.java?rev=1.6&content-type=text/vnd.viewcvs-markup says // .... public class MemoryStore extends AbstractLogEnabled implements Store, ThreadSafe { // ... in order to use this component in your application, you can do Store myStore = new MemoryStore(); ContainerUtil.enableLogging( myStore, new ConsoleLogger() ); // ConsoleLogger lives in avalon-framework; other options // provided there include NullLogger, Log4jLogger, // LogkitLogger, and jdk1.4 logging. A wrapper around // commons-logging is planned for framework 4.1.5 and has // been previously discussed here myStore.hold( key, value ); myStore.get( key ); IOW, the difference is an additional library to include and a single line of code. Where Code Should Live ---------------------- > unless there > are lots of Jakarta Projects out there which are customers of the Avalon > project. Then it makes some sense, though it could also be Avalon Commons > [or better name] as a subproject of Avalon? > > If there are Jakarta projects out there who want to share Avalon > components, I don't see why they can't be in Jakarta Commons. I'll tackle this part of the issue (which is more complex) in a seperate post. cheers, - Leo --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org