Introduction
Avalon is a component framework, as EJB.
There are lot of discussion about pro and cons
of each framework.
The following document tries to show some
way using both frameworks, benefiting
from their strength.
Today there is quite some common sense about designing EJB.
You should design EJB in a coarse grained fashion.
Speaking in other words EJBs are designed to implement
use cases, or business artifact.
In contrast Avalon components could be designed a bit
more fine-grained. Avalon components will be the toolbox
reused across EJB projects.
Moreover Avalon components are not to supposed to live
in an EJB container only. Having the design pattern
"Separation of Concern" in mind as Avalon component
framework was designed, Avalon components may
live in any J2EE container, or in some other container
environment.
Using Avalon components will give you the chance
to reuse Avalon components in some other J2EE container, e.g.
Servlet Container, or in some stand alone application.
As Avalon components are not tied to an EJB container you are
able to do JUnit testing of the Avalon components independently
from the EJBs.
Thus it might be possible to reuse the JUnit test in a JMX
environment to provide some continuse testing.
Avalon EJB Frame
Avalon components should not be too visible I
would suggest to use some delegate approach. As it was
suggested by Peter and the AvalonEJBFrame.
As side note this approach is not new and it was already
used in the ExaliburTestCase which ties together the
JUnit framwork and the Avalon framework.
Configuring the Avalon EJB Frame
Using the Avalon framework usually requires some
kind of configuration.
Next I describe the configuration options of
an Avalon EJB Frame.
The following sections presents some EJB conformant
configuration options.
Avalon EJB Frame Configuration
I suggest that an Avalon EJB Frame Configuration
should configure following Avalon components.
Logger -
Although Avalon has some Logkit framework,
I would suggest using the more general Logger, giving
the option to use some different Logging mechanism as
JdkLogger, Log4J, and some ApplicationServer proprietary
logging mechanism.
Context -
As each Avalon component might be Contextualizable
I would suggest that defining an optional context.
Moreover an Avalon context to JNDI context bridge might
give you the chance to access JNDI objects from inside
the Avalon components.
Role -
Components -
Avalon Components -
Using ejb-jar.xml
You might consider defining the avalon configuration in the ejb-jar.xml.
The ejb-jar.xml describes the characteristics of an EJB.
Thus it makes sense to describe the Avalon components used by the
EJB component inside of the EJB deployment descriptor.
... the ejb-jar.xml snippet ...
...
<env-entry>
<env-entry-name>AvalonEJBFrame</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value><![CDATA[
<configuration>
<logger>
<!-- use the log4j logger -->
<log4logger/>
<!-- use the jdk14logger
<jdk14logger/>
-->
<!-- optionally you may use the logkit logger
see ExcaliburTestCase, and avalon.excalibur.logger
<logkit>
<factories>...</factories>
<targets>...</targets>
<categories>...</categories>
</logkit>
-->
</logger>
<context>
<jndi-context
provider.url="t3://myhost:7001"
initial-factory="weblogic.jndi.WLSContextFactory"/>
<entry name="x" value="y"/>
<entry name="z" class="a.b.c.D"/>
</context>
<components>
<component role="A.ROLE" class="x.y.z.AImpl1"/>
</components>
<configuration>
]]>
<env-entry-value>
</env-entry>
....
|
Accessing this configuration:
Context ctx = new InitialContext();
String xconfString = ctx.lookup( "java:comp/env/AvalonEJBFrame" );
Configuration xconf = ... // build configuration from xconfString
|
 |
The prefix java:comp/env is part of the EJB spec and should be
portable across the different application servers.
|
JNDI Lookup of Configuration
Lookup the avalon configuration from the JNDI stored as DOM, or plain xml.
Using this configuration option you must define only a place holder
in the ejb-jar.xml defining where the configuration is has to be looked up
in the JNDI tree.
... the ejb-jar.xml snippet ...
...
<env-entry>
<env-entry-name>AvalonEJBFrame</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>avalon/xconf/a/b/c/EJB1.xconf</env-entry-value>
</env-entry>
....
|
Accessing this configuration:
Context ctx = new InitialContext();
String xconfStringJndi = ctx.lookup( "java:comp/env/AvalonEJBFrame" );
String xconfString = ctx.lookup( xconfStringJndi );
Configuration xconf = ... // build configuration from xconfString
|
 |
The above example assumes that the Avalon configuration is
stored as an XML string, not as an XML DOM.
|
Binding the JNDI name avalon/xconf/a/b/c/EJB1.xconf is
not done by the EJB itself but by some separate process.
You might consider setting it up some application server startup
process, or by some other JNDI setup process.
JNDI Lookup of AvalonEJBFrame
You might consider another option, looking up an
Avalon EJB Frame object from the JNDI.
... the ejb-jar.xml snippet ...
<env-entry>
<env-entry-name>AvalonEJBFrame</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>avalon/xconf/a/b/c/AvalonEJBFrame</env-entry-value>
</env-entry>
....
|
Using the Avalon EJB Frame
Using in a StatelessSessionBean
The AvalonEJBFrame object is shared by all StatelessSessionBean instances.
This means that all avalon components should be ThreadSafe.
Using in a StatefulSessionBean
Each StatefulSessionBean instance has its own AvalonEJBFrame.
Using in a EntityBean
Each EntityBean instance has its own AvalonEJBFrame.