Filter question
Hi, suggest, that I am creating a filter, which replaces the input stream. This works fine, if the input stream is used by the application itself. However, there are cases, when the Request class itself is accessing the input stream: If the method is POST and the content type is application/x-www-form-urlencoded and a method like getParameterNames() is invoked. In that case, the Request class is simply accessing the original input stream, circumventing the request wapper, that my filter has created. 1.) Is that intentional or is that a bug? 2.) If the former: Is there a way, I can ensure that my input stream is used? 3.) If the latter: Is there any chance to fix the bug? In other words: Does the Request class have access to the wrapper created by my filter? I'd be able to create and submit a patch in that case. Regards, Jochen - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: ExpandWar doesn't set the lastModified attribute
Nag! The mail below was sent by me two weeks ago. Is the idea to maintain timestamps so absurd, that it's not even worth a comment? -- Hi, would anyone please be so nice and comment http://issues.apache.org/bugzilla/show_bug.cgi?id=33636 Please note, that it contains a suggested patch. Regards, Jochen - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
ExpandWar doesn't set the lastModified attribute
Hi, would anyone please be so nice and comment http://issues.apache.org/bugzilla/show_bug.cgi?id=33636 Please note, that it contains a suggested patch. Regards, Jochen - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Proposed patch for Tomcat 4.1: Replacing JarURLHandler with Ant's ZipFile class
Hi, in http://nagoya.apache.org/bugzilla/show_bug.cgi?id=26275 it turned out, that Tomcat suffers from a problem in Java's zip file handling, which persists since years and most probably won't be fixed in the next years. It also turned out, that the problem could be fixed by using Ant's ZipFile class. In the last days I inspected Tomcat's (4.1.30) sources for extracting WAR files. To be honest, I find them a real mess. The design decision for dealing with jar: and file: URL's seems to me to be severely broken, because in the end it depends on an underlying File anyways. Attached you find a patch, which is *not* necessary to fix bug 26275. (Changes in ExtractWar would be sufficient.) However, I find it worth looking at, because you'll easily see that replacing URL's with File's reduces the code complexity quite much. The attached patch is *not* ready for checkin, because I did not even test it. (That's why I omitted the [PATCH] in the subject.) I just wanted a first sign, whether it's worth to continue. If you don't like this work, let me know and I'll return with a smaller fix for 26275. Jochen Only in c:\jwi\Workspace\jakarta-tomcat-4.1.30-src: .classpath Only in c:\jwi\Workspace\jakarta-tomcat-4.1.30-src: .project Only in c:\jwi\Workspace\jakarta-tomcat-4.1.30-src: bin diff -ubr c:\tmp\jakarta-tomcat-4.1.30-src/catalina/src/share/org/apache/catalina/Deployer.java c:\jwi\Workspace\jakarta-tomcat-4.1.30-src/catalina/src/share/org/apache/catalina/Deployer.java --- c:\tmp\jakarta-tomcat-4.1.30-src/catalina/src/share/org/apache/catalina/Deployer.java 2004-01-25 14:23:36.0 +0100 +++ c:\jwi\Workspace\jakarta-tomcat-4.1.30-src/catalina/src/share/org/apache/catalina/Deployer.java 2004-03-15 05:06:46.858592000 +0100 @@ -65,6 +65,7 @@ package org.apache.catalina; +import java.io.File; import java.io.IOException; import java.net.URL; @@ -117,22 +118,21 @@ public String getName(); -/** - * Install a new web application, whose web application archive is at the - * specified URL, into this container with the specified context path. - * A context path of "" (the empty string) should be used for the root - * application for this container. Otherwise, the context path must - * start with a slash. - * - * If this application is successfully installed, a ContainerEvent of type - * INSTALL_EVENT will be sent to all registered listeners, - * with the newly created Context as an argument. - * - * @param contextPath The context path to which this application should - * be installed (must be unique) - * @param war A URL of type "jar:" that points to a WAR file, or type - * "file:" that points to an unpacked directory structure containing - * the web application to be installed +/** Install a new web application with the given context path. If this + * application is successfully installed, a [EMAIL PROTECTED] ContainerEvent} of + * type [EMAIL PROTECTED] #INSTALL_EVENT} will be sent to all registered + * listeners, with the newly created Context as an + * argument. + * + * @param contextPath The context path to which this application + * should be installed (must be unique). A context path of "" + * (the empty string) should be used for containers root + * application. Otherwise, the context path must start with a + * slash. + * @param war The web application being installed. If the location + * points to a file, then it is assumed, that the file contains + * a web application archive. Otherwise, the location must point + * to a directory with the extracted web application. * * @exception IllegalArgumentException if the specified context path * is malformed (it must be "" or start with a slash) @@ -141,7 +141,7 @@ * @exception IOException if an input/output error was encountered * during installation */ -public void install(String contextPath, URL war) throws IOException; +public void install(String contextPath, File war) throws IOException; /** @@ -156,9 +156,10 @@ * * @param config A URL that points to the context configuration file to * be used for configuring the new Context - * @param war A URL of type "jar:" that points to a WAR file, or type - * "file:" that points to an unpacked directory structure containing - * the web application to be installed + * @param war The web application being installed. If the location + * points to a file, then it is assumed, that the file contains + * a web application archive. Otherwise, the location must point + * to a directory with the extracted web application. * * @exception IllegalArgumentException if one of the specified URLs is * null @@ -168,7 +169,7 @@ * @exception IOException if an input/output error was encountered * during installation */
[Patch] TC3.2: error-page directive is not properly supported by Jasper
Hi, I have just submitted #3377 to Bugzilla, where I describe the following problem and a workaround. When using the error-page directive in web.xml, the exception handling of JSP pages is insufficient. What happens is that Jasper catches the exception, but isn't aware of the configured error-page. As it may throw only ServletExceptions, it does exactly that, discards the actual exception, keeps the exception message and creates a new ServletException. (See handlePageException().) In practice that means, that the stack trace is lost in error messages, making them practically useless, because you always see the stack trace of handlePageException(). IMO Jasper should have a possibility to see the error-page directive and handle it properly. In our production environment we do this with the attached patch, which is mainly a workaround, because it breaks the separation between TomCat and Jasper. However, as the Specification does not give a way to find the configured error-page (at least no way that I can think of), this is probably the way to go. Thanks, Jochen Only in c:\Programme\jakarta-tomcat-3.2.3\src/org/apache/jasper/runtime: .nbattrs diff -ubr --exclude *.class --exclude *~ c:\temp\jakarta-tomcat-3.2.3\src/org/apache/jasper/runtime/PageContextImpl.java c:\Programme\jakarta-tomcat-3.2.3\src/org/apache/jasper/runtime/PageContextImpl.java --- c:\temp\jakarta-tomcat-3.2.3\src/org/apache/jasper/runtime/PageContextImpl.java Tue Jul 17 16:57:50 2001 +++ +c:\Programme\jakarta-tomcat-3.2.3\src/org/apache/jasper/runtime/PageContextImpl.java + Mon Sep 3 08:21:17 2001 @@ -441,11 +441,34 @@ // set the request attribute with the exception. request.setAttribute("javax.servlet.jsp.jspException", e); - if (errorPageURL != null && !errorPageURL.equals("")) { + // Try to obtain an error page URL + String url = errorPageURL; + if (url == null || "".equals(url)) { +org.apache.tomcat.core.Context ctx = null; +if (context instanceof org.apache.tomcat.core.Context) { + ctx = (org.apache.tomcat.core.Context) context; +} else if (context instanceof +org.apache.tomcat.facade.ServletContextFacade) { +ctx = ((org.apache.tomcat.facade.ServletContextFacade) +context).getRealContext(); +} +if (ctx != null) { + url = ctx.getErrorPage(e.getClass().getName()); + if (url == null || "".equals(url)) { + url = ctx.getErrorPage("java.lang.Exception"); + if (url == null || "".equals(url)) { + url = ctx.getErrorPage("java.lang.Throwable"); + if (url == null || "".equals(url)) { + url = ctx.getErrorPage("500"); +} + } + } + } + } + + if (url != null && !"".equals(url)) { try { -forward(errorPageURL); +forward(url); } catch (IllegalStateException ise) { -include(errorPageURL); +include(url); } } // Otherwise throw the exception wrapped inside a ServletException. else { diff -ubr --exclude *.class --exclude *~ c:\temp\jakarta-tomcat-3.2.3\src/org/apache/tomcat/facade/ServletContextFacade.java c:\Programme\jakarta-tomcat-3.2.3\src/org/apache/tomcat/facade/ServletContextFacade.java --- c:\temp\jakarta-tomcat-3.2.3\src/org/apache/tomcat/facade/ServletContextFacade.java Tue Jul 17 16:57:50 2001 +++ +c:\Programme\jakarta-tomcat-3.2.3\src/org/apache/tomcat/facade/ServletContextFacade.java +Mon Sep 3 08:21:38 2001 @@ -79,7 +79,7 @@ * @author James Todd [[EMAIL PROTECTED]] * @author Harish Prabandham */ -final class ServletContextFacade implements ServletContext { +public final class ServletContextFacade implements ServletContext { // Use the strings from core private static StringManager sm = StringManager.getManager("org.apache.tomcat.core"); private ContextManager contextM; @@ -90,7 +90,7 @@ this.context = context; } -Context getRealContext() { +public Context getRealContext() { return context; }
TC 3.2: How to debug thread pool problems?
Hi, we are using TC 3.2.2 (upgrade to 3.2.3 soon to follow) in a production environment with medium traffic and standalone mode. The configuration in server.xml is identical to the distribution, except for the modified port number and an in the configuration of the HTTP connector. Other connectors are not in use, except for shutdown (AJP12). From time to time it occurs, that TomCat is no more serving requests. In the error log I find the message "thread pool exhausted". The dropouts could be reduced by increasing the thread pool size and by rebooting nightly. However, from time to time the problem still occurs, although I am sure that we never serve 500 concurrent connections. My question is: How do I debug the problem? I would like to insert appropriate log statements into the TomCat source, that tell me when a new thread is created, when its serving a request, when it finishs serving a request, when its returned to or obtained from the pool in the hope to find a responsible problem in some servlet or whatever by analyzing thir output. However, I am not sufficiently used to the TomCat source to determine the appropriate locations for such logging statements. Any help appreciated. Thanks, Jochen
TomCat TCP connector leaking
[This was posted on tomcat-user some weeks ago. As there was no response I am now trying it here.] Hi, we are using TC 3.2.2 in standalone mode on a medium frequented site. I am sure we never have more than 40-50 active, simultaneous connections. However, from time to time I see the message "thread pool exhausted" in jvm.stderr. I have raised the max_threads parameter in server.xml, lets see if this helps. However, I actually wonder how 100 threads can be used? Our application has some long running servlets in push mode, but definitely not that much. So I ask myself whether the thread pool of the TCP connector is leaking? My question is: How would I debug the TCP connector? How can I determine, which threads are actually busy, running which servlet and which are waiting? Thanks, Jochen
Acceptance of patches
Hi, it is quite some weeks since I have posted a patch for a bug that makes TomCat's getWriter().flush() method completely unusable. (Perhaps in standalone method only.) I have also submitted a bug report (#1802). Since then I have never received a reply and the bug report is still in the state "NEW". That makes me wonder what good my patch is for? Did I miss some policy guideline? Or what else is wrong? Thanks, Jochen
Recycle Logic in 3.2.1 broken
Hi, I have detected what seems to be a bug in the recycle logic of TomCat 3.2.1. What seems to be happening is, that a response object of some kind is using a Writer and processes the request. In some other request the BufferedServletOutputStream's "usingWriter" flag is still set, in other words, the recycling doesn't seem to work properly. I can demonstrate the problem and create a workaround by adding the following code on top of my servlet. It uses a method isUsingWriter(), which I have added to the BufferedServletOutputStream class: ServletOutputStream os = pRes.getOutputStream(); if (os instanceof org.apache.tomcat.core.BufferedServletOutputStream) { org.apache.tomcat.core.BufferedServletOutputStream bsos = (org.apache.tomcat.core.BufferedServletOutputStream) os; if (bsos.isUsingWriter()) { Trace.Log(this, "tmGet", 5, "OutputStream is using Writer"); bsos.setUsingWriter(false); } }
Is response.getServletOutputStream().flush() working
Hi, subject says it all, but an explanation is missing, of course. I am talking about TomCat 3.2.1, my observation is this: - response.getServletOutputStream() is actually org.apache.tomcat.core.BufferedServletOutputStream.flush() - This method is calling org.apache.tomcat.core.BufferedServletOutputStream.reallyFlush() - This method is calling org.apache.tomcat.core.BufferedServletOutputStream.doWrite() - This method is calling org.apache.tomcat.core.ResponseImpl.doWrite() which is simply appending the collected bytes to the body() variable. A flush() operation doesn't actually occur. Please tell me, if there's something wrong with my observation. If not: Where is the body content actually written? Thanks in advance, Jochen
getHostByName() disabled in AccessLogInterceptor
Hi, attached you find a slightly modified version of the AccessLogInterceptor that I have recently submitted to this mailing list. The AccessLogInterceptor is generating log files in the style of Apache's request logs. The difference to the first version is that the log file styles "common" and "combined" are now by default using request.getRemoteAddr() (%a) and not request.getRemoteHost() (%h). The former turned out to be too slow in practice. I would appreciate if this could make it into the TomCat distribution. I would also offer to insert it into the CVS tree myself, if I could get an account. Thanks, Jochen AccessLogInterceptor.java
Re: Access log files in the style of Apache
Quoting [EMAIL PROTECTED]: > Please send the source file - you attached a .class :-) So sorry - here it is. :-) Thank you, Jochen package org.apache.tomcat.logging; import org.apache.tomcat.core.BaseInterceptor; import org.apache.tomcat.core.ContextManager; import org.apache.tomcat.core.Request; import org.apache.tomcat.core.Response; import org.apache.tomcat.core.TomcatException; /** This is a TomCat RequestInterceptor that creates log files * in the style of the Apache servers "AccessLog". It used by * embedding a line like the following into server.xml: * * <RequestInterceptor * className="org.apache.tomcat.logging.AccessLogInterceptor" * logFile="logs/AccessLog" format="combined"/> * * Possible attributes of the above XML element are: * * * logFile * Name of the logfile being generated. Defaults to "logs/AccessLog". * Tomcat.home is prepended, if the file name is relative. * * * flush * An optional boolean attribute, that enables (value = "true") * or disables (value="false", default) flushing the log file * after every request. For performance reasons, you should * not enable flushing unless you are debugging this class. * * * * format * * A string describing the logfile format. Possible values are * "combined" (Apache httpd combined format, default), "common" * (Apache httpd common format) or a format string like * * '%h %l %u %t "%r" %>s %b "%{Referer}" "%{User-Agent}"' * '%h %l %u %t "%r" %>s %b' * * (The above examples are used when "combined" or "common" * format is requested.) Possible patterns are: * * %% * The percent character itself * * * %{var} * The value of request.getHeader("var") or * empty string for null. * * * %b * The value of response.getContentLength(). * * * %h * The value of request.getRemoteHost(). * * * %l * Should be the remote users name, as indicated by an * identd lookup. Currently it is always "-". * * * %r * First line of the request submitted by the client, for * example * * GET /index.html?frame=main HTTP/1.0 * * The first line is rebuilt from the values of * request.getMethod(), * request.getRequestURI(), * request.getQueryString() and * request.getProtocol(). It should probably * better be recorded while reading the headers. * * * * %s * The value of response.getStatus(). * * * %>s * The value of response.getStatus(). * Should differ between different internal requests, as * Apache httpd does, but this is currently not supported. * * * %t * The current time and date in the format * * [20/Apr/2001:19:45:23 0200] * * * * * %u * The value of request.getRemoteUser() or * "-" for null.. * * * * * * * * * @author Jochen Wiedmann, [EMAIL PROTECTED] */ public class AccessLogInterceptor extends BaseInterceptor { private static final String LOGFORMAT_COMBINED = "%h %l %u %t \"%r\" %>s %b \"%{Referer}\" \"%{User-Agent}\""; private static final String LOGFORMAT_COMMON = "%h %l %u %t \"%r\" %>s %b"; private static java.io.FileWriter fw = null; private static String fileName = "logs/AccessLog"; private static boolean useFlush = false; private static String logformat = LOGFORMAT_COMBINED; private static java.text.DateFormat df = new java.text.SimpleDateFormat("dd/MMM/:HH:mm:ss"); /** Creates a new AccessLogInterceptor */ public AccessLogInterceptor() {} /** Sets the logfile name. */ public static void setLogFile(String logFile) { synchronized (AccessLogInterceptor.class) { fileName = logFile; } } /** Enables (true) or disables (false, default) flushing * the log file after any request. */ public static void setFlush(boolean flush) { synchronized (AccessLogInterceptor.class) { useFlush = flush; } } /** Sets the logfile format. */ public static void setFormat(String format) { synchronized (AccessL