Return-Path: Delivered-To: apmail-myfaces-dev-archive@www.apache.org Received: (qmail 61078 invoked from network); 4 Sep 2007 19:02:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Sep 2007 19:02:55 -0000 Received: (qmail 86206 invoked by uid 500); 4 Sep 2007 19:02:48 -0000 Delivered-To: apmail-myfaces-dev-archive@myfaces.apache.org Received: (qmail 86166 invoked by uid 500); 4 Sep 2007 19:02:48 -0000 Mailing-List: contact dev-help@myfaces.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "MyFaces Development" Delivered-To: mailing list dev@myfaces.apache.org Delivered-To: moderator for dev@myfaces.apache.org Received: (qmail 4996 invoked by uid 99); 4 Sep 2007 17:02:44 -0000 X-ASF-Spam-Status: No, hits=2.6 required=10.0 tests=DNS_FROM_OPENWHOIS,SPF_HELO_PASS,SPF_PASS,WHOIS_MYPRIVREG X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of bounces@nabble.com designates 216.139.236.158 as permitted sender) Message-ID: <12489828.3414471188925338191.JavaMail.nabble@isper.nabble.com> From: skold@comcast.net To: dev@myfaces.apache.org Subject: [jira] Created: (TOMAHAWK-1040) Apparent File Handle Leak with Tomahawk 1.1.5 or 1.1.6 with MyFaces 1.1.5 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Tue, 04 Sep 2007 10:02:18 -0700 X-Virus-Checked: Checked by ClamAV on apache.org Derek, We just started seeing our Web application hanging this last week to too many open files (Switched over to tomahawk 1.1.5 about two weeks ago and use both the calendar function and the JSCookMenu). I saw your post here and was wondering two things. First, do you know if the new version of MyFaces 1.2.0 has fixed this issue? Second, where in the configuration do you make the change to call the new resource class instead of the DefaultAddResource? Thanks, Randy Skold My Faces - Dev mailing list wrote: > > Apparent File Handle Leak with Tomahawk 1.1.5 or 1.1.6 with MyFaces 1.1.5 > ------------------------------------------------------------------------- > > Key: TOMAHAWK-1040 > URL: https://issues.apache.org/jira/browse/TOMAHAWK-1040 > Project: MyFaces Tomahawk > Issue Type: Bug > Affects Versions: 1.1.6, 1.1.5 > Environment: Linux version 2.6.9-42.0.10.plus.c4smp > Java 1.5.0_09-b03 > Tomcat 5.5.20 > > Reporter: Derek C. Ashmore > Priority: Critical > > > We experienced a file handle leak when using Tomahawk components that > require static resources, such as the JSCookMenu, Calendar, and Tabbed > Pane. The handle allocations never go away. Eventually, the container > becomes inoperative and has to be restarted. > > We experience this bug under Tomahawk 1.1.5 and 1.1.6 using Myfaces 1.1.5. > We do *not* experience the leak under Myfaces/Tomahawk 1.1.3. I have no > information about whether the bug appears under 1.1.4. > > We detected the leak behavior by monitoring our container process using > lsof. > > Although it's a hack and I don't like it, I was able to avoid the leak by > writing a custom AddResource class (and changing the configuration so that > my custom class was used instead of the default). My custom AddResource > class works by caching request resources and preventing more than one I/O > to a given resource. > > My source code (for what it's worth) is attached below. I'd be happy to > provide additional information -- I would rather see this bug fixed in > 1.1.6 then have my hack around for ever. > > Thanks for looking at this. > > --------------------------------------------------------------------------------------------------------- > package com.ies.common.ui.common.util; > > import java.io.ByteArrayInputStream; > import java.io.ByteArrayOutputStream; > import java.io.IOException; > import java.io.InputStream; > import java.util.Map; > import java.util.StringTokenizer; > import java.util.concurrent.ConcurrentHashMap; > > import javax.servlet.ServletContext; > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > > import org.apache.myfaces.renderkit.html.util.DefaultAddResource; > import org.apache.myfaces.renderkit.html.util.DefaultResourceProvider; > import org.apache.myfaces.renderkit.html.util.MyFacesResourceLoader; > > import com.ies.common.error.IESRuntimeException; > > /** > * Needed to prevent 'too many file handles' problem. > * @author D. Ashmore > * > */ > public class IesAddResource extends DefaultAddResource { > > private static final String MYFACES_RESOURCE = "MyFacesResourceLoader"; > private static final String MYFACES_PACKAGE_PREFIX = > "org.apache.myfaces.custom."; > private static Map resourceMap = new > ConcurrentHashMap(); > > public IesAddResource() { > // No Op > } > > @Override > public void serveResource(ServletContext context, HttpServletRequest > request, HttpServletResponse response) throws IOException { > String pathInfo = request.getPathInfo(); > String uri = request.getContextPath() + request.getServletPath() > + (pathInfo == null ? "" : pathInfo); > > if (uri.indexOf(MYFACES_RESOURCE) > 0) { > StringTokenizer token = new StringTokenizer(uri, "/"); > if (token.countTokens() < 6) { > super.serveResource(context, request, response); > return; > } > > // Bypass the first five tokens as non-essential. > token.nextToken(); > token.nextToken(); > token.nextToken(); > token.nextToken(); > token.nextToken(); > String className = token.nextToken(); > Class componentClass = null; > try { > componentClass = Class.forName(MYFACES_PACKAGE_PREFIX + > className); > } > catch (Exception e) { > IESRuntimeException ire = new IESRuntimeException("Class not > found."); > ire.addLabeledValue("className", className); > > throw ire; > } > > DefaultResourceProvider provider = new > DefaultResourceProvider(componentClass); > String resource = uri.substring( > uri.lastIndexOf(className) + > className.length() + 1); > String resourceKey = className + resource; > > Resource resourceData = (Resource)resourceMap.get(resourceKey); > InputStream is = null; > MyResourceLoader loader = new MyResourceLoader(); > > if (resourceData == null) { > resourceData = new Resource(); > try { > is = provider.getInputStream(context, resource); > if (is == null) { > IESRuntimeException ire = new IESRuntimeException("Resource > not found."); > ire.addLabeledValue("resource", resource); > > throw ire; > } > resourceData.setData(inputStreamReader(is)); > resourceData.setEncoding(provider.getEncoding(context, > resource)); > resourceData.setLastModified(provider.getLastModified(context, > resource)); > > resourceData.setContentLength(provider.getContentLength(context, > resource)); > } > finally {if (is != null) is.close();} > resourceMap.put(resourceKey, resourceData); > > } > is = new ByteArrayInputStream(resourceData.data); > > loader.defineContentHeaders(request, response, resource, > resourceData.data.length, resourceData.encoding); > loader.defineCaching(request, response, resource, > resourceData.lastModified); > loader.writeResource(request, response, is); > } > else super.serveResource(context, request, response); > } > > private byte[] inputStreamReader(InputStream is) throws IOException { > ByteArrayOutputStream outStream = new ByteArrayOutputStream(512000); > > byte[] bArray = new byte[8192]; > int nbrBytesRead = is.read(bArray); > while (nbrBytesRead > 0) { > outStream.write(bArray, 0, nbrBytesRead); > nbrBytesRead = is.read(bArray); > } > > return outStream.toByteArray(); > } > > private static class Resource { > byte[] data; > long lastModified; > long contentLength; > String encoding; > > public Resource() { > } > > public byte[] getData() { > return data; > } > > public void setData(byte[] data) { > this.data = data; > } > > public String getEncoding() { > return encoding; > } > > public void setEncoding(String encoding) { > this.encoding = encoding; > } > > public long getLastModified() { > return lastModified; > } > > public void setLastModified(long lastModified) { > this.lastModified = lastModified; > } > > public long getContentLength() { > return contentLength; > } > > public void setContentLength(long contentLength) { > this.contentLength = contentLength; > } > } > > private static class MyResourceLoader extends MyFacesResourceLoader { > > @Override > public void defineCaching(HttpServletRequest request, > HttpServletResponse response, String resource, long lastModified) { > super.defineCaching(request, response, resource, lastModified); > } > > @Override > public void defineContentHeaders(HttpServletRequest request, > HttpServletResponse response, String resource, int contentLength, String > contentEncoding) { > super.defineContentHeaders(request, response, resource, contentLength, > contentEncoding); > } > > @Override > public void writeResource(HttpServletRequest request, > HttpServletResponse response, InputStream in) throws IOException { > super.writeResource(request, response, in); > } > > } > > } > > -- > This message is automatically generated by JIRA. > - > You can reply to this email to add a comment to the issue online. > > > Quoted from: http://www.nabble.com/-jira--Created%3A-%28TOMAHAWK-1040%29-Apparent-File-Handle-Leak-with-Tomahawk-1.1.5-or-1.1.6-with-MyFaces-1.1.5-tf3998086.html#a11354721