shale-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From craig...@apache.org
Subject svn commit: r473638 - in /shale/framework/trunk/shale-dialog-basic: ./ src/main/java/org/apache/shale/dialog/basic/ src/main/resources/META-INF/
Date Sat, 11 Nov 2006 04:16:19 GMT
Author: craigmcc
Date: Fri Nov 10 20:16:19 2006
New Revision: 473638

URL: http://svn.apache.org/viewvc?view=rev&rev=473638
Log:
Partial fix for cleaning up static resources at application shutdown
(SHALE-274) for the basic implementation.  This took several changes:
* We needed a servlet context listener that can call
  PropertyUtils.clearDescriptors() and LogFactory.release().
* In order to get this without requiring the user to configure a listener
  manually in web.xml, create a dummy "tag library" inside the JAR
  (META-INF/taglib.tld) that serves to declare the listener.
* Since we now have an application startup/shutdown instance, migrate
  the dialog configuration parsing from "first use" in BasicDialogManager
  to "application startup time" as well.

With these changes, we have successfully cleaned up issues that caused
the Commons BeanUtils and Commons Logging jars to remain locked after
undeployment on a Windows platform.  However, there is still something
that prevents shale-dialog-basic-xxx.jar itself from being deleted -- and
this means there will be a memory leak over multiple application deploys
and undeploys.  This needs to be investigated and fixed before this issue
can be considered as "dealt with" for the basic implementation.

The Commons SCXML implementation is going to need the same sort of changes
(can be tagged against SHALE-274 as well), but it's likely to have its own
set of different issues about leaving the shale-dialog-scxml-xxx.jar file
locked.


Added:
    shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
  (with props)
    shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld   (with
props)
Modified:
    shale/framework/trunk/shale-dialog-basic/   (props changed)
    shale/framework/trunk/shale-dialog-basic/pom.xml
    shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicDialogManager.java

Propchange: shale/framework/trunk/shale-dialog-basic/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Nov 10 20:16:19 2006
@@ -0,0 +1 @@
+target

Modified: shale/framework/trunk/shale-dialog-basic/pom.xml
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-basic/pom.xml?view=diff&rev=473638&r1=473637&r2=473638
==============================================================================
--- shale/framework/trunk/shale-dialog-basic/pom.xml (original)
+++ shale/framework/trunk/shale-dialog-basic/pom.xml Fri Nov 10 20:16:19 2006
@@ -40,6 +40,23 @@
         </dependency>
 
         <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jsp-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>

Modified: shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicDialogManager.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicDialogManager.java?view=diff&rev=473638&r1=473637&r2=473638
==============================================================================
--- shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicDialogManager.java
(original)
+++ shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicDialogManager.java
Fri Nov 10 20:16:19 2006
@@ -19,7 +19,6 @@
 
 import java.io.Serializable;
 import java.net.URL;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -31,7 +30,6 @@
 import org.apache.shale.dialog.Constants;
 import org.apache.shale.dialog.DialogContext;
 import org.apache.shale.dialog.DialogContextManager;
-import org.apache.shale.dialog.basic.config.ConfigurationParser;
 import org.apache.shale.dialog.basic.model.Dialog;
 
 /**
@@ -54,22 +52,6 @@
 
 
     /**
-     * <p>The default configuration resource we will process (if present),
-     * even if it is not explicitly configured.</p>
-     */
-    private static final String DEFAULT_CONFIGURATION_RESOURCE =
-            "/WEB-INF/dialog-config.xml";
-
-
-    /**
-     * <p>Resource name for dialog configuration resource(s) embedded in
-     * JAR files inside the application.</p>
-     */
-    private static final String EMBEDDED_CONFIGURATION_RESOURCE =
-            "META-INF/dialog-config.xml";
-
-
-    /**
      * <p><code>Map</code> of {@link Dialog} configurations, keyed
      * by dialog name.  This value is lazily instantiated, and is also
      * transient and may need to be regenerated.</p>
@@ -88,7 +70,7 @@
      * <p>Map containing all currently active {@link DialogContext} instances for
      * the current user.</p>
      */
