geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <>
Subject [Geronimo Wiki] Update of "Geronimo Management API" by AaronMulder
Date Sun, 17 Jul 2005 00:21:54 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Geronimo Wiki" for change notification.

The following page has been changed by AaronMulder:

New page:
= Proposed Geronimo Management API =

So this comes from looking at JSR-77 and the code that the web console uses to interact with

Here's an example:
    ObjectName gbeanName = ...;
    DataSourceInfo info = new DataSourceInfo();
    try {
        info.setJndiName((String) kernel.getAttribute(gbeanName,
        info.setState((Integer) kernel.getAttribute(gbeanName,
        //check if user asked this connection to be tested
        if ((gbeanName.toString().equals(name)) && (check)) {
            try {
                Object cf = kernel.invoke(gbeanName, "$getResource");

At heart, this is non-portable code, because it interacts with the kernel, which is produced
by a call like
    kernel = KernelRegistry.getSingleKernel();

However, this is quite close to JSR-77 code.  Like kernel, the JSR-77 ManagementEJB is built
on calls like this:
public Object getAttribute(ObjectName name, String attribute) throws ...
public Object invoke(ObjectName name, String operationName,
                     Object[] params, String[] signature) throws ...

So the code above could be changed to use the ManagementEJB instead of kernel, and it would
be close to portable -- the missing link being that JSR-77 doesn't define {{{$getResource}}}
as a legitimate function of a `JCAManagedConnectionFactory` or `JDBCDataSource` (the closest
JSR-77 objects to the example above).

== So what's the problem? ==

Well, at heart, I don't like code that looks like this:
String value = (String) service.getAttribute("object", "attribute");
Something something = (Something) service.invoke("object", "method",
                       new Class[]{arg_types}, new String[]{args});

It's pretty hard to code to an API like that.  If you're determined to write a portable JSR-77
management tool, then you need to learn JSR-77 by heart, and too bad.  But otherwise, how
can you know what object names to use, what method names to use, what methods take what argument
types, what attributes are available, what to cast the results to, and so on?  Well, you can
look it up, but can you imagine writing more fragile code?  Code completion doesn't help,
the compiler and IDE can't catch your problems, etc.  If you're not familiar with the API,
there's nothing to do but read documentation or browse code.

== So what's the solution? ==

I'm imagining an API like this:
public interface Factory {
    public J2EEDomain[] getDomains();

public interface J2EEDomain {
    public J2EEServer[] getServers();

public interface J2EEServer {
    public J2EEDeployedObject[] getDeployedObjects();
    public JVM getJavaVMs();

// everything down to here mirrors JSR-77, everything below is non-JSR-77

    public CORBAContainer getCORBAContainer();
    public WebContainer getWebContainer();
    public EJBContainer getEJBContainer();
    public ThreadPool[] getThreadPools();

public interface WebContainer {
    public ThreadPool getAcceptThreadPool();
    public WebConnector[] getConnectors();
    public (String?) getJSPCompiler();

public interface WebConnector {
    public InetSocketAddress getListenAddress();


So this would be a mix of JSR-77 and not JSR-77.

On the JSR-77 side, it would include interfaces representing the JSR-77 components, and trying
to keep to similar  names and similarly named properties.  The types would change -- for example,
a JSR-77 J2EEDomain.getServers() method would return a list of ObjectNames for servers, and
in this API it would instead return a list of J2EEServer objects.  But the idea is that someone
familiar with JSR-77 programming would find it easy to get up to speed.

However, the API would also include non-JSR-77 components.  For example, there's no "WebContainer"
object in JSR-77, that would let you inspect and alter the listen port of Tomcat/Jetty, or
configure the number of threads used, or which compiler is used for JSPs, and so on.  The
reason I want to extend beyond JSR-77 is that I want to give direct API access to all the
things that something like the web console would need to do its job.

== How could this be implemented? ==

We have GBeans that expose all the necessary properties and functions already.  The only issue
is providing an implementation of this API that accesses them.  In many cases, we might supply
interfaces that the GBeans could implement.  Still, here might be some glue code between the
interfaces defined above and the actual GBeans.

The interfaces themselves probably wouldn't be as extensive as the GBeans.  For example, the
WebContainer interface would likely have the least-common-denominator configuration options
across Jetty and Tomcat (and maybe even less than that).  Still, a programmer always has access
to the raw GBeans to go deeper than the common API allows.  But this way you can use normal
OO code for the bulk of your management tasks, and only go to the paradigm that started this
page if you really need to.

Note that it is not my intention to start a "build the world" project to provide a totally
comprehensive management API for Geronimo.  Instead, I'd plan to start small, and grow it
as tools such as the web console expand into new areas.  "On demand" development of the management
API, I guess.

== How would this be integrated into Geronimo? ==

Well, at the source level, it would be a Geronimo module.  I don't think it would need much
presence in the server runtime -- mostly it's just an outside wrapper around the GBeans in
the server already.  So a tool would create a new management factory, get an instance connected
to the desired Geronimo server, and then start making calls against the API which would be
translated under the covers into calls against the Geronimo MEJB or kernel and GBeans.

It only makes sense for J2EE configurations of Geronimo.  That is, if you start the Geronimo
kernel and load it with nothing but a mail server GBean, you would not be able to use this
API to manage it.  That's OK though, you still have JMX/GBean access to manage totally arbitrary
Geronimo configurations -- this is just to help tools for the common J2EE configurations of

Still, some methods might return null or 0-length arrays if certain features are disabled.
 For example, if you remove the EJB container from your configuration, then you just wouldn't
be able to navigate to that part of the management API tree.

== What's the advantage?  Is it worth the trouble? ==

Well, back to the example at the top of the page.  I'd much rather see it like this (where
JDBCDataSource is an interface in the management API, based on the JDBCDataSource definition
in JSR-77):
    JDBCDataSource ds = ...;
    DataSourceInfo info = new DataSourceInfo();
    try {
        //check if user asked this connection to be tested
        if ((ds.getName().equals(name)) && (check)) {
            try {
                Connection con = ds.createConnection();

In fact, maybe the tool could just dispense with the `DataSourceInfo` altogether and just
use `JDBCDataSource` as its object model, depending on whether the `DataSourceInfo` class
has any UI-specific stuff in it.

In any case, note that there are no Strings in the code above.  It's all verified by the compiler,
you can inspect an unfamiliar interface via code completion and popup JavaDoc, etc.

I think something like this would make it much easier to develop management tools such as
the web console.  By using this API the tools would end up being specific to Geronimo, but
that's OK for our purposes -- we're trying to make Geronimo more usable not write a console
that can manage any J2EE server.  And if we're going to be reusing code across tools, I would
much rather it be an API layer like this, not copying and pasting kernel invocations with
string arguments and so on.

View raw message