Question about ByteChunk.substract implementation
Why does the implementation of the substract() methods of org.apache.tomcat.util.buf.ByteChunk.java (http://cvs.apache.org/viewcvs.cgi/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/buf/ByteChunk.java?rev=1.24view=markup) assume that in.realReadBytes will manipulate the start and end pointers of ByteChunk? org.apache.coyote.http11.InternalInputBuffer.doRead [which gets invoked along the realReadBytes codepath] calls ByteChunk.setBytes (which initializes start, end etc) so the scenario below doesn't occur with the coyote connector. Just wondering if this is a contract that other buffering connector implementations must adhere to. In the code below, when buff needs to be refilled (e.g. start = end = buff.length = 8192), and if realReadBytes doesn't reset start to 0, then buff[start++] results in an IndexOutOfBoundsException. The other substract() variants have a similar issue. public int substract() throws IOException { if ((end - start) == 0) { if (in == null) return -1; int n = in.realReadBytes( buff, 0, buff.length ); if (n 0) return -1; } return (buff[start++] 0xFF); } I expected to see start, off and end rest in the substract() method itself. public int substract() throws IOException { if ((end - start) == 0) { if (in == null) return -1; int n = in.realReadBytes( buff, 0, buff.length ); start = off = 0; end = n; } return (buff[start++] 0xFF); } Thanks, Arvind - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
qn about ResponseFacade.flushBuffer()
In http://cvs.apache.org/viewcvs.cgi/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/ResponseFacade.java?annotate=1.3 What was the intention of the following ? 175 if (isFinished()) 176 resp.setSuspended(true) since 137 public boolean isFinished() { 138 139 return resp.isSuspended(); 140 141 } Thanks, Arvind - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[PATCH] TC4.0 - Intermittent IllegalArgumentException inWebappClassLoader
Attaching a patch that fixes an intermittent error (that occurs when an attempt is made to define a package that has already been defined). I noticed this when running a multi-threaded test. - Root Cause - java.lang.IllegalArgumentException: Servlet22.S05_Request at java.lang.ClassLoader.definePackage(ClassLoader.java:1151) at java.net.URLClassLoader.definePackage(URLClassLoader.java:310) at org.apache.catalina.loader.WebappClassLoader.findClassInternal(Webapp ClassLoader.java:1647) at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoa der.java:970) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa der.java:1409) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa der.java:1287) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper. java:870) at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.jav a:658) Arvind Index: WebappClassLoader.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v retrieving revision 1.15.2.11 diff -u -r1.15.2.11 WebappClassLoader.java --- WebappClassLoader.java 18 Feb 2002 05:22:07 - 1.15.2.11 +++ WebappClassLoader.java 18 Jul 2002 22:34:45 - @@ -1599,15 +1599,18 @@ if (packageName != null) { -pkg = getPackage(packageName); +synchronized (loaderPC) { +pkg = getPackage(packageName); -// Define the package (if null) -if (pkg == null) { -if (entry.manifest == null) { -definePackage(packageName, null, null, null, null, null, - null, null); -} else { -definePackage(packageName, entry.manifest, entry.source); +// Define the package (if null) +if (pkg == null) { +if (entry.manifest == null) { +definePackage(packageName, null, null, null, null, + null, null, null); +} else { +definePackage(packageName, entry.manifest, + entry.source); +} } } -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[TC 4.0/4.1] - Recycling session objects is inherently error prone
Since the lifetime of session objects span requests and since session objects are expired asynchronously by the background thread created by the session manager, if one did recycle session objects then isn't it possible for 2 separate requests to access and possibly modify a session object simultaneously ? - Request 1 gets access to a session (session-timeout = 1 minute) - Request 1 then does some operations that take a couple of minutes - The session manager thread expires the session and recycles the session object - Request 2 asks for a session and gets a reference to the recycled session object and starts using it - Request 1's database operations complete and it too uses the session o.a.c.session.ManagerBase has an ArrayList 'recycled' that is used for recycling session objects. 4.0.x never uses this because manager is set to null in StandardSession.recycle() and hence ManagerBase.recycle() is never invoked. 4.1 however, does recycle sessions and does run into the problem described in the above scenario when running a session based load on a multi-cpu box. If this is indeed a problem, I can submit a patch that removes the session recycling code. Thanks, Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: $ in JSP names
Craig R. McClanahan wrote: On Mon, 15 Jul 2002, Kin-Man Chung wrote: Date: Mon, 15 Jul 2002 11:55:15 -0700 (PDT) From: Kin-Man Chung [EMAIL PROTECTED] Reply-To: Tomcat Developers List [EMAIL PROTECTED], Kin-Man Chung [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Re: $ in JSP names I totally agree that the use of $ in a file name is a pain in the neck. In fact, I don't see the need for appending a $jsp at all. Currently we have the following mapping: jsp file name: foo.jsp class name: foo$jsp servelt file name: foo$jsp.java class file name: foo$jsp.class I think it'd be perfectly OK to use the following mapping: jsp file name: foo.jsp class name: foo servelt file name: foo.java class file name: foo.class I thought the reason for appending something ($jsp or _jsp) was to prevent errors in the generated java files for jsp filenames that use one of java's keywords - default.jsp or new.jsp. -Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[PATCH] TC 4.1 - Prevent NPEs after sessions are recycled
The change made in v1.29 to o.a.c.session.StandardSession.java sets the manager of a session to null *after* the session has been recycled (another thread could pick up and start using the recycled session before manager is set to null). Even under a light session-based workload, this causes NPEs when the recycled session uses the manager (to make calls like manager.getContainer() in session.setAttribute for example). The attached patch fixes this by not modifying the session's data members once it has been sent to its manager for recycling. thanks, Arvind ? .StandardSession.java.swp Index: StandardSession.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/session/StandardSession.java,v retrieving revision 1.30 diff -u -r1.30 StandardSession.java --- StandardSession.java21 Jun 2002 18:14:21 - 1.30 +++ StandardSession.java13 Jul 2002 02:11:07 - @@ -766,12 +766,13 @@ setPrincipal(null); isNew = false; isValid = false; +Manager savedManager = manager; +manager = null; // Tell our Manager that this Session has been recycled -if ((manager != null) (manager instanceof ManagerBase)) -((ManagerBase) manager).recycle(this); +if ((savedManager != null) (savedManager instanceof ManagerBase)) +((ManagerBase) savedManager).recycle(this); -manager = null; } -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[PATCH] TC 4.0.4 - Disallow setLocale() on an included response
simple patch to ignore response header changes (by included servlets) via setLocale. -Arvind Index: ApplicationHttpResponse.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationHttpResponse.java,v retrieving revision 1.6 diff -u -r1.6 ApplicationHttpResponse.java --- ApplicationHttpResponse.java22 Jul 2001 20:25:08 - 1.6 +++ ApplicationHttpResponse.java24 Jun 2002 22:00:52 - @@ -66,6 +66,7 @@ import java.io.IOException; +import java.util.Locale; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; @@ -188,6 +189,19 @@ if (!included) getResponse().setContentType(type); + +} + + +/** + * Disallow codesetLocale()/code calls on an included response. + * + * @param loc The new locale + */ +public void setLocale(Locale loc) { + +if (!included) +getResponse().setLocale(loc); } -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[PATCH] [TC 4.0.4] Missing charset= in JSP Content-Type headers
JSPs don't seem to be setting the Content-Type header correctly. Have attached a patch that adds the missing 'charset=' string to the content-type value. thx, arvind GET /foo.jsp HTTP/1.0 HTTP/1.1 200 OK Content-Type: text/html;ISO-8859-1 Connection: close Date: Mon, 24 Jun 2002 02:07:50 GMT Server: Apache Tomcat/4.0.4-dev (HTTP/1.1 Connector) Set-Cookie: JSESSIONID=F2343A7E566549F42027165B1896184E;Path=/ html /html Index: JspParseEventListener.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/JspParseEventListener.java,v retrieving revision 1.33.2.5 diff -u -r1.33.2.5 JspParseEventListener.java --- JspParseEventListener.java 21 May 2002 01:46:40 - 1.33.2.5 +++ JspParseEventListener.java 24 Jun 2002 02:12:33 - @@ -361,7 +361,7 @@ // Per errata_a, determine the default output content type if (servletContentType == null) { -servletContentType = defaultType + +servletContentType = defaultType + charset= + ((pageEncoding == null)? defaultCharset: pageEncoding); } writer.println(response.setContentType( -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
ArrayIndexOutOfBoundsException in WebappClassLoader
I'm unable to reproduce this easily but I was running some tests (using a multithreaded load generator) on a 4 cpu machine and encountered a couple of ArrayIndexOutOfBoundsException @ lines 1747 and 1754 in o.a.c.loaders.WebappClassLoader.java. 737// Register the full path for modification checking 1738 synchronized (paths) { 1739 1740int j; 1741 1742long[] result2 = 1743new long[lastModifiedDates.length + 1]; 1744for (j = 0; j lastModifiedDates.length; j++) { 1745result2[j] = lastModifiedDates[j]; 1746} 1747result2[lastModifiedDates.length] = entry.lastModified; 1748lastModifiedDates = result2; 1749 1750String[] result = new String[paths.length + 1]; 1751for (j = 0; j paths.length; j++) { 1752result[j] = paths[j]; 1753} 1754result[paths.length] = fullPath; 1755paths = result; 1756 1757} Shouldn't line 1738 synchronize on 'this' rather than 'paths' because 'paths' is changed to point to a new array within the synchronized block itself @ line 1755 ? Thanks, Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: Qn about a performance bottleneck in InvokerServlet
Craig R. McClanahan wrote: The purpose is a performance optimization -- on subsequent requests to /servlet/foo, the container should find an existing mapping for the servlet, so it will get called directly instead of going through the invoker. context.addServletMapping is called on every request to the InvokerServlet and shows up on performance profiles. Removing it did not affect the behaviour of InvokerServlet but it eliminated this performance hotspot. The intent is that the invoker only gets called once for any given /servlet/xxx pattern. If it's actually executing the invoker again, that's a bug (probably in the way the dynamically registered servlet mapping's URL pattern is constructed). My apologies...the bug was in a change I had made in my tree. The performance optimization is working as implemented. Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: embedded tomcat and JspServlet
Richard Unger wrote: jsp: init Internal Error: File /WEB-INF/web.xml not found. I believe this particular error message is generated (by o.a.j.compiler.TldLocationsCache.processWebDotXml) when initializing the default context (which doesn't have a WEB-INF/web.xml). I don't think this causes any problems (nor is it the source of your error) and the message should probably be suppressed. Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
TC4: qn about requestdispatcher forwards and input streams
I'd appreciate it if someone can clarify whether the following is a bug in TC4 or not. I have a servlet whose doPost() implementation simply gets hold of a requestdispatcher and invokes forward() on it. The form that is posted contains a couple of name/value parameters. The forwarded-to servlet runs into an error when it tries to read data from the input stream of the request. The error is that the input stream has already been closed. o.a.c.core.ApplicationDispatcher.forward() invokes its wrapRequest() method which in turn ends up invoking ApplicationHttpRequest.setRequest() which reads the parameters (request.getParameterMap()) from the input stream and closes the input stream. The servlet spec says the following about POST data parameters. -- SRV.4.1.1 When Parameters Are Available The following are the conditions that must be met before post form data will be populated to the parameter set: 1. The request is an HTTP or HTTPS request. 2. The HTTP method is POST 3. The content type is application/x-www-form-urlencoded 4. The servlet has made an initial call of any of the getParameter family of methods on the request object. If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request objects input stream. If the conditions are met, post form data will no longer be available for reading directly from the request objects input stream. --- If my understanding is right, condition #4 is not met in the ApplicationDispatcher.forward() codepath, so the parameters/data should not have been read from the input stream. (I read the request dispatcher section of the spec and it only talked about query string parameters and doesn't say what should be done to the data on the input stream.) Thanks, Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardPipeline.java
Hi Remy, I think the performance related change that you made to StandardPipeline can be improved upon in that it can avoid using a HashMap to store/retrieve the pipeline stage and instead simply store/retrieve it from an integer variable in the RequestBase class. Since this codepath (StandardPipeline.invokeNext) is executed many times per request, replacing the request.getNote() call with something like request.getPipelineStage() will benefit performance. I've attached a patch that implements this suggestion. Thanks, Arvind remm02/03/31 20:19:55 Modified:catalina/src/share/org/apache/catalina/core StandardPipeline.java Log: - Use a note in the request instead of a ThreadLocal to keep track of the pipeline stage. Note: This could cause problems with a valve that would wrap the request, and not delegate the getNote method to the wrapped request. Index: catalina/src/share/org/apache/catalina/Request.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/Request.java,v retrieving revision 1.5 diff -u -r1.5 Request.java --- catalina/src/share/org/apache/catalina/Request.java 1 Aug 2001 03:04:04 - 1.5 +++ catalina/src/share/org/apache/catalina/Request.java 3 Apr 2002 08:40:02 - @@ -210,6 +210,22 @@ public void setWrapper(Wrapper wrapper); +/** + * Set the index of the (next) valve (in the pipeline) that will process + * this request. + * + * @param stage The position of the next valve (in the pipeline) + */ +public void setPipelineStage(int stage); + + +/** + * Return the index (in the pipeline) of the valve that is to process + * this request. + */ +public int getPipelineStage(); + + // - Public Methods Index: catalina/src/share/org/apache/catalina/connector/RequestBase.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/RequestBase.java,v retrieving revision 1.18 diff -u -r1.18 RequestBase.java --- catalina/src/share/org/apache/catalina/connector/RequestBase.java 18 Mar 2002 07:15:39 - 1.18 +++ catalina/src/share/org/apache/catalina/connector/RequestBase.java 3 Apr 2002 +08:40:02 - @@ -270,6 +270,13 @@ protected Wrapper wrapper = null; +/** + * The index (in the pipeline) of the valve that is processing/will + * process this request. + */ +protected int _stage = 0; + + // - Properties @@ -455,6 +462,26 @@ this.wrapper = wrapper; +} + + +/** + * Set the index of the (next) valve (in the pipeline) that will process + * this request. + * + * @param stage The position of the next valve (in the pipeline) + */ +public void setPipelineStage(int stage) { +_stage = stage; +} + + +/** + * Return the index (in the pipeline) of the valve that is to process + * this request. + */ +public int getPipelineStage() { +return _stage; } Index: catalina/src/share/org/apache/catalina/core/StandardPipeline.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardPipeline.java,v retrieving revision 1.5 diff -u -r1.5 StandardPipeline.java --- catalina/src/share/org/apache/catalina/core/StandardPipeline.java 1 Apr 2002 04:19:54 - 1.5 +++ catalina/src/share/org/apache/catalina/core/StandardPipeline.java 3 Apr 2002 +08:40:02 - @@ -100,12 +100,6 @@ implements Pipeline, Contained, Lifecycle, ValveContext { -// -- Constants - - -protected static final String STATE = pipelineState; - - // --- Constructors @@ -472,8 +466,9 @@ public void invoke(Request request, Response response) throws IOException, ServletException { -// Initialize the per-thread state for this thread -request.setNote(STATE, new PipelineState()); +// Indicate that the first valve in the pipeline should process +// this request +request.setPipelineStage(0); // Invoke the first Valve in this pipeline for this request invokeNext(request, response); @@ -561,10 +556,10 @@ public void invokeNext(Request request, Response response) throws IOException, ServletException { -// Identify the current subscript for the current request thread -PipelineState pipelineState = (PipelineState) request.getNote(STATE); -int subscript = pipelineState.stage; -
[PATCH] TC4.0 - Propagate Embedded's debug level to loaders it creates
Simple patch to o.a.c.startup.Embedded.java to propagate its debug level to Loaders that it creates. Arvind Index: Embedded.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/Embedded.java,v retrieving revision 1.14 diff -u -r1.14 Embedded.java --- Embedded.java 9 Nov 2001 19:40:44 - 1.14 +++ Embedded.java 3 Apr 2002 00:31:28 - @@ -653,6 +653,7 @@ parent + '); WebappLoader loader = new WebappLoader(parent); +loader.setDebug(debug); return (loader); } -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardPipeline.java
Christopher St. John wrote: The obvious implementation is to have have ValveContext hold the index. That's how I assumed it worked the first time I saw the Pipeline, Valve and ValveContext classes. I was suprised to see a ThreadLocal. Using ValveContext has the appropriate threading semantics, and it avoids hiding the index in a mystery attribute in the Request. And, (although none of this will result in a measurable performance gain) using ValveContext to hold the index should be faster, since it avoids a hashtable lookup. Using a Request note is much like using a global variable: it's hidden state. Long term that's bad, for obvious reasons. But isn't a ValveContext (Pipeline) shared across requests ? I think the stage has to be maintained in the Request object. -Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardPipeline.java
Christopher St. John wrote: No, definitely not. Here's how MinTC (MinimalTomcat) does it (this is alpha code, and I've deleted some of the methods to keep the size down): Thanks..I like MinTC's solution. Arvind -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[PATCH] - Make default deployment descriptor file location configurable
This is a patch for RFE# 7564. It allows one to specify/override the location of the default deployment descriptor. Currently, this is hardcoded to 'conf/web.xml' in o.a.c.startup.Constants.java Products that embed the Catalina engine (using Embedded's API) may have a different directory structure and this patch allows one to programmatically specify the location of the default deployment descriptor rather than having to change the value of o.a.c.startup.Constants.defaultWebXml. e.g. StandardContext context = new StandardContext(); ... ... ContextConfig config = new ContextConfig(); config.setDefaultWebXml(/webserver1/config/default-web.xml); ((Lifecycle) context).addLifecycleListener(config); Cheers, Arvind Index: ContextConfig.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/ContextConfig.java,v retrieving revision 1.60 diff -u -r1.60 ContextConfig.java --- ContextConfig.java 14 Mar 2002 23:58:35 - 1.60 +++ ContextConfig.java 28 Mar 2002 09:28:12 - @@ -168,6 +168,12 @@ /** + * The default deployment descriptor location. + */ +private String defaultWebXml = Constants.DefaultWebXml; + + +/** * The string resources for this package. */ private static final StringManager sm = @@ -213,6 +219,28 @@ } +/** + * Return the location of the default deployment descriptor + */ +public String getDefaultWebXml() { + +return (this.defaultWebXml); + +} + + +/** + * Set the location of the default deployment descriptor + * + * @param path Absolute/relative path to the 'default' web.xml + */ +public void setDefaultWebXml(String path) { + +this.defaultWebXml = path; + +} + + // - Public Methods @@ -480,10 +508,10 @@ private void defaultConfig() { // Open the default web.xml file, if it exists -File file = new File(Constants.DefaultWebXml); +File file = new File(this.defaultWebXml); if (!file.isAbsolute()) file = new File(System.getProperty(catalina.base), -Constants.DefaultWebXml); +this.defaultWebXml); FileInputStream stream = null; try { stream = new FileInputStream(file.getCanonicalPath()); Index: ContextConfig.java === RCS file: /home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/ContextConfig.java,v retrieving revision 1.60 diff -u -r1.60 ContextConfig.java --- ContextConfig.java 14 Mar 2002 23:58:35 - 1.60 +++ ContextConfig.java 28 Mar 2002 09:28:12 - @@ -168,6 +168,12 @@ /** + * The default deployment descriptor location. + */ +private String defaultWebXml = Constants.DefaultWebXml; + + +/** * The string resources for this package. */ private static final StringManager sm = @@ -213,6 +219,28 @@ } +/** + * Return the location of the default deployment descriptor + */ +public String getDefaultWebXml() { + +return (this.defaultWebXml); + +} + + +/** + * Set the location of the default deployment descriptor + * + * @param path Absolute/relative path to the 'default' web.xml + */ +public void setDefaultWebXml(String path) { + +this.defaultWebXml = path; + +} + + // - Public Methods @@ -480,10 +508,10 @@ private void defaultConfig() { // Open the default web.xml file, if it exists -File file = new File(Constants.DefaultWebXml); +File file = new File(this.defaultWebXml); if (!file.isAbsolute()) file = new File(System.getProperty(catalina.base), -Constants.DefaultWebXml); +this.defaultWebXml); FileInputStream stream = null; try { stream = new FileInputStream(file.getCanonicalPath()); -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]