-    private final HashMap map = new HashMap();
+    private final Map map = new HashMap();
 
 
     /**
@@ -158,8 +140,7 @@
 
     /**
      * <p>Return a <code>Map</code> of the configured {@link Dialog}s,
keyed
-     * by logical dialog name.  Upon the first request, the configuration
-     * resources will be processed.</p>
+     * by logical dialog name.</p>
      *
      * @param context FacesContext for the current request
      * @return The map of available dialogs, keyed by dialog logical name
@@ -174,110 +155,6 @@
         // Return the previously configured application scope instance (if any)
         this.dialogs = (Map)
           context.getExternalContext().getApplicationMap().get(Globals.DIALOGS);
-        if (this.dialogs != null) {
-            return this.dialogs;
-        }
-
-        // Set up to parse our specified configuration resources and cache the results
-        boolean didDefault = false;
-        ConfigurationParser parser = new ConfigurationParser();
-        parser.setDialogs(new HashMap());
-
-        // Parse implicitly specified resources embedded in JAR files
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        if (loader == null) {
-            loader = this.getClass().getClassLoader();
-        }
-        try {
-            Enumeration resources = loader.getResources(EMBEDDED_CONFIGURATION_RESOURCE);
-            while (resources.hasMoreElements()) {
-                URL resource = (URL) resources.nextElement();
-                if (log().isDebugEnabled()) {
-                    log().debug("Parsing configuration resource '"
-                            + resource + "'");
-                }
-                parser.setResource(resource);
-                parser.parse();
-            }
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new FacesException(e);
-        }
-
-        // Parse explicitly specified resources
-        String resources =
-          context.getExternalContext().getInitParameter(Globals.CONFIGURATION);
-        if (resources == null) {
-            resources = "";
-            // Because we process the default resource even if it is not
-            // explicitly listed, we don't want to warn here
-        }
-        int comma = 0;
-        String path = null;
-        try {
-            while (true) {
-                comma = resources.indexOf(",");
-                if (comma < 0) {
-                    path = resources.trim();
-                    resources = "";
-                } else {
-                    path = resources.substring(0, comma).trim();
-                    resources = resources.substring(comma + 1);
-                }
-                if (path.length() < 1) {
-                    break;
-                }
-                URL resource = context.getExternalContext().getResource(path);
-                if (log().isDebugEnabled()) {
-                    log().debug("Parsing configuration resource '"
-                            + resource + "'");
-                }
-                parser.setResource(resource);
-                parser.parse();
-                if (DEFAULT_CONFIGURATION_RESOURCE.equals(path)) {
-                    didDefault = true;
-                }
-            }
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new FacesException(e);
-        }
-
-        // Parse the default configuration resource if it exists and has not
-        // already been parsed
-        if (!didDefault) {
-            try {
-                URL resource =
-                  context.getExternalContext().getResource(DEFAULT_CONFIGURATION_RESOURCE);
-                if (resource != null) {
-                    if (log().isDebugEnabled()) {
-                        log().debug("Parsing configuration resource '"
-                                + resource + "'");
-                    }
-                    parser.setResource(resource);
-                    parser.parse();
-                }
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new FacesException(e);
-            }
-        }
-
-        // Cache the results both locally and in application scope
-        this.dialogs = parser.getDialogs();
-
-        if (this.dialogs.size() == 0) {
-            if (log().isWarnEnabled()) {
-                log.warn("No dialog configuration information present.  No default configuration
found at: " +
-                        DEFAULT_CONFIGURATION_RESOURCE + ".  No embedded configuration found
at: " +
-                        EMBEDDED_CONFIGURATION_RESOURCE);
-            }
-        }
-
-        context.getExternalContext().getApplicationMap().put(Globals.DIALOGS, this.dialogs);
         return this.dialogs;
 
     }

Added: shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java?view=auto&rev=473638
==============================================================================
--- shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
(added)
+++ shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
Fri Nov 10 20:16:19 2006
@@ -0,0 +1,206 @@
+/*
+ * 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.shale.dialog.basic;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import javax.faces.FacesException;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.dialog.basic.config.ConfigurationParser;
+
+/**
+ * <p>ServletContextListener that loads dialog configuration resources
+ * at application startup, and cleans up the libraries we depend on at
+ * application shutdown.</p>
+ */
+public class BasicLifecycleListener implements ServletContextListener {
+    
+
+    // -------------------------------------------------------- Static Variables
+
+
+    /**
+     * <p>The default configuration resource we will process (if present),
+     * even if it is not explicitly configured.</p>
+     */
+    private static final String DEFAULT_CONFIGURATION_RESOURCE =
+            "/WEB-INF/dialog-config.xml";
+
+
+    /**
+     * <p>Resource name for dialog configuration resource(s) embedded in
+     * JAR files inside the application.</p>
+     */
+    private static final String EMBEDDED_CONFIGURATION_RESOURCE =
+            "META-INF/dialog-config.xml";
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The <code>Log</code> instance we will use for this listener.</p>
+     */
+    private Log log = LogFactory.getLog(BasicLifecycleListener.class);
+
+
+    // ------------------------------------------ ServletContextListener Methods
+
+
+    /**
+     * <p>Process an application shutdown event.</p>
+     *
+     * @param event Shutdown event to be processed
+     */
+    public void contextDestroyed(ServletContextEvent event) {
+
+        if (log.isInfoEnabled()) {
+            log.info("Finalizing Dialog Basic Implementation");
+        }
+
+        // Clean up our cache of dialog configuration information
+        event.getServletContext().removeAttribute(Globals.DIALOGS);
+
+        // Clean up dependency libraries we have used
+        PropertyUtils.clearDescriptors();
+        LogFactory.release(Thread.currentThread().getContextClassLoader());
+        log = null;
+
+    }
+
+
+    /**
+     * <p>Process an application startup event.</p>
+     *
+     * @param event Startup event to be processed
+     */
+    public void contextInitialized(ServletContextEvent event) {
+
+        if (log.isInfoEnabled()) {
+            log.info("Initializing Dialog Basic Implementation");
+        }
+
+        // Set up to parse our specified configuration resources and cache the results
+        boolean didDefault = false;
+        ConfigurationParser parser = new ConfigurationParser();
+        parser.setDialogs(new HashMap());
+
+        // Parse implicitly specified resources embedded in JAR files
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = this.getClass().getClassLoader();
+        }
+        try {
+            Enumeration resources = loader.getResources(EMBEDDED_CONFIGURATION_RESOURCE);
+            while (resources.hasMoreElements()) {
+                URL resource = (URL) resources.nextElement();
+                if (log.isDebugEnabled()) {
+                    log.debug("Parsing configuration resource '"
+                              + resource + "'");
+                }
+                parser.setResource(resource);
+                parser.parse();
+            }
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new FacesException(e);
+        }
+
+        // Parse explicitly specified resources
+        String resources =
+          event.getServletContext().getInitParameter(Globals.CONFIGURATION);
+        if (resources == null) {
+            resources = "";
+            // Because we process the default resource even if it is not
+            // explicitly listed, we don't want to warn here
+        }
+        int comma = 0;
+        String path = null;
+        try {
+            while (true) {
+                comma = resources.indexOf(",");
+                if (comma < 0) {
+                    path = resources.trim();
+                    resources = "";
+                } else {
+                    path = resources.substring(0, comma).trim();
+                    resources = resources.substring(comma + 1);
+                }
+                if (path.length() < 1) {
+                    break;
+                }
+                URL resource = event.getServletContext().getResource(path);
+                if (log.isDebugEnabled()) {
+                    log.debug("Parsing configuration resource '"
+                              + resource + "'");
+                }
+                parser.setResource(resource);
+                parser.parse();
+                if (DEFAULT_CONFIGURATION_RESOURCE.equals(path)) {
+                    didDefault = true;
+                }
+            }
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new FacesException(e);
+        }
+
+        // Parse the default configuration resource if it exists and has not
+        // already been parsed
+        if (!didDefault) {
+            try {
+                URL resource =
+                  event.getServletContext().getResource(DEFAULT_CONFIGURATION_RESOURCE);
+                if (resource != null) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Parsing configuration resource '"
+                                  + resource + "'");
+                    }
+                    parser.setResource(resource);
+                    parser.parse();
+                }
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new FacesException(e);
+            }
+        }
+
+        // Cache the results in application scope
+        Map dialogs = parser.getDialogs();
+        if (dialogs.size() == 0) {
+            if (log.isWarnEnabled()) {
+                log.warn("No dialog configuration information present.  No default configuration
found at: " +
+                          DEFAULT_CONFIGURATION_RESOURCE + ".  No embedded configuration
found at: " +
+                          EMBEDDED_CONFIGURATION_RESOURCE);
+            }
+        }
+        event.getServletContext().setAttribute(Globals.DIALOGS, dialogs);
+
+    }
+
+
+}

