You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/10/05 22:58:36 UTC

svn commit: r582387 - in /openejb/trunk/openejb3: assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/ assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/ assembly/openejb-tomcat/src/main/resources/ container/openejb-...

Author: dain
Date: Fri Oct  5 13:58:29 2007
New Revision: 582387

URL: http://svn.apache.org/viewvc?rev=582387&view=rev
Log:
Enable logging when dynamically embedded into Tomcat
Abstracted OpenEJB Logger so core log stream can be switched to java.util.logging, but it doesn't fully work yet

Added:
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/juli.properties
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStream.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLog.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStream.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStreamFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStream.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStreamFactory.java
Modified:
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatLoader.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Logger.java
    openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/OpenEJBListener.java

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatLoader.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatLoader.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatLoader.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatLoader.java Fri Oct  5 13:58:29 2007
@@ -18,6 +18,8 @@
 package org.apache.openejb.tomcat;
 
 import org.apache.openejb.OpenEJB;
+import org.apache.openejb.tomcat.installer.Paths;
+import org.apache.openejb.tomcat.installer.Installer;
 import org.apache.openejb.assembler.classic.WebAppBuilder;
 import org.apache.openejb.core.ServerFederation;
 import org.apache.openejb.core.ThreadContext;
@@ -48,6 +50,8 @@
     private EjbServer ejbServer;
 
     public void init(Properties props) throws Exception {
+        installConfigFiles();
+
         // Not thread safe
         if (OpenEJB.isInitialized()) {
             ejbServer = SystemInstance.get().getComponent(EjbServer.class);
@@ -87,6 +91,17 @@
         // Process all applications already started.  This deploys EJBs, PersistenceUnits
         // and modifies JNDI ENC references to OpenEJB managed objects such as EJBs.
         processRunningApplications(tomcatWebAppBuilder, standardServer);
+    }
+
+    private void installConfigFiles() {
+        String openejbWarDir = System.getProperty("openejb.war");
+        if (openejbWarDir == null) return;
+
+        Paths paths = new Paths(openejbWarDir);
+        if (paths.verify()) {
+            Installer installer = new Installer(paths);
+            installer.installConfigFiles();
+        }
     }
 
     private void processRunningApplications(TomcatWebAppBuilder tomcatWebAppBuilder, StandardServer standardServer) {

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java Fri Oct  5 13:58:29 2007
@@ -81,7 +81,11 @@
         return status;
     }
 
-    protected void install() {
+    public void tryDynamicInstall() {
+        invokeStaticNoArgMethod("org.apache.openejb.loader.OpenEJBListener", "tryDynamicInstall");        
+    }
+
+    public void installAll() {
         installListener();
 
         installJavaagent();
@@ -93,7 +97,7 @@
         }
     }
 
-    private void installListener() {
+    public void installListener() {
         if (listenerInstalled) {
 //            addInfo("OpenEJB Listener already installed");
             return;
@@ -160,7 +164,7 @@
         }
     }
 
-    private void installJavaagent() {
+    public void installJavaagent() {
         if (agentInstalled) {
 //            addInfo("OpenEJB Agent already installed");
             return;
@@ -243,7 +247,7 @@
         }
     }
 
-    private void installConfigFiles() {
+    public void installConfigFiles() {
         if (paths.getOpenEJBCoreJar() == null) {
             // the core jar contains the config files
             return;
@@ -281,7 +285,7 @@
                 newLoggingProps = openejbLoggingProps;
             } else {
                 String loggingPropsOriginal = readAll(loggingPropsFile);
-                if (!loggingPropsOriginal.contains("OpenEJB")) {
+                if (!loggingPropsOriginal.toLowerCase().contains("openejb")) {
                     // strip off license header
                     String[] strings = openejbLoggingProps.split("## --*", 3);
                     if (strings.length == 3) {

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java Fri Oct  5 13:58:29 2007
@@ -42,6 +42,7 @@
         this.servletConfig = servletConfig;
         paths = new Paths(servletConfig.getServletContext());
         installer = new Installer(paths);
+        installer.tryDynamicInstall();
     }
 
     protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
@@ -67,7 +68,7 @@
                 paths.setServerXmlFile(req.getParameter("serverXml"));
 
                 if (paths.verify()) {
-                    installer.install();
+                    installer.installAll();
                 }
             }
 

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java Fri Oct  5 13:58:29 2007
@@ -25,14 +25,28 @@
 import java.util.List;
 
 public class Paths {
-    private final ServletContext servletContext;
+    private final File openejbWarDir;
     private final List<String> errors = new ArrayList<String>();
     private File catalinaHomeDir;
     private File catalinaBaseDir;
     private File serverXmlFile;
 
     public Paths(ServletContext servletContext) {
-        this.servletContext = servletContext;
+        String path = servletContext.getRealPath("/");
+        if (path == null) {
+            openejbWarDir = null;
+        } else {
+            openejbWarDir = new File(path);
+        }
+    }
+
+    public Paths(String openejbWarDir) {
+        if (openejbWarDir == null) throw new NullPointerException("openejbWarDir is null");
+        this.openejbWarDir = new File(openejbWarDir);
+    }
+
+    public Paths(File openejbWarDir) {
+        this.openejbWarDir = openejbWarDir;
     }
 
     public File getCatalinaHomeDir() {
@@ -131,9 +145,9 @@
     }
 
     public File getOpenEJBLibDir() {
-        if (servletContext == null) return null;
+        if (openejbWarDir == null) return null;
 
-        return new File(servletContext.getRealPath("lib"));
+        return new File(openejbWarDir, "lib");
     }
 
     public File getOpenEJBLoaderJar() {
@@ -163,12 +177,15 @@
     }
 
     public File getUpdatedAnnotationApiJar() {
-        if (servletContext == null) return null;
+        if (openejbWarDir == null) return null;
 
-        return new File(servletContext.getRealPath("tomcat/annotations-api.jar"));
+        return new File(openejbWarDir, "tomcat/annotations-api.jar");
     }
 
     public boolean verify() {
+        if (openejbWarDir == null) {
+            addError("OpenEJB war is not unpacked");
+        }
         if (getCatalinaHomeDir() == null) {
             addError("Catalina home directory is not defined");
         }

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/juli.properties
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/juli.properties?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/juli.properties (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/juli.properties Fri Oct  5 13:58:29 2007
@@ -0,0 +1,27 @@
+############################################################
+# OpenEJB Handlers and Loggers
+############################################################
+
+OpenEJB.level = WARNING
+OpenEJB.server.level = INFO
+OpenEJB.startup.level = INFO
+OpenEJB.startup.config.level = INFO
+OpenEJB.hsql.level = INFO
+OpenEJB.handlers = 9OpenEJB.org.apache.juli.FileHandler
+CORBA-Adapter.hsql.level = ERROR
+CORBA-Adapter.handlers = 9OpenEJB.org.apache.juli.FileHandler
+Transaction.level = WARNING
+Transaction.handlers = 9Transaction.org.apache.juli.FileHandler
+org.apache.activemq.level = ERROR
+org.apache.activemq.handlers = OpenEJB.org.apache.juli.FileHandler
+org.apache.geronimo.level = ERROR
+org.apache.geronimo.handlers = 9OpenEJB.org.apache.juli.FileHandler
+openjpa.level = ERROR
+openjpa.handlers = 9OpenEJB.org.apache.juli.FileHandler
+
+9OpenEJB.org.apache.juli.FileHandler.level = FINE
+9OpenEJB.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+9OpenEJB.org.apache.juli.FileHandler.prefix = openejb.
+9Transaction.org.apache.juli.FileHandler.level = FINE
+9Transaction.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+9Transaction.org.apache.juli.FileHandler.prefix = transaction.

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStream.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStream.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStream.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStream.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,193 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+public class JuliLogStream implements LogStream {
+    protected Logger logger;
+
+    public JuliLogStream(LogCategory logCategory) {
+        logger = Logger.getLogger(logCategory.getName());
+    }
+
+    public boolean isFatalEnabled() {
+        return logger.isLoggable(Level.SEVERE);
+    }
+
+    public void fatal(String message) {
+        log(Level.SEVERE, message, null);
+    }
+
+    public void fatal(String message, Throwable t) {
+        log(Level.SEVERE, message, t);
+    }
+
+    public boolean isErrorEnabled() {
+        return logger.isLoggable(Level.SEVERE);
+    }
+
+    public void error(String message) {
+        log(Level.SEVERE, message, null);
+    }
+
+    public void error(String message, Throwable t) {
+        log(Level.SEVERE, message, t);
+    }
+
+    public boolean isWarnEnabled() {
+        return logger.isLoggable(Level.WARNING);
+    }
+
+    public void warn(String message) {
+        log(Level.WARNING, message, null);
+    }
+
+    public void warn(String message, Throwable t) {
+        log(Level.WARNING, message, t);
+    }
+
+    public boolean isInfoEnabled() {
+        return logger.isLoggable(Level.INFO);
+    }
+
+    public void info(String message) {
+        log(Level.INFO, message, null);
+    }
+
+    public void info(String message, Throwable t) {
+        log(Level.INFO, message, t);
+    }
+
+    public boolean isDebugEnabled() {
+        return logger.isLoggable(Level.FINE);
+    }
+
+    public void debug(String message) {
+        log(Level.FINE, message, null);
+    }
+
+    public void debug(String message, Throwable t) {
+        log(Level.FINE, message, t);
+    }
+
+    private void log(Level level, String message, Throwable t) {
+        if (logger.isLoggable(level)) {
+            LogRecord logRecord = new OpenEJBLogRecord(level, message);
+            if (t != null) logRecord.setThrown(t);
+            logger.log(logRecord);
+        }
+    }
+
+    private static class OpenEJBLogRecord extends LogRecord {
+        /**
+         * The name of the class that issued the logging call.
+         *
+         * @serial
+         */
+        private String sourceClassName;
+
+        /**
+         * The name of the method that issued the logging call.
+         *
+         * @serial
+         */
+        private String sourceMethodName;
+        
+        // If the source method and source class has been inited
+        private transient boolean sourceInited;
+
+        public OpenEJBLogRecord(Level level, String message) {
+            super(level, message);
+            sourceInited = false;
+        }
+
+        /**
+         * Gets the name of the class that issued the logging call.
+         *
+         * @return the name of the class that issued the logging call
+         */
+        public String getSourceClassName() {
+            initSource();
+            return sourceClassName;
+        }
+
+        /**
+         * Sets the name of the class that issued the logging call.
+         *
+         * @param sourceClassName
+         *            the name of the class that issued the logging call
+         */
+        public void setSourceClassName(String sourceClassName) {
+            sourceInited = true;
+            this.sourceClassName = sourceClassName;
+        }
+
+        /**
+         * Gets the name of the method that issued the logging call.
+         *
+         * @return the name of the method that issued the logging call
+         */
+        public String getSourceMethodName() {
+            initSource();
+            return sourceMethodName;
+        }
+
+        /**
+         * Sets the name of the method that issued the logging call.
+         *
+         * @param sourceMethodName the name of the method that issued the logging call
+         */
+        public void setSourceMethodName(String sourceMethodName) {
+            sourceInited = true;
+            this.sourceMethodName = sourceMethodName;
+        }
+
+        /**
+         *  Init the sourceClass and sourceMethod fields.
+         */
+        private void initSource() {
+            if (!sourceInited) {
+                // search back up the stack for the first use of the OpenEJB Logger
+                StackTraceElement[] elements = (new Throwable()).getStackTrace();
+                int i = 0;
+                String current = null;
+                for (; i < elements.length; i++) {
+                    current = elements[i].getClassName();
+                    if (current.equals(org.apache.openejb.util.Logger.class.getName())) {
+                        break;
+                    }
+                }
+
+                // Skip any internal OpenEJB Logger call
+                while (++i < elements.length && elements[i].getClassName().equals(current)) {
+                    // do nothing
+                }
+
+                // If we didn't run out of elements, set the source
+                if (i < elements.length) {
+                    this.sourceClassName = elements[i].getClassName();
+                    this.sourceMethodName = elements[i].getMethodName();
+                }
+                sourceInited = true;
+            }
+        }
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,183 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.openejb.loader.FileUtils;
+import org.apache.openejb.loader.SystemInstance;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+
+public class JuliLogStreamFactory implements LogStreamFactory {
+    private static final String LOGGING_PROPERTIES_FILE = "logging.properties";
+    private static final String DEFAULT_LOGGING_PROPERTIES_FILE = "juli.properties";
+    private static final String EMBEDDED_PROPERTIES_FILE = "embedded.juli.properties";
+
+    public LogStream createLogStream(LogCategory logCategory) {
+        return new JuliLogStream(logCategory);
+    }
+
+    public JuliLogStreamFactory() {
+        try {
+            String prop = System.getProperty("openejb.logger.external", "false");
+            boolean externalLogging = Boolean.parseBoolean(prop);
+            if (!externalLogging) {
+                configureInternal();
+            }
+        } catch (Exception e) {
+            // The fall back here is that if log4j.configuration system property is set, then that configuration file will be used.
+            e.printStackTrace();
+        }
+    }
+
+    private void configureInternal() throws IOException {
+        File confDir = SystemInstance.get().getBase().getDirectory("conf");
+        File loggingPropertiesFile = new File(confDir, LOGGING_PROPERTIES_FILE);
+        if (confDir.exists()) {
+            if (loggingPropertiesFile.exists()) {
+                FileInputStream in = null;
+                try {
+                    in = new FileInputStream(loggingPropertiesFile);
+                    LogManager.getLogManager().readConfiguration(in);
+                } finally {
+                    if (in != null) {
+                        try {
+                            in.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+            } else {
+                // install our logging.properties file into the conf dir
+                installLoggingPropertiesFile(loggingPropertiesFile);
+            }
+        } else {
+            // no conf directory, so we assume we are embedded
+            // configure log4j directly
+            configureEmbedded();
+        }
+    }
+
+    private void preprocessProperties(Properties properties) {
+        FileUtils base = SystemInstance.get().getBase();
+        File confDir = new File(base.getDirectory(), "conf");
+        File baseDir = base.getDirectory();
+        File userDir = new File("foo").getParentFile();
+
+        File[] paths = {confDir, baseDir, userDir};
+
+        List<File> missing = new ArrayList<File>();
+
+        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+            String key = (String) entry.getKey();
+            String value = (String) entry.getValue();
+
+            if (key.endsWith(".File")) {
+                boolean found = false;
+                for (int i = 0; i < paths.length && !found; i++) {
+                    File path = paths[i];
+                    File logfile = new File(path, value);
+                    if (logfile.getParentFile().exists()) {
+                        properties.setProperty(key, logfile.getAbsolutePath());
+                        found = true;
+                    }
+                }
+
+                if (!found) {
+                    File logfile = new File(paths[0], value);
+                    missing.add(logfile);
+                }
+            }
+        }
+
+        if (missing.size() > 0) {
+            java.util.logging.Logger logger = getFallabckLogger();
+
+            logger.severe("Logging may not operate as expected.  The directories for the following files do not exist so no file can be created.  See the list below.");
+            for (int i = 0; i < missing.size(); i++) {
+                File file = missing.get(i);
+                logger.severe("[" + i + "] " + file.getAbsolutePath());
+            }
+        }
+    }
+
+    private Logger getFallabckLogger() {
+        java.util.logging.Logger logger = Logger.getLogger("OpenEJB.logging");
+        ConsoleHandler consoleHandler = new ConsoleHandler();
+        consoleHandler.setFormatter(new SimpleFormatter());
+        logger.addHandler(consoleHandler);
+        return logger;
+    }
+
+    private void configureEmbedded() {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(EMBEDDED_PROPERTIES_FILE);
+        if (resource != null) PropertyConfigurator.configure(resource);
+        else System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING embedded.logging.properties FILE ");
+    }
+
+    private void installLoggingPropertiesFile(File loggingPropertiesFile) throws IOException {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(DEFAULT_LOGGING_PROPERTIES_FILE);
+        if (resource == null) {
+            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING logging.properties FILE ");
+            return;
+        }
+        InputStream in = resource.openStream();
+        in = new BufferedInputStream(in);
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        byte buf[] = new byte[4096];
+        for (int count = in.read(buf); count >= 0 ; count = in.read(buf)) {
+            bao.write(buf, 0, count);
+        }
+        byte[] byteArray = bao.toByteArray();
+        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
+
+        Properties props = new Properties();
+        props.load(bis);
+        preprocessProperties(props);
+        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(loggingPropertiesFile));
+        bout.write(byteArray);
+        PropertyConfigurator.configure(props);
+        try {
+            bout.close();
+        } catch (IOException e) {
+
+        }
+        try {
+            in.close();
+        } catch (IOException e) {
+
+        }
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLog.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLog.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLog.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLog.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,587 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.loader.FileUtils;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.SimpleLayout;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+
+import java.util.ResourceBundle;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.text.MessageFormat;
+import java.io.IOException;
+import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.net.URL;
+
+public class Log4jLog {
+
+    protected org.apache.log4j.Logger _logger = null;
+    private LogCategory category;
+    private String baseName;
+
+    private static final String SUFFIX = ".Messages";
+
+    private static final String OPENEJB = "org.apache.openejb";
+    /**
+     * Computes the parent of a resource name. E.g. if we pass in a key of
+     * a.b.c, it returns the value a.b
+     */
+    private static final Computable<String, String> heirarchyResolver = new Computable<String, String>() {
+        public String compute(String key) throws InterruptedException {
+            int index = key.lastIndexOf(".");
+            String parent = key.substring(0, index);
+            if (parent.contains(OPENEJB))
+                return parent;
+            return null;
+        }
+    };
+    /**
+     * Simply returns the ResourceBundle for a given baseName
+     */
+    private static final Computable<String, ResourceBundle> bundleResolver = new Computable<String, ResourceBundle>() {
+        public ResourceBundle compute(String baseName)
+                throws InterruptedException {
+            try {
+                return ResourceBundle.getBundle(baseName + SUFFIX);
+            } catch (MissingResourceException e) {
+                return null;
+            }
+        }
+    };
+    /**
+     * Builds a Logger object and returns it
+     */
+    private static final Computable<Object[], Log4jLog> loggerResolver = new Computable<Object[], Log4jLog>() {
+        public Log4jLog compute(Object[] args) throws InterruptedException {
+
+            Log4jLog logger = new Log4jLog();
+            logger.category = (LogCategory) args[0];
+            logger._logger = org.apache.log4j.Logger.getLogger(logger.category.getName());
+            logger.baseName = (String) args[1];
+            return logger;
+
+        }
+    };
+    /**
+     * Creates a MessageFormat object for a message and returns it
+     */
+    private static final Computable<String, MessageFormat> messageFormatResolver = new Computable<String, MessageFormat>() {
+        public MessageFormat compute(String message)
+                throws InterruptedException {
+
+            return new MessageFormat(message);
+
+        }
+    };
+    /**
+     * Cache of parent-child relationships between resource names
+     */
+    private static final Computable<String, String> heirarchyCache = new Memoizer<String, String>(heirarchyResolver);
+    /**
+     * Cache of ResourceBundles
+     */
+    private static final Computable<String, ResourceBundle> bundleCache = new Memoizer<String, ResourceBundle>(bundleResolver);
+    /**
+     * Cache of Loggers
+     */
+    private static final Computable<Object[], Log4jLog> loggerCache = new Memoizer<Object[], Log4jLog>(loggerResolver);
+    /**
+     * Cache of MessageFormats
+     */
+    private static final Computable<String, MessageFormat> messageFormatCache = new Memoizer<String, MessageFormat>(messageFormatResolver);
+
+    private static final String LOGGING_PROPERTIES_FILE = "logging.properties";
+    private static final String EMBEDDED_PROPERTIES_FILE = "embedded.logging.properties";
+
+    static {
+        try {
+            String prop = System.getProperty("openejb.logger.external", "false");
+            boolean externalLogging = Boolean.parseBoolean(prop);
+            if (!externalLogging)
+                configureInternal();
+        } catch (Exception e) {
+            // The fall back here is that if log4j.configuration system property is set, then that configuration file will be used.
+            e.printStackTrace();
+        }
+    }
+
+    private static void configureInternal() throws IOException {
+
+        System.setProperty("openjpa.Log", "log4j");
+        SystemInstance system = SystemInstance.get();
+        FileUtils base = system.getBase();
+        File confDir = base.getDirectory("conf");
+        File loggingPropertiesFile = new File(confDir, LOGGING_PROPERTIES_FILE);
+        if (confDir.exists()) {
+            if (loggingPropertiesFile.exists()) {
+                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(loggingPropertiesFile));
+                Properties props = new Properties();
+                props.load(bis);
+                preprocessProperties(props);
+                PropertyConfigurator.configure(props);
+                try {
+                    bis.close();
+                } catch (IOException e) {
+
+                }
+            } else {
+                installLoggingPropertiesFile(loggingPropertiesFile);
+            }
+        } else {
+            configureEmbedded();
+        }
+    }
+
+    private static void preprocessProperties(Properties properties) {
+        FileUtils base = SystemInstance.get().getBase();
+        File confDir = new File(base.getDirectory(), "conf");
+        File baseDir = base.getDirectory();
+        File userDir = new File("foo").getParentFile();
+
+        File[] paths = {confDir, baseDir, userDir};
+
+        List missing = new ArrayList();
+
+        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+            String key = (String) entry.getKey();
+            String value = (String) entry.getValue();
+
+
+            if (key.endsWith(".File")) {
+
+                boolean found = false;
+                for (int i = 0; i < paths.length && !found; i++) {
+                    File path = paths[i];
+                    File logfile = new File(path, value);
+                    if (logfile.getParentFile().exists()) {
+                        properties.setProperty(key, logfile.getAbsolutePath());
+                        found = true;
+                    }
+                }
+
+                if (!found) {
+                    File logfile = new File(paths[0], value);
+                    missing.add(logfile);
+                }
+            }
+        }
+
+        if (missing.size() > 0) {
+            org.apache.log4j.Logger logger = getFallabckLogger();
+
+            logger.error("Logging may not operate as expected.  The directories for the following files do not exist so no file can be created.  See the list below.");
+            for (int i = 0; i < missing.size(); i++) {
+                File file = (File) missing.get(i);
+                logger.error("[" + i + "] " + file.getAbsolutePath());
+            }
+        }
+    }
+
+    private static org.apache.log4j.Logger getFallabckLogger() {
+        org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("OpenEJB.logging");
+
+        SimpleLayout simpleLayout = new SimpleLayout();
+        ConsoleAppender newAppender = new ConsoleAppender(simpleLayout);
+        logger.addAppender(newAppender);
+        return logger;
+    }
+
+    private static void configureEmbedded() {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(EMBEDDED_PROPERTIES_FILE);
+        if (resource != null)
+            PropertyConfigurator.configure(resource);
+        else
+            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING embedded.logging.properties FILE ");
+    }
+
+    private static void installLoggingPropertiesFile(File loggingPropertiesFile) throws IOException {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(LOGGING_PROPERTIES_FILE);
+        if (resource == null) {
+            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING logging.properties FILE ");
+            return;
+        }
+        InputStream in = resource.openStream();
+        in = new BufferedInputStream(in);
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        byte buf[] = new byte[4096];
+        int i = in.read(buf);
+        while (i != -1) {
+            bao.write(buf);
+            i = in.read(buf);
+        }
+        byte[] byteArray = bao.toByteArray();
+        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
+
+        Properties props = new Properties();
+        props.load(bis);
+        preprocessProperties(props);
+        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(loggingPropertiesFile));
+        bout.write(byteArray);
+        PropertyConfigurator.configure(props);
+        try {
+            bout.close();
+        } catch (IOException e) {
+
+        }
+        try {
+            in.close();
+        } catch (IOException e) {
+
+        }
+
+    }
+
+    /**
+     * Given a key and a baseName, this method computes a message for a key. if
+     * the key is not found in this ResourceBundle for this baseName, then it
+     * recursively looks up its parent to find the message for a key. If no
+     * message is found for a key, the key is returned as is and is logged by
+     * the logger.
+     */
+    private String getMessage(String key, String baseName) {
+        try {
+
+            ResourceBundle bundle = bundleCache.compute(baseName);
+            if (bundle != null) {
+                String message = null;
+                try {
+                    message = bundle.getString(key);
+                    return message;
+                } catch (MissingResourceException e) {
+                    String parentName = heirarchyCache.compute(baseName);
+                    if (parentName == null)
+                        return key;
+                    else
+                        return getMessage(key, parentName);
+                }
+
+            } else {
+                String parentName = heirarchyCache.compute(baseName);
+                if (parentName == null)
+                    return key;
+                else
+                    return getMessage(key, parentName);
+
+            }
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        return key;
+    }
+
+
+    /**
+     * Finds a Logger from the cache and returns it. If not found in cache then builds a Logger and returns it.
+     *
+     * @param category - The category of the logger
+     * @param baseName - The baseName for the ResourceBundle
+     * @return Logger
+     */
+    public static Log4jLog getInstance(LogCategory category, String baseName) {
+        try {
+            Log4jLog logger = loggerCache
+                    .compute(new Object[]{category, baseName});
+            return logger;
+        } catch (InterruptedException e) {
+            /*
+                * Don't return null here. Just create a new Logger and set it up.
+                * It will not be stored in the cache, but a later lookup for the
+                * same Logger would probably end up in the cache
+                */
+            Log4jLog logger = new Log4jLog();
+            logger.category = category;
+            logger._logger = org.apache.log4j.Logger.getLogger(category.getName());
+            logger.baseName = baseName;
+            return logger;
+        }
+    }
+
+    public static Log4jLog getInstance(LogCategory category, Class clazz) {
+        return getInstance(category, packageName(clazz));
+    }
+
+    private static String packageName(Class clazz) {
+        String name = clazz.getName();
+        return name.substring(0, name.lastIndexOf("."));
+    }
+
+    public Log4jLog getLogger(String moduleId) {
+        return getInstance(this.category, this.baseName);
+
+    }
+
+    /**
+     * Formats a given message
+     *
+     * @param message
+     * @param args
+     * @return the formatted message
+     */
+    private String formatMessage(String message, Object... args) {
+        try {
+            MessageFormat mf = messageFormatCache.compute(message);
+            String msg = mf.format(args);
+            return msg;
+        } catch (InterruptedException e) {
+            return "Error in formatting message " + message;
+        }
+
+    }
+
+    private Log4jLog() {
+    }
+
+    public boolean isDebugEnabled() {
+        return _logger.isDebugEnabled();
+    }
+
+    public boolean isErrorEnabled() {
+        return _logger.isEnabledFor(Level.ERROR);
+    }
+
+    public boolean isFatalEnabled() {
+        return _logger.isEnabledFor(Level.FATAL);
+    }
+
+    public boolean isInfoEnabled() {
+        return _logger.isInfoEnabled();
+    }
+
+    public boolean isWarningEnabled() {
+        return _logger.isEnabledFor(Level.WARN);
+    }
+
+    /**
+     * If this level is enabled, then it finds a message for the given key  and logs it
+     *
+     * @param message - This could be a plain message or a key in Messages.properties
+     * @return the formatted i18n message
+     */
+    public String debug(String message) {
+
+        if (isDebugEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.debug(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String debug(String message, Object... args) {
+
+        if (isDebugEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.debug(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String debug(String message, Throwable t) {
+
+        if (isDebugEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.debug(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String debug(String message, Throwable t, Object... args) {
+
+        if (isDebugEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.debug(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String error(String message) {
+
+        if (isErrorEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.error(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String error(String message, Object... args) {
+
+        if (isErrorEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.error(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String error(String message, Throwable t) {
+
+        if (isErrorEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.error(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String error(String message, Throwable t, Object... args) {
+
+        if (isErrorEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.error(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String fatal(String message) {
+        if (isFatalEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.fatal(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String fatal(String message, Object... args) {
+        if (isFatalEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.fatal(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String fatal(String message, Throwable t) {
+        if (isFatalEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.fatal(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String fatal(String message, Throwable t, Object... args) {
+        if (isFatalEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.fatal(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String info(String message) {
+        if (isInfoEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.info(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String info(String message, Object... args) {
+        if (isInfoEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.info(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String info(String message, Throwable t) {
+        if (isInfoEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.info(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String info(String message, Throwable t, Object... args) {
+        if (isInfoEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.info(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String warning(String message) {
+        if (isWarningEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.warn(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String warning(String message, Object... args) {
+        if (isWarningEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.warn(msg);
+            return msg;
+        }
+        return message;
+    }
+
+    public String warning(String message, Throwable t) {
+        if (isWarningEnabled()) {
+            String msg = getMessage(message, baseName);
+            _logger.warn(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+    public String warning(String message, Throwable t, Object... args) {
+        if (isWarningEnabled()) {
+            String msg = getMessage(message, baseName);
+            msg = formatMessage(msg, args);
+            _logger.warn(msg, t);
+            return msg;
+        }
+        return message;
+    }
+
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStream.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStream.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStream.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStream.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,88 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import org.apache.log4j.Level;
+
+public class Log4jLogStream implements LogStream {
+    protected org.apache.log4j.Logger logger;
+
+    public Log4jLogStream(LogCategory logCategory) {
+        logger = org.apache.log4j.Logger.getLogger(logCategory.getName());
+    }
+
+    public boolean isFatalEnabled() {
+        return logger.isEnabledFor(Level.FATAL);
+    }
+
+    public void fatal(String message) {
+        logger.fatal(message);
+    }
+
+    public void fatal(String message, Throwable t) {
+        logger.fatal(message, t);
+    }
+
+    public boolean isErrorEnabled() {
+        return logger.isEnabledFor(Level.ERROR);
+    }
+
+    public void error(String message) {
+        logger.error(message);
+    }
+
+    public void error(String message, Throwable t) {
+        logger.error(message, t);
+    }
+
+    public boolean isWarnEnabled() {
+        return logger.isEnabledFor(Level.WARN);
+    }
+
+    public void warn(String message) {
+        logger.warn(message);
+    }
+
+    public void warn(String message, Throwable t) {
+        logger.warn(message, t);
+    }
+
+    public boolean isInfoEnabled() {
+        return logger.isInfoEnabled();
+    }
+
+    public void info(String message) {
+        logger.info(message);
+    }
+
+    public void info(String message, Throwable t) {
+        logger.info(message, t);
+    }
+
+    public boolean isDebugEnabled() {
+        return logger.isDebugEnabled();
+    }
+
+    public void debug(String message) {
+        logger.debug(message);
+    }
+
+    public void debug(String message, Throwable t) {
+        logger.debug(message, t);
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStreamFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStreamFactory.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStreamFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Log4jLogStreamFactory.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,184 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.loader.FileUtils;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.SimpleLayout;
+import org.apache.log4j.ConsoleAppender;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.net.URL;
+
+public class Log4jLogStreamFactory implements LogStreamFactory {
+    private static final String LOGGING_PROPERTIES_FILE = "logging.properties";
+    private static final String EMBEDDED_PROPERTIES_FILE = "embedded.logging.properties";
+
+    public LogStream createLogStream(LogCategory logCategory) {
+        return new Log4jLogStream(logCategory);
+    }
+
+    public Log4jLogStreamFactory() {
+        try {
+            String prop = System.getProperty("openejb.logger.external", "false");
+            boolean externalLogging = Boolean.parseBoolean(prop);
+            if (!externalLogging)
+                configureInternal();
+        } catch (Exception e) {
+            // The fall back here is that if log4j.configuration system property is set, then that configuration file will be used.
+            e.printStackTrace();
+        }
+    }
+
+    private void configureInternal() throws IOException {
+        // OpenJPA should use Log4j also
+        System.setProperty("openjpa.Log", "log4j");
+
+        File confDir = SystemInstance.get().getBase().getDirectory("conf");
+        File loggingPropertiesFile = new File(confDir, LOGGING_PROPERTIES_FILE);
+        if (confDir.exists()) {
+            if (loggingPropertiesFile.exists()) {
+                // load logging.properties file
+                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(loggingPropertiesFile));
+                Properties props = new Properties();
+                props.load(bis);
+                preprocessProperties(props);
+                PropertyConfigurator.configure(props);
+                try {
+                    bis.close();
+                } catch (IOException e) {
+
+                }
+            } else {
+                // install our logging.properties file into the conf dir
+                installLoggingPropertiesFile(loggingPropertiesFile);
+            }
+        } else {
+            // no conf directory, so we assume we are embedded
+            // configure log4j directly
+            configureEmbedded();
+        }
+    }
+
+    private void preprocessProperties(Properties properties) {
+        FileUtils base = SystemInstance.get().getBase();
+        File confDir = new File(base.getDirectory(), "conf");
+        File baseDir = base.getDirectory();
+        File userDir = new File("foo").getParentFile();
+
+        File[] paths = {confDir, baseDir, userDir};
+
+        List<File> missing = new ArrayList<File>();
+
+        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+            String key = (String) entry.getKey();
+            String value = (String) entry.getValue();
+
+            if (key.endsWith(".File")) {
+                boolean found = false;
+                for (int i = 0; i < paths.length && !found; i++) {
+                    File path = paths[i];
+                    File logfile = new File(path, value);
+                    if (logfile.getParentFile().exists()) {
+                        properties.setProperty(key, logfile.getAbsolutePath());
+                        found = true;
+                    }
+                }
+
+                if (!found) {
+                    File logfile = new File(paths[0], value);
+                    missing.add(logfile);
+                }
+            }
+        }
+
+        if (missing.size() > 0) {
+            org.apache.log4j.Logger logger = getFallabckLogger();
+
+            logger.error("Logging may not operate as expected.  The directories for the following files do not exist so no file can be created.  See the list below.");
+            for (int i = 0; i < missing.size(); i++) {
+                File file = missing.get(i);
+                logger.error("[" + i + "] " + file.getAbsolutePath());
+            }
+        }
+    }
+
+    private org.apache.log4j.Logger getFallabckLogger() {
+        org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("OpenEJB.logging");
+
+        SimpleLayout simpleLayout = new SimpleLayout();
+        ConsoleAppender newAppender = new ConsoleAppender(simpleLayout);
+        logger.addAppender(newAppender);
+        return logger;
+    }
+
+    private void configureEmbedded() {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(EMBEDDED_PROPERTIES_FILE);
+        if (resource != null)
+            PropertyConfigurator.configure(resource);
+        else
+            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING embedded.logging.properties FILE ");
+    }
+
+    private void installLoggingPropertiesFile(File loggingPropertiesFile) throws IOException {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource(LOGGING_PROPERTIES_FILE);
+        if (resource == null) {
+            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING logging.properties FILE ");
+            return;
+        }
+        InputStream in = resource.openStream();
+        in = new BufferedInputStream(in);
+        ByteArrayOutputStream bao = new ByteArrayOutputStream();
+        byte buf[] = new byte[4096];
+        for (int count = in.read(buf); count >= 0 ; count = in.read(buf)) {
+            bao.write(buf, 0, count);
+        }
+        byte[] byteArray = bao.toByteArray();
+        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
+
+        Properties props = new Properties();
+        props.load(bis);
+        preprocessProperties(props);
+        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(loggingPropertiesFile));
+        bout.write(byteArray);
+        PropertyConfigurator.configure(props);
+        try {
+            bout.close();
+        } catch (IOException e) {
+
+        }
+        try {
+            in.close();
+        } catch (IOException e) {
+
+        }
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogFactory.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogFactory.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,22 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+public interface LogFactory {
+    Logger getInstance(LogCategory category, String baseName);
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStream.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStream.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStream.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStream.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,41 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+public interface LogStream {
+
+    boolean isFatalEnabled();
+    void fatal(String message);
+    void fatal(String message, Throwable t);
+
+    boolean isErrorEnabled();
+    void error(String message);
+    void error(String message, Throwable t);
+
+    boolean isWarnEnabled();
+    void warn(String message);
+    void warn(String message, Throwable t);
+
+    boolean isInfoEnabled();
+    void info(String message);
+    void info(String message, Throwable t);
+
+    boolean isDebugEnabled();
+    void debug(String message);
+    void debug(String message, Throwable t);
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStreamFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStreamFactory.java?rev=582387&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStreamFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/LogStreamFactory.java Fri Oct  5 13:58:29 2007
@@ -0,0 +1,22 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+public interface LogStreamFactory {
+    LogStream createLogStream(LogCategory logCategory);
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Logger.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Logger.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Logger.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Logger.java Fri Oct  5 13:58:29 2007
@@ -16,40 +16,50 @@
  */
 package org.apache.openejb.util;
 
-import org.apache.log4j.Level;
-import org.apache.log4j.PropertyConfigurator;
-import org.apache.log4j.ConsoleAppender;
-import org.apache.log4j.SimpleLayout;
-import org.apache.openejb.loader.FileUtils;
-import org.apache.openejb.loader.SystemInstance;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
 import java.text.MessageFormat;
-import java.util.Map;
 import java.util.MissingResourceException;
-import java.util.Properties;
 import java.util.ResourceBundle;
-import java.util.List;
-import java.util.ArrayList;
 
 public class Logger {
+    private static final String SUFFIX = ".Messages";
+    private static final String OPENEJB = "org.apache.openejb";
+    private static LogStreamFactory logStreamFactory;
 
-    protected org.apache.log4j.Logger _logger = null;
-    private LogCategory category;
-    private String baseName;
+    static {
+        String factoryName = System.getProperty("openejb.log.factory");
+        Class<?> factoryClass = null;
+        if (factoryName != null) {
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+            if (classLoader != null) {
+                try {
+                    factoryClass = classLoader.loadClass(factoryName);
+                } catch (ClassNotFoundException e) {
+                }
+            }
 
-    private static final String SUFFIX = ".Messages";
+            if (factoryClass != null) {
+                try {
+                    factoryClass = Class.forName(factoryName);
+                } catch (ClassNotFoundException e) {
+                }
+            }
+        }
+
+        LogStreamFactory factory = null;
+        if (factoryClass != null) {
+            try {
+                factory = (LogStreamFactory) factoryClass.newInstance();
+            } catch (Exception e) {
+            }
+        }
+
+        if (factory == null) {
+            factory = new Log4jLogStreamFactory();
+        }
+
+        logStreamFactory = factory;
+    }
 
-    private static final String OPENEJB = "org.apache.openejb";
     /**
      * Computes the parent of a resource name. E.g. if we pass in a key of
      * a.b.c, it returns the value a.b
@@ -63,12 +73,12 @@
             return null;
         }
     };
+
     /**
      * Simply returns the ResourceBundle for a given baseName
      */
     private static final Computable<String, ResourceBundle> bundleResolver = new Computable<String, ResourceBundle>() {
-        public ResourceBundle compute(String baseName)
-                throws InterruptedException {
+        public ResourceBundle compute(String baseName) throws InterruptedException {
             try {
                 return ResourceBundle.getBundle(baseName + SUFFIX);
             } catch (MissingResourceException e) {
@@ -76,228 +86,48 @@
             }
         }
     };
+
     /**
      * Builds a Logger object and returns it
      */
     private static final Computable<Object[], Logger> loggerResolver = new Computable<Object[], Logger>() {
         public Logger compute(Object[] args) throws InterruptedException {
-
-            Logger logger = new Logger();
-            logger.category = (LogCategory) args[0];
-            logger._logger = org.apache.log4j.Logger.getLogger(logger.category.getName());
-            logger.baseName = (String) args[1];
+            LogCategory category = (LogCategory) args[0];
+            LogStream logStream = logStreamFactory.createLogStream(category);
+            String baseName = (String) args[1];
+            Logger logger = new Logger(category, logStream, baseName);
             return logger;
-
         }
     };
+
     /**
      * Creates a MessageFormat object for a message and returns it
      */
     private static final Computable<String, MessageFormat> messageFormatResolver = new Computable<String, MessageFormat>() {
-        public MessageFormat compute(String message)
-                throws InterruptedException {
-
+        public MessageFormat compute(String message) throws InterruptedException {
             return new MessageFormat(message);
-
         }
     };
+
     /**
      * Cache of parent-child relationships between resource names
      */
-    private static final Computable<String, String> heirarchyCache = new Memoizer<String, String>(
-            heirarchyResolver);
+    private static final Computable<String, String> heirarchyCache = new Memoizer<String, String>(heirarchyResolver);
+
     /**
      * Cache of ResourceBundles
      */
-    private static final Computable<String, ResourceBundle> bundleCache = new Memoizer<String, ResourceBundle>(
-            bundleResolver);
+    private static final Computable<String, ResourceBundle> bundleCache = new Memoizer<String, ResourceBundle>(bundleResolver);
+
     /**
      * Cache of Loggers
      */
-    private static final Computable<Object[], Logger> loggerCache = new Memoizer<Object[], Logger>(
-            loggerResolver);
-    /**
-     * Cache of MessageFormats
-     */
-    private static final Computable<String, MessageFormat> messageFormatCache = new Memoizer<String, MessageFormat>(
-            messageFormatResolver);
-
-    private static final String LOGGING_PROPERTIES_FILE = "logging.properties";
-    private static final String EMBEDDED_PROPERTIES_FILE = "embedded.logging.properties";
-
-    static {
-        try {
-            String prop = System.getProperty("openejb.logger.external", "false");
-            boolean externalLogging = Boolean.parseBoolean(prop);
-            if (!externalLogging)
-                configureInternal();
-        } catch (Exception e) {
-            // The fall back here is that if log4j.configuration system property is set, then that configuration file will be used.
-            e.printStackTrace();
-        }
-    }
-
-    private static void configureInternal() throws IOException {
-
-        System.setProperty("openjpa.Log", "log4j");
-        SystemInstance system = SystemInstance.get();
-        FileUtils base = system.getBase();
-        File confDir = base.getDirectory("conf");
-        File loggingPropertiesFile = new File(confDir, LOGGING_PROPERTIES_FILE);
-        if (confDir.exists()) {
-            if (loggingPropertiesFile.exists()) {
-                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(loggingPropertiesFile));
-                Properties props = new Properties();
-                props.load(bis);
-                preprocessProperties(props);
-                PropertyConfigurator.configure(props);
-                try {
-                    bis.close();
-                } catch (IOException e) {
-
-                }
-            } else {
-                installLoggingPropertiesFile(loggingPropertiesFile);
-            }
-        } else {
-            configureEmbedded();
-        }
-    }
-
-    private static void preprocessProperties(Properties properties) {
-        FileUtils base = SystemInstance.get().getBase();
-        File confDir = new File(base.getDirectory(), "conf");
-        File baseDir = base.getDirectory();
-        File userDir = new File("foo").getParentFile();
-
-        File[] paths = {confDir, baseDir, userDir};
-
-        List missing = new ArrayList();
-
-        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
-            String key = (String) entry.getKey();
-            String value = (String) entry.getValue();
-
-
-            if (key.endsWith(".File")) {
-
-                boolean found = false;
-                for (int i = 0; i < paths.length && !found; i++) {
-                    File path = paths[i];
-                    File logfile = new File(path, value);
-                    if (logfile.getParentFile().exists()) {
-                        properties.setProperty(key, logfile.getAbsolutePath());
-                        found = true;
-                    }
-                }
-
-                if (!found) {
-                    File logfile = new File(paths[0], value);
-                    missing.add(logfile);
-                }
-            }
-        }
-
-        if (missing.size() > 0) {
-            org.apache.log4j.Logger logger = getFallbackLogger();
-
-            logger.error("Logging may not operate as expected.  The directories for the following files do not exist so no file can be created.  See the list below.");
-            for (int i = 0; i < missing.size(); i++) {
-                File file = (File) missing.get(i);
-                logger.error("[" + i + "] " + file.getAbsolutePath());
-            }
-        }
-    }
-
-    private static org.apache.log4j.Logger getFallbackLogger() {
-        org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger("OpenEJB.logging");
-
-        SimpleLayout simpleLayout = new SimpleLayout();
-        ConsoleAppender newAppender = new ConsoleAppender(simpleLayout);
-        logger.addAppender(newAppender);
-        return logger;
-    }
-
-    private static void configureEmbedded() {
-        URL resource = Thread.currentThread().getContextClassLoader().getResource(EMBEDDED_PROPERTIES_FILE);
-        if (resource != null)
-            PropertyConfigurator.configure(resource);
-        else
-            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING embedded.logging.properties FILE ");
-    }
-
-    private static void installLoggingPropertiesFile(File loggingPropertiesFile) throws IOException {
-        URL resource = Thread.currentThread().getContextClassLoader().getResource(LOGGING_PROPERTIES_FILE);
-        if (resource == null) {
-            System.out.println("FATAL ERROR WHILE CONFIGURING LOGGING!!!. MISSING logging.properties FILE ");
-            return;
-        }
-        InputStream in = resource.openStream();
-        in = new BufferedInputStream(in);
-        ByteArrayOutputStream bao = new ByteArrayOutputStream();
-        for(int i = in.read(); i!=-1;i=in.read()){
-        	bao.write(i);
-        }
-        byte[] byteArray = bao.toByteArray();
-        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
-
-        Properties props = new Properties();
-        props.load(bis);
-        preprocessProperties(props);
-        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(loggingPropertiesFile));
-        bout.write(byteArray);
-        PropertyConfigurator.configure(props);
-        try {
-            bout.close();
-        } catch (IOException e) {
-
-        }
-        try {
-            in.close();
-        } catch (IOException e) {
-
-        }
-
-    }
+    private static final Computable<Object[], Logger> loggerCache = new Memoizer<Object[], Logger>(loggerResolver);
 
     /**
-     * Given a key and a baseName, this method computes a message for a key. if
-     * the key is not found in this ResourceBundle for this baseName, then it
-     * recursively looks up its parent to find the message for a key. If no
-     * message is found for a key, the key is returned as is and is logged by
-     * the logger.
+     * Cache of MessageFormats
      */
-    private String getMessage(String key, String baseName) {
-        try {
-
-            ResourceBundle bundle = bundleCache.compute(baseName);
-            if (bundle != null) {
-                String message = null;
-                try {
-                    message = bundle.getString(key);
-                    return message;
-                } catch (MissingResourceException e) {
-                    String parentName = heirarchyCache.compute(baseName);
-                    if (parentName == null)
-                        return key;
-                    else
-                        return getMessage(key, parentName);
-                }
-
-            } else {
-                String parentName = heirarchyCache.compute(baseName);
-                if (parentName == null)
-                    return key;
-                else
-                    return getMessage(key, parentName);
-
-            }
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        return key;
-    }
-
+    private static final Computable<String, MessageFormat> messageFormatCache = new Memoizer<String, MessageFormat>(messageFormatResolver);
 
     /**
      * Finds a Logger from the cache and returns it. If not found in cache then builds a Logger and returns it.
@@ -308,23 +138,28 @@
      */
     public static Logger getInstance(LogCategory category, String baseName) {
         try {
-            Logger logger = loggerCache
-                    .compute(new Object[]{category, baseName});
+            Logger logger = loggerCache.compute(new Object[]{category, baseName});
             return logger;
         } catch (InterruptedException e) {
-            /*
-                * Don't return null here. Just create a new Logger and set it up.
-                * It will not be stored in the cache, but a later lookup for the
-                * same Logger would probably end up in the cache
-                */
-            Logger logger = new Logger();
-            logger.category = category;
-            logger._logger = org.apache.log4j.Logger.getLogger(category.getName());
-            logger.baseName = baseName;
+            // Don't return null here. Just create a new Logger and set it up.
+            // It will not be stored in the cache, but a later lookup for the
+            // same Logger would probably end up in the cache
+            LogStream logStream = logStreamFactory.createLogStream(category);
+            Logger logger = new Logger(category, logStream, baseName);
             return logger;
         }
     }
 
+    private final LogCategory category;
+    private final LogStream logStream;
+    private final String baseName;
+
+    public Logger(LogCategory category, LogStream logStream, String baseName) {
+        this.category = category;
+        this.logStream = logStream;
+        this.baseName = baseName;
+    }
+
     public static Logger getInstance(LogCategory category, Class clazz) {
         return getInstance(category, packageName(clazz));
     }
@@ -336,7 +171,6 @@
 
     public Logger getChildLogger(String child) {
         return Logger.getInstance(this.category.createChild(child), this.baseName);
-
     }
 
     /**
@@ -357,27 +191,24 @@
 
     }
 
-    private Logger() {
-    }
-
     public boolean isDebugEnabled() {
-        return _logger.isDebugEnabled();
+        return logStream.isDebugEnabled();
     }
 
     public boolean isErrorEnabled() {
-        return _logger.isEnabledFor(Level.ERROR);
+        return logStream.isErrorEnabled();
     }
 
     public boolean isFatalEnabled() {
-        return _logger.isEnabledFor(Level.FATAL);
+        return logStream.isFatalEnabled();
     }
 
     public boolean isInfoEnabled() {
-        return _logger.isInfoEnabled();
+        return logStream.isInfoEnabled();
     }
 
     public boolean isWarningEnabled() {
-        return _logger.isEnabledFor(Level.WARN);
+        return logStream.isWarnEnabled();
     }
 
     /**
@@ -390,7 +221,7 @@
 
         if (isDebugEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.debug(msg);
+            logStream.debug(msg);
             return msg;
         }
         return message;
@@ -401,7 +232,7 @@
         if (isDebugEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.debug(msg);
+            logStream.debug(msg);
             return msg;
         }
         return message;
@@ -411,7 +242,7 @@
 
         if (isDebugEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.debug(msg, t);
+            logStream.debug(msg, t);
             return msg;
         }
         return message;
@@ -422,7 +253,7 @@
         if (isDebugEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.debug(msg, t);
+            logStream.debug(msg, t);
             return msg;
         }
         return message;
@@ -432,7 +263,7 @@
 
         if (isErrorEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.error(msg);
+            logStream.error(msg);
             return msg;
         }
         return message;
@@ -443,7 +274,7 @@
         if (isErrorEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.error(msg);
+            logStream.error(msg);
             return msg;
         }
         return message;
@@ -453,7 +284,7 @@
 
         if (isErrorEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.error(msg, t);
+            logStream.error(msg, t);
             return msg;
         }
         return message;
@@ -464,7 +295,7 @@
         if (isErrorEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.error(msg, t);
+            logStream.error(msg, t);
             return msg;
         }
         return message;
@@ -473,7 +304,7 @@
     public String fatal(String message) {
         if (isFatalEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.fatal(msg);
+            logStream.fatal(msg);
             return msg;
         }
         return message;
@@ -483,7 +314,7 @@
         if (isFatalEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.fatal(msg);
+            logStream.fatal(msg);
             return msg;
         }
         return message;
@@ -492,7 +323,7 @@
     public String fatal(String message, Throwable t) {
         if (isFatalEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.fatal(msg, t);
+            logStream.fatal(msg, t);
             return msg;
         }
         return message;
@@ -502,7 +333,7 @@
         if (isFatalEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.fatal(msg, t);
+            logStream.fatal(msg, t);
             return msg;
         }
         return message;
@@ -511,7 +342,7 @@
     public String info(String message) {
         if (isInfoEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.info(msg);
+            logStream.info(msg);
             return msg;
         }
         return message;
@@ -521,7 +352,7 @@
         if (isInfoEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.info(msg);
+            logStream.info(msg);
             return msg;
         }
         return message;
@@ -530,7 +361,7 @@
     public String info(String message, Throwable t) {
         if (isInfoEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.info(msg, t);
+            logStream.info(msg, t);
             return msg;
         }
         return message;
@@ -540,7 +371,7 @@
         if (isInfoEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.info(msg, t);
+            logStream.info(msg, t);
             return msg;
         }
         return message;
@@ -549,7 +380,7 @@
     public String warning(String message) {
         if (isWarningEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.warn(msg);
+            logStream.warn(msg);
             return msg;
         }
         return message;
@@ -559,7 +390,7 @@
         if (isWarningEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.warn(msg);
+            logStream.warn(msg);
             return msg;
         }
         return message;
@@ -568,7 +399,7 @@
     public String warning(String message, Throwable t) {
         if (isWarningEnabled()) {
             String msg = getMessage(message, baseName);
-            _logger.warn(msg, t);
+            logStream.warn(msg, t);
             return msg;
         }
         return message;
@@ -578,10 +409,48 @@
         if (isWarningEnabled()) {
             String msg = getMessage(message, baseName);
             msg = formatMessage(msg, args);
-            _logger.warn(msg, t);
+            logStream.warn(msg, t);
             return msg;
         }
         return message;
+    }
+
+    /**
+     * Given a key and a baseName, this method computes a message for a key. if
+     * the key is not found in this ResourceBundle for this baseName, then it
+     * recursively looks up its parent to find the message for a key. If no
+     * message is found for a key, the key is returned as is and is logged by
+     * the logger.
+     */
+    private String getMessage(String key, String baseName) {
+        try {
+
+            ResourceBundle bundle = bundleCache.compute(baseName);
+            if (bundle != null) {
+                String message = null;
+                try {
+                    message = bundle.getString(key);
+                    return message;
+                } catch (MissingResourceException e) {
+                    String parentName = heirarchyCache.compute(baseName);
+                    if (parentName == null)
+                        return key;
+                    else
+                        return getMessage(key, parentName);
+                }
+
+            } else {
+                String parentName = heirarchyCache.compute(baseName);
+                if (parentName == null)
+                    return key;
+                else
+                    return getMessage(key, parentName);
+
+            }
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        return key;
     }
 
 }

Modified: openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/OpenEJBListener.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/OpenEJBListener.java?rev=582387&r1=582386&r2=582387&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/OpenEJBListener.java (original)
+++ openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/OpenEJBListener.java Fri Oct  5 13:58:29 2007
@@ -33,10 +33,19 @@
     static private Boolean listenerInstalled;
 
     public static boolean isListenerInstalled() {
-        new OpenEJBListener().tryDynamicInstall();
         return listenerInstalled;
     }
 
+    public static void tryDynamicInstall() {
+        // if installed hasn't been set yet, we can assume that
+        // this is the first entry into this code, meaning
+        // the listener was NOT installed into Tomcat
+        if (listenerInstalled == null) listenerInstalled = false;
+
+        StandardServer server = (StandardServer) ServerFactory.getServer();
+        new OpenEJBListener().init(server);
+    }
+
     public OpenEJBListener() {
     }
 
@@ -60,6 +69,7 @@
             properties.setProperty("openejb.loader", "tomcat-system");
 
             File webappDir = findOpenEjbWar(standardServer);
+            System.setProperty("openejb.war", webappDir.getAbsolutePath());            
             File libDir = new File(webappDir, "lib");
             String catalinaHome = System.getProperty("catalina.home");
             properties.setProperty("openejb.home", catalinaHome);
@@ -143,15 +153,5 @@
             }
         }
         return null;
-    }
-
-    private void tryDynamicInstall() {
-        // if installed hasn't been set yet, we can assume that
-        // this is the first entry into this code, meaning
-        // the listener was NOT installed into Tomcat
-        if (listenerInstalled == null) listenerInstalled = false;
-
-        StandardServer server = (StandardServer) ServerFactory.getServer();
-        this.init(server);
     }
 }