Conversation regarding JBoss MC and Nuts container between A
ajoo Dec 9, 2005 3:15 PMHello Everybody. I recently had some conversations about what makes JBoss mc different than all other light weight containers, which also includes the Yan/Nuts container I developed.
Since Adrian prefers to use this forum rather than email, I hereby try to move relevant conversations over here. The following are the relevant conversations so far. I'll post my answers to Adrian after this.
"Ben" wrote:
Hi Adrian.
After several days of reading the code, I think I kinda get some sense
about the idea of JBoss container being a "state machine".
This fine-grained explicit state transition is quite an interesting
idea that is not found in Pico, Spring and Yan. Though I'm not sure
about the reason why this is needed.
"Adrian" wrote:
It's needed because that's what the JBoss Microcontainer/MicroKernel
is for. We control the state (or will do when it is finished)
and lifecycle of "complicated" systems.
Some things that the traditional IOC container doesn't usually
get involved in:
* classloader dependency
* state of the bean (e.g. serialize/deserialize across server restarts
or redeploys or pull state from the cluster)
* metadata injection/overrides.
* valve (holding requests while a bean is internally reconfigured)
* on-demand - don't even if create the service if it is not used
* cross model dependecy, e.g. dependency on something bound into jndi
These all require a well defined state machine to control properly
"Ben" wrote:
About the question I asked, I did not mean a singleton aspect that's
weaved into the bytecode and affects every relevant "new" statement in
the source code. I meant the bean deployment mode, like the
"singleton/prototype" thing in Spring.
But I guess I found the answer myself. Correct me if I'm wrong, in
JBoss, once a BeanMetaData is installed, a ControllerContext object is
created and registered in the Controller. This ControllerContext is
pretty much a singleton bean in Spring because at any time I can only
have one "target" per ControllerContext. Yes, the state machine can
uninstall and re-install, which can create a second instance, but this
just doesn't look like designed for "prototype bean" deployment.
This observation more or less leads to the conclusion that JBoss has
no "prototype bean" deployment mode. All beans are deployed as
"singleton". I wouldn't call this a restriction because I don't know
the problem domain that JBoss container is targeted. But it is a
difference between JBoss and other containers like Spring, Pico and
Yan.
"Adrian" wrote:
There is a<beanfactory>for "prototype bean"
"Ben" wrote:
About "modulng". honestly I don't quite follow the "AOP moduling"
thing you described. I'm actually more concerned about the
maintainability of xml config files. JBoss container requires every
bean to be registered into the global namespace of the Controller,
without a support for local/inner beans. This may make it a challenge
when the number of beans scales up. A moduling system should be able
to alleviate this problem and organize beans in a more modular way.
"Adrian" wrote:
JBossMC works at the "kernel" level.
Support for deployments and modularation has a lot more to it than
"xml files".
On your particular case, I haven't done anonymous beans
or "beans as values".<bean> <property><bean/><property>
etc.
This leads to no loss of functionality,
it just pollutes the configuration space (as you say)
This has been waiting on a more generic concept called
"use case" xml.<bean <property><xx:blah xmlns:xx="..."></property>
where you can "inject" objects created using other xml schemes
into the state machine. Which might be plain objects or they
might simpler versions of the xml for a specific use case.
e.g.<ds:xa xmlns:ds="http://www.jboss.org/schema/datasource"> <connection-url>....</connection-url> <:ds>
will map to the uglier<bean class="org.jboss.resource.jdbc.DataSource"> <property name="transactionManager"><inject bean="TransactionManager"/></property> <property name="connectionURL">....</proeprty> </bean>
without revealing all the implementation details to the end user
or even the implementing class "org.jboss.resource.jdbc.DataSource"!
My classic example is,<cl:urlclassloader url="whatever"/>
which is really the more long winded<bean class="java.net.URLClassLoader"> <constructor> <parameter> <array elementClass="java.net.URL"> <value>whatever</value> </array> </parameter> </constructor> </bean>
"Ben" wrote:
For the "xml scripting" thing, I totally agree with you that logic
should be put into Java as much as possible. In fact, if you look at
Yan's API, almost everything Nuts provides are doable directly with
Java API.
Same as JBoss, Nuts is also a thin wrapper and xml facade on top of
Yan. The reason why Nuts' syntax looks to you like a scripting
language is because that level of flexibility is already provided by
Yan's core API. All Nuts needs to do is just some xml syntax that can
use this flexibility provided by the Java API. This API employs the
"monad" computation model that's proved very powerful by those
functional programming folks. An API with flexibility as a scripting
language isn't a bad thing to have anyway, IMHO.
For example, the following piece of Java code needs to create new
instances of A1 and A2 every time createA() is requested. (Assuming
createA is a bean deployed as prototype):A createA(){ A a1 = new A1(); A a2 = new A2(); return new A3(a1, a2, a1, a2); }
Simple as this, it is hard to mimic in Pico or Spring, But it is
doable with Yan API:final Component a1 = Components.ctor(A1.class); final Component a2 = Components.ctor(A2.class); final Component a3 = Components.ctor(A3.class); return a1.bind(new Binder(){ public Creator bind(Object o1){ final Component arg1 = Components.value(o1); return a2.bind(new Binder(){ public Creator bind(Object o2){ final Component arg2 = Components.value(o2); a3.withArguments(new Component[]{ arg1, arg2, arg1, arg2 }); } }); } });
Of course, the nested anonymous class is ugly and ugly, which is why
sometimes xml syntax is preferrable over Java code:<sequence id="createA" singleton="false"> <bean var="a1" class="A1"/> <bean var="a2" class="A2"/> <bean class="A3" args="$a1,$a2,$a1,$a2"/> </sequence>
Nuts XML simply translates the tags into the above Java code without
handling the logic itself. It provides a nice "do-notation" syntax
that can be found in Haskell monad. Not as concise as Haskell, but
much better than Java.
"Adrian" wrote:
It is very difficult (if not impossible) to do "generic scripting"
and still have a state machine. The script will do nasty things
that the state machine doesn't know about.
Instead, these requirements to run scripts should be turned
into declaritive state transition events (mostly likely in the
form of decorators, rather than introducing new states in into the MC).
But how do you even know the class "A1" is deployed yet?
or
* how do you know to "rerun the script" when A1 is redeployed?
* maybe you only deploy A1 and initialize its subsystem/support
when somebody references A1 ("on-demand").