My Photo

August 2007

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

September 06, 2006

Glassbox 2.0 automated troubleshooter Goes Beta

I'm pleased to announce that we just shipped the Beta release of the open source Glassbox 2.0 automated troubleshooter. Glassbox 2.0 is a major step forward in simplifying troubleshooting enterprise Java, just deploy it to your app server and it discovers your existing applications and automatically diagnoses problems. Glassbox provides a concise analysis of what’s wrong, focusing on relevant information like excessive queries, or parameters that cause failures.

Glassbox now offers an AJAX Web Client, improved analysis and an automated installer that makes it easy to monitor Java applications in either a standalone or clustered environment.  Under the hood, Glassbox continues to improve its monitoring and analysis to more easily pinpoint problems, Glassbox monitors selectively to allow very low overhead data capture, and we have been working with the AspectJ project to significantly reduce memory and startup time overhead. Glassbox is all open source with our CVS repository now hosted at SourceForge.

Please try it and let us know what you think.

screen shot

We’d enjoy showing you in person, too. We’re presenting Glassbox this fall at:

July 26, 2006

Stupid Log Tricks: Avoiding Nondelegation

I have been fairly quiet recently as we've been heads down working on an alpha release of Glassbox 2.0, with a focus on further ease of use in troubleshooting Java applications.  Most of the Glassbox functionality will be deployed as a portable Web application that is easy to install and run (except for the parts that have to integrate at a system level to monitor applications).

However, making a portable Web application is challenging because of nondelegating loaders and, you guessed it, logging. Of course, Jakarta Commons Logging is both widespread in its use and as Ceki Gülcü illustrated, there can be a number of problems with how it functions when you have a copy of it deployed to a shared location on a server AND inside a Web application with nondelegating classloaders. We have to support it because libraries we use like Spring use it. However, it turns out that there is a portable work-around: force your Web app's parent loader to load the classes in JCL before  you use logging:

    private void eagerlyLoadCommonsLogging() {

        String classes[] = {

                "org.apache.commons.logging.Log",

                "org.apache.commons.logging.LogFactory",

                "org.apache.commons.logging.impl.NoOpLog"

        };

        ClassLoader myLoader = getClass().getClassLoader();

       

        if (myLoader != null) {

            ClassLoader parent = myLoader.getParent();

            for (int i=0; i<classes.length; i++) {

                try {

                    Class.forName(classes[i], false, parent);

                } catch (ClassNotFoundException cne) {

                    // ok - not present in parent

                }

            }

        }

    }

Of course this exercise isn't limited to logging: any library that a portable Web application uses can have problems like this. But logging is crosscutting, widespread and often used. Some of the forces that make this exercise particularly challenging for us are:

  1. We don't want to require log4j, commons logging, or slf4j to be installed on the system class loader.
  2. We don't want to ship many different versions of the app, one per environment
  3. We don't want to modify the Web app during installation (e.g., to remove overlapping versions of the libraries)
  4. We don't want to require configuring our app manually (e.g., plugging in a different logging adaptor as slf4j does)
  5. We need to work with older versions of libraries (e.g., that eager loading code could find JCL 1.0!)
  6. We want to configure logging for shared classes that are typically on the system classpath (or in the equivalent of Tomcat's common loader). This last one requires us to set the context ClassLoader when initializing a log inside our library (good thing we manage logging with aspects!)

Of course, if you'd like to configure how logging works (e.g., redirecting to files, not leaving on overly verbose INFO logging for used components etc.) you still have to do that programmatically or ask users to configure their global log settings. Indeed, setting them programmatically has its own problems for shared libraries (the configuration would be global).

This is an area where reuse hurts. If you use an emerging logging implementation today you will probably not have any conflicts with existing code. In three years, you may find a lot of them. This is also the reason that tools like jarjar exist. Of course, this is typical for successful component models: they have to become popular before people take isolation and versioning seriously... remember when Java developers were glad that we didn't suffer from DLL hell?