Propchange: shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: shale/framework/trunk/shale-dialog-basic/src/main/java/org/apache/shale/dialog/basic/BasicLifecycleListener.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld?view=auto&rev=473638
==============================================================================
--- shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld (added)
+++ shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld Fri Nov
10 20:16:19 2006
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!DOCTYPE taglib PUBLIC
+ "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
+ "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
+
+<taglib>
+
+
+  <tlib-version>1.0</tlib-version>
+  <jsp-version>1.2</jsp-version>
+  <short-name>s</short-name>
+  <uri>http://shale.apache.org/dialog-basic</uri>
+  <display-name>Shale Framework Basic Dialog Tag Library</display-name>
+  <description>
+    This tag library contains no live custom tag handlers.  It exists
+    solely to declare the lifecycle context listener without requiring
+    any entries in the application's WEB-INF/web.xml resource
+  </description>
+
+
+  <!-- ===================== Servlet Listeners ============================= -->
+
+
+  <listener>
+    <listener-class>org.apache.shale.dialog.basic.BasicLifecycleListener</listener-class>
+  </listener>
+  
+
+  <!-- ================= JSF Component Tags ================================ -->
+
+
+</taglib>

Propchange: shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: shale/framework/trunk/shale-dialog-basic/src/main/resources/META-INF/taglib.tld
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



Mime
View raw message