RE: Extending Server.xml configurability (for additional classpaths)
I don't understand why you would want this - doesn't the WEB-INF/lib and WEB-INF/classes not already provide seperation of classpaths for the various webapps. Am I missing something? jr I've seen lots of discussion on the user list desiring the ability to have additional classpaths available to web applications, but not necessarily available to all web apps. Ideally, this could be specified in the web.xml file, but that would require changing a spec, and I can think of some arguments against doing so anyway. But, perhaps it would be possible to add classpath specifications in the Server.xml file. Inside a context tag, you could specify something like this: additional-classpath~someuser/somedir/classesadditional-classpath Multiple occurrences of this would just add to the locations where classes can be found. An alternative for us would be to do something with the class loaders in our own web apps, if that's possible, but I'd like to see Tomcat have the functionality. Can someone give me some pointers to get started adding this particular configuration tag? I'd really appreciate it. BTW, I'm currently working with the 4.0b7 codebase. Thanks!
Re: Catalina 4.0-b7 - StandardWrapper.load() - bug?
Hi Craig Thanks for your reply and apologies for the late reply. The goalposts have changed slightly but the problem appears to be the same. I've set up the MBean server environment to create the two classloaders (a la Bootstrap) and when I fire up the server with a Security Manager, I find that the (catalina) loader can find the javax.servlet.Servlet class but the Container Base cannot. servlet.jar is not in any CLASSPATH (save the classloaders). For the simple example .. System.out.println(CatalinaClassLoaders.getCatalinaClassLoader()); System.out.println(CatalinaClassLoaders.getSharedClassLoader()); try { System.out.println(Thread.currentThread().getContextClassLoader().loadClass(javax.servlet.Servlet)); } catch (Exception ex) { ex.printStackTrace(); } Embedded embedded = new Embedded(); Engine engine = embedded.createEngine(); . I get the following output showing the classloaders (including the servlet.jar), the 'javax.servlet.Servlet' interface and then the stacktrace with NoClassDefFoundError: javax/servlet/Servlet Exception ... StandardClassLoader available: delegate: false repositories: file:/export/home/servers/web/jakarta-tomcat-4.0-b7/server/lib/jakarta-regex p-1.2.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/server/lib/crimson.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/server/lib/catalina.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/server/lib/warp.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/server/lib/jaxp.jar required: -- Parent Classloader: StandardClassLoader available: delegate: false repositories: file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/servlet.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/naming.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/resources.jar required: -- Parent Classloader: sun.misc.Launcher$AppClassLoader@2c3c08 StandardClassLoader available: delegate: false repositories: file:/export/home/servers/web/jakarta-tomcat-4.0-b7/lib/namingfactory.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/lib/jasper-runtime.jar required: -- Parent Classloader: StandardClassLoader available: delegate: false repositories: file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/servlet.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/naming.jar file:/export/home/servers/web/jakarta-tomcat-4.0-b7/common/lib/resources.jar required: -- Parent Classloader: sun.misc.Launcher$AppClassLoader@2c3c08 interface javax.servlet.Servlet Exception in thread main java.lang.NoClassDefFoundError: javax/servlet/Servlet Exception at org.apache.catalina.core.ContainerBase.init(ContainerBase.java:254) at org.apache.catalina.core.StandardEngine.init(StandardEngine.java:10 4) at org.apache.catalina.startup.Embedded.createEngine(Embedded.java:577) at com.syntactics.server.management.catalina.Bootstrap.init(Bootstrap. java:191) at com.syntactics.server.management.catalina.Bootstrap$1.run(Bootstrap.j ava:61) at java.security.AccessController.doPrivileged(Native Method) at com.syntactics.server.management.catalina.Bootstrap.main(Bootstrap.ja va:58) this code is running in class driven by a PrivilegedAction. Getting this to work with MBeans and a Security Manager is turning out to be quite tricky! Cheers Nick On Wed, 22 Aug 2001, Nick Betteridge wrote: javax.servlet.ServletException: Class org.apache.jasper.servlet.JspServlet is not a Servlet The only time I've seen this kind of thing happen is when servlet.jar is loaded from the wrong class loader -- it needs to be visible to both Catalina internal classes *and* web apps. In the usual stand-alone configuration, this is accomplished by putting servlet.jar into the $CATALINA_HOME/common/lib directory. Also, make sure servlet.jar is *not* in your Java system extensions directory ($JAVA_HOME/jre/lib/ext) or on the CLASSPATH. Could you double check to see if any of those issues might be the problem? Nick Craig
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/testHeader.java HttpRequest.java
| This has nothing to do with tomcat accepting Chunked encoding on the | request - we did few fixes but this hasn't been tested yet, I believe | there are few changes in mod_jk we still have to do. | Almost done... Keith
JSP buffer=none not working
I want immediate response to a browser as information becomes available so I sent buffer=none i.e.: %@ page buffer=none % I have loop using a scriptlet where information should be displayed but nothing shows at the browser. Is their a way to force a flush from a JSP. I've done this with CGI and PERL and it works great any ideas? Thanks, Joe Knudsen Optical Solutions Network Management Developer Email: [EMAIL PROTECTED]
Bug in tag lib implementation
Hi, According to my interpretation of the JSP 1.1 spec, the following code should be legal. I've changed the name of the tag from foo to foo.test. Page 99 of the spec states that name can be any NMTOKEN. Since foo.test is a NMTOKEN it should be a legal name. I think this is the same as bug #3019. I've tested this on Tomcat 3.2.3, 3.3, and 4.0b7. They all throw exception similiar to the one below. It appears that the problem is that the tag name is concatenated with some other text to created varible names in the generated JSP without checking the name for illegal variable name characters and replacing them. Is my interpretation of the spec correct? Has this problem been fixed already? How can I submit a fix to the problem that my co-worker has come up with? What version of tomcat will such a fix be accepted for? Thanks, Jin ---updated example-taglib.tld !-- A simple Tag -- !-- foo tag -- tag namefoo.test/name tagclassexamples.FooTag/tagclass teiclassexamples.FooTagExtraInfo/teiclass bodycontentJSP/bodycontent info Perform a server side action; uses 3 mandatory attributes /info - updated foo.jsp from examples -- html !-- Copyright (c) 1999 The Apache Software Foundation. All rights reserved. -- body %@ taglib uri=http://java.apache.org/tomcat/examples-taglib; prefix=eg % Radio stations that rock: ul eg:foo.test att1=98.5 att2=92.3 att3=107.7 li%= member %/li /eg:foo.test /ul - exception seen in the browser -- Error: 500 Location: /examples/jsp/simpletag/foo.jsp Internal Servlet Error: org.apache.jasper.JasperException: Unable to compile class for JSPD:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002f jsp_0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:65: Invalid declaration. examples.FooTag _jspx_th_eg_foo.test_0 = new examples.FooTag(); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:66: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setPageContext(pageContext); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:67: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setParent(null); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:68: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt1(98.5); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:69: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt2(92.3); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:70: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt3(107.7); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:72: Invalid declaration. int _jspx_eval_eg_foo.test_0 = _jspx_th_eg_foo.test_0.doStartTag(); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:73: Undefined variable or class name: _jspx_eval_eg_foo if (_jspx_eval_eg_foo.test_0 == Tag.EVAL_BODY_INCLUDE) ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:75: Undefined variable or class name: _jspx_eval_eg_foo if (_jspx_eval_eg_foo.test_0 != Tag.SKIP_BODY) { ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:77: Undefined variable or class name: _jspx_eval_eg_foo if (_jspx_eval_eg_foo.test_0 != Tag.EVAL_BODY_INCLUDE) { ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:79: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setBodyContent((BodyContent) out); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:81: Undefined variable, class, or package name: _jspx_th_eg_foo
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/testHeader.java HttpRequest.java
For whatever it's worth, here are some changes I made to the 3.2.2 code base to add support for chunked requests. I just did the work a few days ago and am still in the process of moving them to 3.3. Still, since the topic came up now I thought it would be helpful to share my approach. I have been running some heavy stress tests on this and have not seen any problems yet. It would be great to run the changes through some unit tests as well. The changes are in Ajp13ConnectorRequest.java, jk_ajp13_worker.c, and a minor change to mod_jk.c. The key change in Ajp13ConnectorRequest.java is not to set a limit on the BufferedServletInputStream when there is no Content-Length. On key change in jk_ajp13_worker.c was to add a read buffer to the ajp13_endpoint struct. This was needed to ensure that calls to ap_get_client_block() (via the service's read() function) will always ask for a fixed amount. Without this, you can end up calling read_client_block() with a buffer that is too small and it will return an error. This is due to ap_get_client_block() requiring a buffer size large enough to hold a chunk-size line. In mod_jk.c, I made a simple change to avoid possible cross platform issues due to assigning a long to an unsigned. I welcome any questions or comments about this approach. Hopefully, I have presented the changes in a way that makes sense. If not, I'll be happy to take suggestions about how to make the changes easier to understand. -David Here are the changes: In Ajp13ConnectorRequest.java $Revision: 1.5.2.7 234c234,235 ((BufferedServletInputStream)this.in).setLimit(contentLength); --- 236,244c237,246 /* Read present data */ int err = con.receive(msg); if(err 0) { return -1; } blen = msg.peekInt(); msg.getBytes(bodyBuff); } --- ((BufferedServletInputStream)this.in).setLimit(contentLength); } /* Read present data */ int err = con.receive(msg); if(err 0) { return -1; } blen = msg.peekInt(); msg.getBytes(bodyBuff); 306,311c308,313 MsgBuffer msg = con.getMsgBuffer(); msg.appendByte(JK_AJP13_GET_BODY_CHUNK); msg.appendInt(MAX_READ_SIZE); con.send(msg); int err = con.receive(msg); --- MsgBuffer msg = con.getMsgBuffer(); msg.appendByte(JK_AJP13_GET_BODY_CHUNK); msg.appendInt(MAX_READ_SIZE); con.send(msg); int err = con.receive(msg); 313,314c315,316 throw new IOException(); } --- throw new IOException(); } 317,319c319,325 pos = 0; msg.getBytes(bodyBuff); --- if (blen 0) { pos = 0; msg.getBytes(bodyBuff); } else { pos = 0; msg.getBytes(bodyBuff); } In jk_ajp13_worker.c $Revision: 1.3.2.2 111c111,117 unsigned left_bytes_to_send; --- int left_bytes_to_send; int had_content_length; unsigned char readbuf[READ_BUF_SIZE]; unsigned left; unsigned int current; 116c122,124 ep-reuse = JK_FALSE; --- ep-reuse = JK_FALSE; ep-left = 0; ep-current = 0; 236c244,246 static int read_fully_from_server(jk_ws_service_t *s, --- static int read_fully_from_server(ajp13_endpoint_t *ep, jk_ws_service_t *s, 238c248,249 unsigned len) --- unsigned len, jk_logger_t *l) 240a252 unsigned this_time; 243,245c255,261 unsigned this_time = 0; if(!s-read(s, buf + rdlen, len - rdlen, this_time)) { return -1; --- if (ep-left = 0) { if(!s-read(s, ep-readbuf, (unsigned)READ_BUF_SIZE, (ep-left))) { jk_log(l, JK_LOG_DEBUG, read_fully says -1\n); return -1; } ep-current = 0; 247a264,268 this_time = (ep-left (len - rdlen)) ? ep-left : (len-rdlen); memcpy(buf+rdlen, (ep-readbuf)+ep-current, this_time); ep-left -= this_time; ep-current += this_time; 249c270 break; --- break; 251c272,274 rdlen += this_time; --- rdlen += this_time; 264c287 --- int just_got = 0; 270c293,297 if(read_fully_from_server(r, read_buf, len) 0) { --- if((just_got = read_fully_from_server(ep, r, read_buf, len, l)) 0) { if (ep-had_content_length == 0) { ep-left_bytes_to_send = -1; return JK_TRUE; } else { 273c300,301 return JK_FALSE; --- return JK_FALSE; } 276c304,307 ep-left_bytes_to_send -= len; --- if ((ep-had_content_length == 0) (just_got != len)) {
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/testHeader.java HttpRequest.java
Heh, you beat me to it. I'd like to compare notes. Can you resend the diff with -u -b? Keith | -Original Message- | From: Schreibman, David [mailto:[EMAIL PROTECTED]] | Sent: Tuesday, August 28, 2001 11:17 AM | To: '[EMAIL PROTECTED]' | Subject: RE: cvs commit: | jakarta-tomcat/src/share/org/apache/tomcat/util/testHeader.java | HttpRequest.java | | | For whatever it's worth, here are some changes I made to the 3.2.2 code base | to add support for chunked requests. I just did the work a few days ago and | am still in the process of moving them to 3.3. Still, since the topic came
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/testHeader.java HttpRequest.java
Sure. Here are the diffs again with -u -b. -David --- Ajp13ConnectorRequest.orig Tue Aug 28 07:16:10 2001 +++ Ajp13ConnectorRequest.java Tue Aug 28 07:43:54 2001 @@ -231,8 +231,11 @@ contentLength = headers.getIntHeader(content-length); contentType = headers.getHeader(content-type); - ((BufferedServletInputStream)this.in).setLimit(contentLength); + + if(contentLength 0) { + ((BufferedServletInputStream)this.in).setLimit(contentLength); + } /* Read present data */ int err = con.receive(msg); if(err 0) { @@ -241,7 +244,6 @@ blen = msg.peekInt(); msg.getBytes(bodyBuff); - } return 0; } @@ -314,9 +316,13 @@ } blen = msg.peekInt(); +if (blen 0) { pos = 0; msg.getBytes(bodyBuff); - + } else { + pos = 0; + msg.getBytes(bodyBuff); + } return (blen 0); } } --- jk_ajp13_worker.origThu Jan 4 18:39:26 2001 +++ jk_ajp13_worker.c Tue Aug 28 07:12:35 2001 @@ -108,12 +108,20 @@ int reuse; jk_endpoint_t endpoint; -unsigned left_bytes_to_send; +int left_bytes_to_send; +int had_content_length; + +unsigned char readbuf[READ_BUF_SIZE]; +unsigned left; +unsigned int current; + }; static void reset_endpoint(ajp13_endpoint_t *ep) { ep-reuse = JK_FALSE; +ep-left = 0; +ep-current = 0; jk_reset_pool((ep-pool)); } @@ -233,22 +241,37 @@ return JK_TRUE; } -static int read_fully_from_server(jk_ws_service_t *s, + +static int read_fully_from_server(ajp13_endpoint_t *ep, + jk_ws_service_t *s, unsigned char *buf, - unsigned len) + unsigned len, + jk_logger_t *l) { unsigned rdlen = 0; +unsigned this_time; while(rdlen len) { -unsigned this_time = 0; -if(!s-read(s, buf + rdlen, len - rdlen, this_time)) { + +if (ep-left = 0) { +if(!s-read(s, ep-readbuf, (unsigned)READ_BUF_SIZE, (ep-left))) { + jk_log(l, JK_LOG_DEBUG, read_fully says -1\n); return -1; } + ep-current = 0; +} + +this_time = (ep-left (len - rdlen)) ? ep-left : (len-rdlen); + memcpy(buf+rdlen, (ep-readbuf)+ep-current, this_time); + ep-left -= this_time; + ep-current += this_time; if(0 == this_time) { break; } + rdlen += this_time; + } return (int)rdlen; @@ -261,19 +284,27 @@ unsigned len) { unsigned char *read_buf = jk_b_get_buff(msg); - +int just_got = 0; jk_b_reset(msg); read_buf += 4; /* leave some space for the buffer headers */ read_buf += 2; /* leave some space for the read length */ -if(read_fully_from_server(r, read_buf, len) 0) { +if((just_got = read_fully_from_server(ep, r, read_buf, len, l)) 0) { + if (ep-had_content_length == 0) { + ep-left_bytes_to_send = -1; + return JK_TRUE; + } else { jk_log(l, JK_LOG_ERROR, read_into_msg_buff: Error - read_fully_from_server failed\n); return JK_FALSE; } +} -ep-left_bytes_to_send -= len; +if ((ep-had_content_length == 0) (just_got != len)) { + ep-left_bytes_to_send = -1;/* we are done */ + len = just_got; +} if(0 != jk_b_append_int(msg, (unsigned short)len)) { jk_log(l, JK_LOG_ERROR, @@ -333,12 +364,21 @@ { unsigned len = (unsigned)jk_b_get_int(msg); + if (ep-left_bytes_to_send 0) { +read_into_msg_buff(ep, r, msg, l, 0); + return JK_AJP13_HAS_RESPONSE; + } + if(len MAX_SEND_BODY_SZ) { len = MAX_SEND_BODY_SZ; } + + if (ep-had_content_length) { if(len ep-left_bytes_to_send) { len = ep-left_bytes_to_send; } + } + if(len 0) { len = 0; } @@ -545,7 +585,13 @@ jk_b_set_buffer_size( msg, DEF_BUFFER_SZ); jk_b_reset(msg); +if (s-content_length 0) { + p-had_content_length = 1; p-left_bytes_to_send = s-content_length; +} else { + p-had_content_length = 0; + p-left_bytes_to_send = MAX_SEND_BODY_SZ; + } p-reuse = JK_FALSE; *is_recoverable_error = JK_TRUE; @@ -595,7 +641,6 @@ */ *is_recoverable_error = JK_FALSE; - if(p-left_bytes_to_send 0) { unsigned len = p-left_bytes_to_send; if(len
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/test Header.java HttpRequest.java
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/test/ HttpRequest.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- HttpRequest.java 2001/02/20 03:14:12 1.3 +++ HttpRequest.java 2001/08/28 05:46:28 1.4 @@ -320,7 +320,8 @@ if( v!=null) sb.append(v); } } -sb.append( ).append(protocol); +// sb.append( ).append(protocol); +sb.append( ).append(HTTP/1.0); // only http1.0 for now on request requestLine=sb.toString(); } When HTTP/1.0 is missing, client is consider HTTP/0.9 not 1.1 ?
Jasper optimizations
I'm working on a product that is heavily based on a JSP tag library which lets developers write their pages using JSP tags only. The result is JSP pages that make heavy use of nested JSP tags, some of which implement iteration. One of the most complex pages we have takes about 6 seconds to run in Tomcat 3.2, while in Resin it runs in 0.06 seconds. We believe the cause of this to be the way Tomcat (that is, Jasper) generates the JSP servlet Java code. Every time a tag is executed the following actions are performed: 1. a new tag instance is instantiated 2. the new instance is configured (set*() methods called) 3. the tag is executed Jasper now has a setting that allows us to not repeat step #1 every time a tag is executed, which brought page execution down to 3 seconds (from the original 6), but this still isn't good enough for our purposes. In my opinion, it is also necessary to be able to not repeat step #2 every time a tag is executed. If we can avoid this we save an awful lot of method calls, and our tag implementations can also perform a number of costly operations at creation-time, which they then won't have to repeat every time they are executed. I expect that with this change our execution times will be more reasonable. As far as I can tell, the only way to get rid of step #2 is to modify Jasper. I've looked at the source code, and I think I see a way to do this with the sources on the MAIN branch. (BTW, is that the latest and greatest version of Jasper?) The current approach with a tree of generators makes this difficult, and the resulting Java code will be ugly, but it can be done. When Jasper is rewritten to use visitors this can be done much prettier. Basically, my idea is to generate code like this for each tag: ClassName variable = taghash.get(variable); // [1] if (variable == null) { variable = new ClassName(); taghash.put(variable, variable); // do the setters here } // execute tag in the usual way Before I start I would like to know: - is anyone else working on this already? is there some way to achieve this already? - which version of the Jasper sources should I be working on? the MAIN branch? - what do people think of my proposed solution? I know it is not very nice, but as long as the code has to be generated from within the current generators, which are called the way they are, I don't see any better alternative. - if I do make this change, what are the chances that it will be accepted into the Jasper sources? - if I do make this change, what version of Tomcat could the modified Jasper become part of? --Lars M. [1] I've noticed that the Jasper sources seem to use 1.1 collections, instead of the 1.2 collections. Is that on purpose?
Re: Addition of 'dirty' field to Session interface
--- Carlos Gaston Alvarez [EMAIL PROTECTED] We have an instance of the database to store the sessions. What does the database mean? If we're persisting the sessions to a real RDBMS, then that's a serious performance hit above and beyond just having to serialize the session whenever it's accessed. Not to mention that the user would have to add DB config info into the TC config. An alternate implementation would be to maintain this data in memory using a similar table-like object. When sessions are created/modified, you broadcast the changes on a multicast address. All other interested servlet engines can pick up this change and replicate it locally. This could conceivably be done using the Servlet 2.3 HttpSessionAttributeListener interface, and could also provide transparent failover for distributed sessions. Persistence to a database really only makes sense if you're dealing with MANY sessions (or perhaps many long-lived sessions) and you need an activate/passivate behavior to conserve memory. Session creation is a litle tricky because be should get sure that no other virtual machine is trying to create the same session (for the same user) and if so syncronize them. Well, there's really not much you can do about this. This situation would occur if the same browser accessed two different servlets simultaneously. For cookie-based sessions, the browser would get the session id for whichever servlet sent the cookie last. For url-rewriting based sessions, you'd have two different sessions started. I think this situation is sufficiently rare to not worry about. On every request: - get the lock sessionLocker (check if the locker is 0, if it is we take it; if it is not we wait until the locker is 0 try again). [sessionLocker = me] - check if it is the same sessionVersion. - if yes just use the session at memory. (why unserilize it if we can have them in memory?). - if not get the session of the database (sessionStream) and unserialize it. * now the user request runs as normal, until it is finished when .. - sessionVersion++ - sessionStream gets updated. - sessionLocker = 0 There are other optimizations but I will not discuss them now not to make a mess. A simple optimization: you mention above On every request... but really it is only On every request that calls getSession because if the servlet never accesses the session, we don't need to worry about it changing. So the pre-request stuff you mention above should really be done when getSession is called, and the post-request stuff should be done after the request is completed, but only if getSession was called during the request. All of this points to a solution presented much earlier in this thread - that any time the session is accessed we have to consider it dirty. The more I think about this the more it makes sense - you *really* don't want the developer to have to keep track of whether or not the session is dirty. Finally, this is a lot of extra processing to do if the web app is only run on a single machine. Perhaps a directive in the server.xml could indicate whether sessions should be shared/synchronized across multiple servlet engines or not. - osama. __ Do You Yahoo!? Make international calls for as low as $.04/minute with Yahoo! Messenger http://phonecard.yahoo.com/
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader WebappClassLoader.java
remm01/08/28 11:12:37 Modified:catalina/src/share/org/apache/catalina/loader WebappClassLoader.java Log: - Sync before calling defineClass. Appears to fix bug 3107, and should also help similar CL problems where two threads simultaneously try to load the same class. Revision ChangesPath 1.13 +8 -6 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java Index: WebappClassLoader.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- WebappClassLoader.java2001/07/31 00:30:28 1.12 +++ WebappClassLoader.java2001/08/28 18:12:37 1.13 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v 1.12 2001/07/31 00:30:28 remm Exp $ - * $Revision: 1.12 $ - * $Date: 2001/07/31 00:30:28 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v 1.13 2001/08/28 18:12:37 remm Exp $ + * $Revision: 1.13 $ + * $Date: 2001/08/28 18:12:37 $ * * * @@ -123,7 +123,7 @@ * * @author Remy Maucherat * @author Craig R. McClanahan - * @version $Revision: 1.12 $ $Date: 2001/07/31 00:30:28 $ + * @version $Revision: 1.13 $ $Date: 2001/08/28 18:12:37 $ */ public class WebappClassLoader extends URLClassLoader @@ -1481,8 +1481,10 @@ } -clazz = defineClass(name, entry.binaryContent, 0, -entry.binaryContent.length, codeSource); +synchronized(this) { +clazz = defineClass(name, entry.binaryContent, 0, +entry.binaryContent.length, codeSource); +} entry.loadedClass = clazz;
RE: Extending Server.xml configurability (for additional classpat hs)
Wouldn't it be better to use META-INF/MANIFEST.MF to specify additional classpath information via the Class-Path: manifest header in a .war archive. I know disk space is cheap and it isn't a problem to copy jars to multiple locations, but it does make version control and updates of jars kind of a pain. Using the Class-Path: manifest header allows a system administrator to keep jars in a central place for easy control, while at the same time maintaining the compartmentalization of classpath space that you get with the web application class loader. It would be easy enough to extend the web app class loader to parse out the Class-Path: headers in any META-INF/MANIFEST.MF files it finds in its repository directories and/or jars/zips. If I have time, I will look at the source tonight and see if I can't whip up a patch ... It seems to me that using existing classpath extension mechanisms is better than adding a non-spec extension to server.xml ... -Doug Seifert -Original Message- From: Reilly, John [mailto:[EMAIL PROTECTED]] Sent: Tuesday, August 28, 2001 2:14 AM To: '[EMAIL PROTECTED]' Subject: RE: Extending Server.xml configurability (for additional classpat hs) I don't understand why you would want this - doesn't the WEB-INF/lib and WEB-INF/classes not already provide seperation of classpaths for the various webapps. Am I missing something? jr I've seen lots of discussion on the user list desiring the ability to have additional classpaths available to web applications, but not necessarily available to all web apps. Ideally, this could be specified in the web.xml file, but that would require changing a spec, and I can think of some arguments against doing so anyway. But, perhaps it would be possible to add classpath specifications in the Server.xml file. Inside a context tag, you could specify something like this: additional-classpath~someuser/somedir/classesadditional-classpath Multiple occurrences of this would just add to the locations where classes can be found. An alternative for us would be to do something with the class loaders in our own web apps, if that's possible, but I'd like to see Tomcat have the functionality. Can someone give me some pointers to get started adding this particular configuration tag? I'd really appreciate it. BTW, I'm currently working with the 4.0b7 codebase. Thanks!
Re: Jasper optimizations
Hi Lars, As far as I can tell, the only way to get rid of step #2 is to modify Jasper. I've looked at the source code, and I think I see a way to do this with the sources on the MAIN branch. (BTW, is that the latest and greatest version of Jasper?) The current approach with a tree of generators makes this difficult, and the resulting Java code will be ugly, but it can be done. When Jasper is rewritten to use visitors this can be done much prettier. We started a major refactoring of jasper in jakarta-tomcat-jasper directory. I'm working on it - probably next week I'll do another commit with the first part of the migration to SAX-based, which is the first step to add JSP1.2 features and cleans up even more. We had many discussion on this, the visitor pattern is on the TODO list, as well as improving the modularity. There are some issues we don't agree on ( i.e. the use of XSLT to generate code, cocoon-style ), so I'll do this later and in a separate module ( that will not be required for normal operation ). Probably in 2-3 weeks things will start to move much faster there, after 3.3 is released I'll have more time, and things start to look pretty clean. - is anyone else working on this already? is there some way to achieve this already? Yes, No. - which version of the Jasper sources should I be working on? the MAIN branch? I would sugest jakarta-tomcat-jasper, the MAIN branch is frozen, it's very unlikely we'll do anything else in 3.3 jasper. Jasper34 will be a module you can use to 'upgrade' jasper in 3.3. - what do people think of my proposed solution? I know it is not very nice, but as long as the code has to be generated from within the current generators, which are called the way they are, I don't see any better alternative. It seems some other people are working on that, I've got a sugestion to set all the constant fields when the tag is created ( including parent, etc) - that implies caching the whole tag set per page. It makes sense - but it needs few more changes. - if I do make this change, what are the chances that it will be accepted into the Jasper sources? For 3.3 - I don't think so. For j-t-j/jasper34 - certainly. [1] I've noticed that the Jasper sources seem to use 1.1 collections, instead of the 1.2 collections. Is that on purpose? For the main branch ( 3.2 and 3.3 ) - yes, it has to be backward compatible with 1.1. For j-t-c/jasper34: there is no such requirement for the compiler. I would like to keep the runtime 1.1 compatible - but if someone doesn't like that it's fine, we already added support for 'plugable' runtime. Costin
Re: Extending Server.xml configurability (for additionalclasspaths)
on 8/28/01 2:13 AM, Reilly, John at [EMAIL PROTECTED] wrote: I don't understand why you would want this - doesn't the WEB-INF/lib and WEB-INF/classes not already provide seperation of classpaths for the various webapps. Am I missing something? Well, I need to share a class tree and/or .jar files among a handful of separate contexts. The currently available options are not really sufficient for my needs: 1. I can copy the classes/.jar files to each context's WEB-INF directory. 2. I can add a separate directory containing my classes and add that directory to the environment's CLASSPATH (this has, so far, not worked). I really want to be able to take a stock installation of Tomcat, add our Server.xml file and context directories, and start the server. Solution (1) makes version control difficult (as Douglas notes below), and Solution (2), aside from not working yet for me, means scripts have to be changed, and is possibly different for different platforms. on 8/28/01 11:51 AM, Douglas Seifert at [EMAIL PROTECTED] wrote: Wouldn't it be better to use META-INF/MANIFEST.MF to specify additional classpath information via the Class-Path: manifest header in a .war archive. I know disk space is cheap and it isn't a problem to copy jars to multiple locations, but it does make version control and updates of jars kind of a pain. Using the Class-Path: manifest header allows a system administrator to keep jars in a central place for easy control, while at the same time maintaining the compartmentalization of classpath space that you get with the web application class loader. It would be easy enough to extend the web app class loader to parse out the Class-Path: headers in any META-INF/MANIFEST.MF files it finds in its repository directories and/or jars/zips. If I have time, I will look at the source tonight and see if I can't whip up a patch ... It seems to me that using existing classpath extension mechanisms is better than adding a non-spec extension to server.xml ... Ideally, I'd be able to specify additional class paths in the web.xml file, but that requires changing a spec. However, I was under the impression that the server.xml file was defined by Tomcat, and so could be extended. Using the manifest might be an acceptable solution; I didn't know about that. However, I have these questions: 1) can the manifest be placed in an open or expanded .war archive (I'm not sure of the terminology; whatever it is where have separate folders, rather than a single .war file). 2) can this manifest be easily edited to add/change/remove class paths (i.e. with a regular text editor)? I'm not 100% sure that extending the web.xml file or using the manifest are necessarily the best places for this, because it means that a context can extend its reach, so to speak, without intervention from anyone else. This is potentially a security risk, since someone might install a webapp without considering what it might touch. If the control of additional classpaths is placed within the context's dir contents, perhaps a flag in the Server.xml file indicating that a context is allowed to extend its reach should be considered as well. Thanks, Douglas, for looking into this for me. I really appreciate it. Roderick Mann rmann @ latencyzero.com.sansspam
RE: Extending Server.xml configurability (for additional classpaths)
Rick, For a description of the MANIFEST.MF file format, look here: http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html Since a .war file is kind of a jar, I don't see any reason not to adopt the META-INF/MANIFEST.MF Class-Path: extension mechanism, unless it is specifically prohibited by the spec. 1) can the manifest be placed in an open or expanded .war archive (I'm not sure of the terminology; whatever it is where have separate folders, rather than a single .war file). That would be a requirement, yes. The WebAppClassloader should look for META-INF/MANIFEST.MF files in unexpanded .war files as well as expanded ones. Ideally, it should not only look at the web app's META-INF/MANIFEST.MF, but also the META-INF/MANIFEST.MF of any jars in WEB-INF/lib. This could also be done recursively if you want to get fanatical about it. 2) can this manifest be easily edited to add/change/remove class paths (i.e. with a regular text editor)? It is a simple properties file, so, yes, a text editor can handle it. -Doug
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java
-Original Message- From: Schreibman, David [mailto:[EMAIL PROTECTED]] Sent: Tuesday, August 28, 2001 5:17 PM To: '[EMAIL PROTECTED]' Subject: RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java For whatever it's worth, here are some changes I made to the 3.2.2 code base to add support for chunked requests. I just did the work a few days ago and am still in the process of moving them to 3.3. Still, since the topic came up now I thought it would be helpful to share my approach. I have been running some heavy stress tests on this and have not seen any problems yet. It would be great to run the changes through some unit tests as well. You may have noticed that mod_jk in TC 3.3 is different from the one in TC 3.2. Also Ajp13 in Tomcat 3.3 (java) is also different since using directly InputStream. And mod_jk in jakarta-tomcat-connectors is also very different since there was some refactoring. From what I saw it seems you're on the right way, and I'm waiting to see your port to TC 3.3. Or if you like, I could try to port it to both 3.3 and J-T-C. I've got many questions here and some refactory should be done on that part of the code later, I don't like very much the way the communication is done. May be something to rewrite completly to Ajp14, adding others new commands (CHUNKED-DATA). The goal will be to have a simpler (and so fastest) way to do the transfert. Questions : - Does the java part need to know that the incoming data came in CHUNKED ? - Should we add others HTTP/1.1 commands like Range, Accept-Ranges, CONNECT ? What do you think about that ?
Re: Jasper optimizations
Hi there, * [EMAIL PROTECTED] | | I'm working on it - probably next week I'll do another commit with | the first part of the migration to SAX-based, which is the first | step to add JSP1.2 features and cleans up even more. Does this mean that you intend to completely separate parsing, tree building, tree representation, and code generation, and to have a SAX interface between the first two? If so, I think that makes a lot of sense. | We had many discussion on this, the visitor pattern is on the TODO | list, as well as improving the modularity. There are some issues we | don't agree on ( i.e. the use of XSLT to generate code, cocoon-style Use XSLT to generate the code? I can see why you wouldn't want to do that. | I would sugest jakarta-tomcat-jasper, the MAIN branch is frozen, | it's very unlikely we'll do anything else in 3.3 jasper. Uh, you'll have to go slowly here, I'm afraid. I'm not at all familiar with the Tomcat sources. So the MAIN branch in jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/ is where Jasper development is done right now? | Jasper34 will be a module you can use to 'upgrade' jasper in 3.3. Does this mean that there is a Jasper version somewhere else that goes into Tomcat 3.3, and that the version I referred to above is what you call Jasper34? Also, you plan to make this interface-compatible with the Jasper in Tomcat 3.3? * Lars Marius Garshol | | - what do people think of my proposed solution? I know it is not |very nice, but as long as the code has to be generated from within |the current generators, which are called the way they are, I don't |see any better alternative. * [EMAIL PROTECTED] | | It seems some other people are working on that, Would these other people be Niko Schmuck? If so, he and I are working in the same company, on the same project. If not, would be possible to get in contact with them somehow, and find out what their plans are? | I've got a sugestion to set all the constant fields when the tag is | created ( including parent, etc) - that implies caching the whole | tag set per page. This is also what I had in mind, but as far as I can tell, it is not exactly straightforward to make the current code generate variable declarations in class scope for each tag, and then afterwards generate the code that uses those variables. | It makes sense - but it needs few more changes. What changes? A redesign of the generator to use visitors? Or were you thinking of something else? * Lars Marius Garshol | | - if I do make this change, what are the chances that it will be |accepted into the Jasper sources? * [EMAIL PROTECTED] | | For 3.3 - I don't think so. | | For j-t-j/jasper34 - certainly. OK, that's useful to know. In that case I have an another question. I am working on a product that needs to run with reasonable efficiency within Tomcat, and so I need to a have a version of Tomcat where this runs fast enough by October 1st. What would you recommend that I do? Can I expect this optimization to be in a stable version of Jasper 3.4 by then? Is there anything I can do to make sure that it will be? Also, where can I find the version of Jasper that is in Tomcat 3.3? In the worst case I may have to add a temporary hack to that to make our product perform. * [EMAIL PROTECTED] | | For j-t-c/jasper34: there is no such requirement for the compiler. I | would like to keep the runtime 1.1 compatible - but if someone | doesn't like that it's fine, we already added support for 'plugable' | runtime. No problem for me. I'm happy to write 1.1-compatible code as long as I know that is a deliberate policy. --Lars M.
Re: Jasper optimizations
On 28 Aug 2001, Lars Marius Garshol wrote: | I'm working on it - probably next week I'll do another commit with | the first part of the migration to SAX-based, which is the first | step to add JSP1.2 features and cleans up even more. Does this mean that you intend to completely separate parsing, tree building, tree representation, and code generation, and to have a SAX interface between the first two? Parsing JSP syntax ( org.apache.jasper34.parser ) will behave as a SAX parser, and generate SAX events to generator ( almost identical with what XML syntax will generate - the big difference is that we'll generate the static content as CDATA, instead of parsing it as XML ). This is part of adding support for XML syntax ( and merge 1.2 features ), part of cleaning up the interfaces between components, will be needed later in order to add support for XSLT, etc. Tree representation is still one big issue - I don't know what's the best for that, so I'll keep the current model ( tree of Generators ) until I ( or someone else ) have a better idea. ( well, I have some idea, but I'm not ready to fight for it) | We had many discussion on this, the visitor pattern is on the TODO | list, as well as improving the modularity. There are some issues we | don't agree on ( i.e. the use of XSLT to generate code, cocoon-style Use XSLT to generate the code? I can see why you wouldn't want to do that. So do believe many other people, and that's why it'll not be required or part of 'normal' processing. The benefit of modularity is that crazy people like me can still do what they believe to be right. Again, I don't want to reopen this debate - it's clear people don't want that, so it'll not be in jasper34, but some external add-on. Uh, you'll have to go slowly here, I'm afraid. I'm not at all familiar with the Tomcat sources. So the MAIN branch in jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/ is where Jasper development is done right now? That's where most of the optimizations and refactoring is done. In jakarta-tomcat we have only major bug fixes right now. | Jasper34 will be a module you can use to 'upgrade' jasper in 3.3. Does this mean that there is a Jasper version somewhere else that goes into Tomcat 3.3, and that the version I referred to above is what you call Jasper34? Also, you plan to make this interface-compatible with the Jasper in Tomcat 3.3? What is in jakarta-tomcat/src/share/org/apache/jasper goes into tomcat3.3, and it is what we consider 'stable' ( and frozen ). What is in jakarat-tomcat-jasper/jasper34 is a development version, with quite a few improvements and some bug fixes that couldn't go into the 'stable' branch ( because we didn't want to destabilize it ). About 'interface-compatible' - I don't think so, first of all there is no 'interface' in 3.3, and the main goal is to actually reorganize the code so it could be 'interfaced'. jasper34.core will contain a set of base classes that could be used to extend and plug the generator into different containers. What would you recommend that I do? Can I expect this optimization to be in a stable version of Jasper 3.4 by then? Is there anything I can do to make sure that it will be? Right now jasper34 is reasonably stable ( i.e. it passes all the tests, and seems to be fine ) - however keep in mind it is the development version. I'm holding back most of my changes ( SAX, etc ) until I get them stable enough - I want to keep the 'evolution' as smooth as possible. But I don't think 3.4 will be production ready any time soon - I have very limited amount of free time, and few weeks of Sept will certainly go to finish 3.3, and I also want to do some enhancements in j-t-c - I spend 3-4 hours a week on jasper34. End of september ( and anything after 3.3 is out ) will be much better, but Oct 1 is far too tight. If you get the problem solved ( i.e. have something that works and passes all tests ) - it can certainly go into 3.4, and we could have a 'milestone'. Again, I'm doing my best to keep it stable - but refactoring can introduce bugs, optimization can introduce bugs, etc. Also, where can I find the version of Jasper that is in Tomcat 3.3? In the worst case I may have to add a temporary hack to that to make our product perform. I don't know... Most likely your changes will be in the TagPoolGenerator, and if you do that in 3.3 ( jakarta-tomcat/src/share/org/apache/jasper), it'll be easy to port in jasper34. Most of the changes are now in the general architecture, not in individual generators. So it shouldn't matter - you could play it safe, and hack 3.3 ( knowing the code will not get into the main branch ! ) for your needs, and port the changes to jasper34. There are other optimizations going on in 3.4 that might help you as well. Costin
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java
Since I'm going to need support for chunked requests in 3.3 anyway, I'm going ahead with the port of my 3.2.2 changes. I hope to have it in a couple of days. Questions : - Does the java part need to know that the incoming data came in CHUNKED ? The Java side can figure it out if the Content-Length is not set. Still, the Content-Length might be set even when the transfer was chunked. Not sure how much value would be added in knowing this explicitly. - Should we add others HTTP/1.1 commands like Range, Accept-Ranges, CONNECT ? I suppose these could be helpful but I haven't thought too much about it. In general, it seems like a good idea to leverage as much as possible from the transport. -David -Original Message- From: Schreibman, David [mailto:[EMAIL PROTECTED]] Sent: Tuesday, August 28, 2001 5:17 PM To: '[EMAIL PROTECTED]' Subject: RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java For whatever it's worth, here are some changes I made to the 3.2.2 code base to add support for chunked requests. I just did the work a few days ago and am still in the process of moving them to 3.3. Still, since the topic came up now I thought it would be helpful to share my approach. I have been running some heavy stress tests on this and have not seen any problems yet. It would be great to run the changes through some unit tests as well. You may have noticed that mod_jk in TC 3.3 is different from the one in TC 3.2. Also Ajp13 in Tomcat 3.3 (java) is also different since using directly InputStream. And mod_jk in jakarta-tomcat-connectors is also very different since there was some refactoring. From what I saw it seems you're on the right way, and I'm waiting to see your port to TC 3.3. Or if you like, I could try to port it to both 3.3 and J-T-C. I've got many questions here and some refactory should be done on that part of the code later, I don't like very much the way the communication is done. May be something to rewrite completly to Ajp14, adding others new commands (CHUNKED-DATA). The goal will be to have a simpler (and so fastest) way to do the transfert. Questions : - Does the java part need to know that the incoming data came in CHUNKED ? - Should we add others HTTP/1.1 commands like Range, Accept-Ranges, CONNECT ? What do you think about that ?
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java
On Tue, 28 Aug 2001, Schreibman, David wrote: Since I'm going to need support for chunked requests in 3.3 anyway, I'm going ahead with the port of my 3.2.2 changes. I hope to have it in a couple of days. The fix in Ajp13 ( java side ) should be already in, and any _small_ fix in the java side is ok. Same for mod_jk, after a lot of review :-) If the change is not clear and simple enough ( i.e. easy to understand ), I would be -1 on checking it in 3.3. We'll make sure j-t-c is easy to use with 3.3, and I'm ok with any feature/enhancement/etc there. Henri, Dan, Mike, Keith - please try to help with this one, I want to be sure it gets enough review before going in. - Does the java part need to know that the incoming data came in CHUNKED ? The Java side can figure it out if the Content-Length is not set. Still, the Content-Length might be set even when the transfer was chunked. Not sure how much value would be added in knowing this explicitly. My understanding of HTTP/1.1 is that you can't have both ( or one should be ignored - I'm packing my stuff and the spec is in a box right now, so I can't check ) - Should we add others HTTP/1.1 commands like Range, Accept-Ranges, CONNECT ? I suppose these could be helpful but I haven't thought too much about it. In general, it seems like a good idea to leverage as much as possible from the transport. Range, Accept-Ranges - for static content is done by Apache, for dynamic content - I doubt we can, each servlet must deal with that ( to send partial responses ). AFAIK nothing prevents that. Connection keep alive - again, the server should take care of that, we don't need to do anything special. Costin
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java
Hi, David, Colin, et al., | Since I'm going to need support for chunked requests in 3.3 anyway, I'm | going ahead with the port of my 3.2.2 changes. I hope to have it in a | couple of days. | | The fix in Ajp13 ( java side ) should be already in, and any _small_ | fix in the java side is ok. | | Same for mod_jk, after a lot of review :-) I had some reservations at some of the changes David presented, I think the problem can be solved with a smaller code hit. Working on it now.. | - Does the java part need to know that the incoming data came in CHUNKED ? | The Java side can figure it out if the Content-Length is not set. Still, | the Content-Length might be set even when the transfer was chunked. Not | sure how much value would be added in knowing this explicitly. I don't *think* the Java side needs to be changed at all, and Costin is right, HTTP/1.1 s 4.4 says cl cannot be set with any non-identity transfer encoding. | - Should we add others HTTP/1.1 commands like Range, Accept-Ranges, CONNECT | ? | I suppose these could be helpful but I haven't thought too much about it. | In general, it seems like a good idea to leverage as much as possible from | the transport. Um, let's get chunked encoding in first... Keith
Re: Jasper optimizations
* [EMAIL PROTECTED] | | Parsing JSP syntax ( org.apache.jasper34.parser ) will behave as a SAX | parser, and generate SAX events to generator ( almost identical with what | XML syntax will generate - the big difference is that we'll generate the | static content as CDATA, instead of parsing it as XML ). What do you mean by that last sentence? SAX doesn't represent CDATA marked sections directly, so I'm not sure how to interpret this. | Tree representation is still one big issue - I don't know what's the | best for that, so I'll keep the current model ( tree of Generators ) | until I ( or someone else ) have a better idea. ( well, I have some | idea, but I'm not ready to fight for it) This sounds very strange to me. Surely the best approach is to create an object model that represents the data, and leave actions (generation etc) out of the tree representation? That is, something like an abstract syntax tree. Surely keeping the generators is incompatible with using a visitor approach? I don't mean to restart old debates here, but I would like to know what the reasoning behind this is. To me it seems that having a tree of generators is the opposite of modular, since it means that the JSP page tree is entirely opaque. * Lars Marius Garshol | | So the MAIN branch in | jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/ is where | Jasper development is done right now? * [EMAIL PROTECTED] | | That's where most of the optimizations and refactoring is done. In | jakarta-tomcat we have only major bug fixes right now. In that case there is a bug on line 186 of ServletWriter.java: this.println(response.setContentType(\ + pageInfo.servletContentType + ;charset=8859_1\);); 8859_1 is not one of the IANA-registered names for ISO 8859-1 so it can't be used in HTTP headers. It should be replaced by 'iso-8859-1', which is the preferred name. | What is in jakarta-tomcat/src/share/org/apache/jasper goes into | tomcat3.3, and it is what we consider 'stable' ( and frozen ). | | What is in jakarat-tomcat-jasper/jasper34 is a development version, | with quite a few improvements and some bug fixes that couldn't go | into the 'stable' branch ( because we didn't want to destabilize it | ). Thanks! This was very helpful. | About 'interface-compatible' - I don't think so, first of all there | is no 'interface' in 3.3, and the main goal is to actually | reorganize the code so it could be 'interfaced'. jasper34.core will | contain a set of base classes that could be used to extend and plug | the generator into different containers. You wrote that 3.4 could be used to upgrade the Jasper in 3.3. What did you mean by that, then? I interpreted you to mean that you could take Jasper 3.4 and drop it into Tomcat 3.3 and have that work, but apparently that was wrong. | [...] | End of september ( and anything after 3.3 is out ) will be much | better, but Oct 1 is far too tight. Again, thanks very much for this overview. It was most useful. | So it shouldn't matter - you could play it safe, and hack 3.3 ( | knowing the code will not get into the main branch ! ) for your | needs, and port the changes to jasper34. There are other | optimizations going on in 3.4 that might help you as well. This seems to me like it will be the most likely route for us. It would be best if we could avoid it, but if your release deadlines do not match ours (and they don't seem to), then it may be necessary. I'll do my best to make sure any changes I may make will be easy to integrate into future versions, though. --Lars M.
making HttpUtils of poor post args
This is a suggestion for a slight modification in the jakarta implementation of javax.servlet.http.HttpUtils. If this is the wrong forum for that I apologize. I'm using tomcat with a client app which has a sloppy form-urlencode. It will product a POST body like a=1bc=2 - with no equal sign after the b. Currently, this causes HttpUtils.parseQueryString to throw an IllegalArgumentException. While this is technically correct, it does prevent the use of Tomcat with that client. My first choice would be to interpret a=1bc=2 as meaning that b=. It seems like a fairly unambiguous interpretation. The attached diff makes that change. Regards, Rob Lucier __ Do You Yahoo!? Make international calls for as low as $.04/minute with Yahoo! Messenger http://phonecard.yahoo.com/ HttpUtils.no_equal_sign_fix.diff
Re: How to force authentication from JSP?
The only way to pull something like this off is to have the Create a new user account go to some webapp logic that adds new users to the actual database that JDBCRealm is talking to. It will be instantly available for use by the authentication logic. You still won't be able to have a user create a new account and then be accepted as already having logged in, though, without writing a custom Valve implementation that does this for you (and, obviously, is Tomcat specific). Craig On Mon, 27 Aug 2001, Bragg, Casey wrote: Date: Mon, 27 Aug 2001 21:01:48 -0500 From: Bragg, Casey [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: How to force authentication from JSP? Is there a way to force a user to be authenticates as 'Guest' for example? Running Tomcat 4.0b7.. JDBCRealm... Is it possible for a JSP (not through javascript) to do something along the following lines : jsp:forward page=j_security_check jsp:param name=j_username value=%=p_username% / jsp:param name=j_password value=%=p_password% / /jsp:forward The above doesn't work... 404 error.. which seems logical since j_security_check isn't not really a page. What I really need this for is where I have a 'Create new user account' page. Once the account is created I should have already logged the user in for convenience. I know this has been asked before, but I couldn't find the answer in the archives. Thanks so much for your help! ...Casey
RE: cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/t estHeader.java HttpRequest.java
| | - Does the java part need to know that the incoming data came in | CHUNKED ? | | The Java side can figure it out if the Content-Length is not set. Still, | | the Content-Length might be set even when the transfer was chunked. Not | | sure how much value would be added in knowing this explicitly. | | I don't *think* the Java side needs to be changed at all, Yeah, I've got chunked input working ok with just some changes to the c side of jk. I'll clean it up and post tomorrow for dissection. Keith
Re: Jasper optimizations
On 29 Aug 2001, Lars Marius Garshol wrote: | Parsing JSP syntax ( org.apache.jasper34.parser ) will behave as a SAX | parser, and generate SAX events to generator ( almost identical with what | XML syntax will generate - the big difference is that we'll generate the | static content as CDATA, instead of parsing it as XML ). What do you mean by that last sentence? SAX doesn't represent CDATA marked sections directly, so I'm not sure how to interpret this. Sorry, I meant everything that is static from jasper point of view will be sent as characters - that includes all tags and markup that is not jsp, like it would be if a CDATA section would have been used. In .jsp there is no requirement for the text to be well-formed XML ( or be XML ), and I also want to preserve it up to space level ( parsing it and serializing could brake that ). For XML view - non-jsp markup has to be serialized ( as fragments ). This sounds very strange to me. Surely the best approach is to create an object model that represents the data, and leave actions (generation etc) out of the tree representation? That is, something like an abstract syntax tree. Surely keeping the generators is incompatible with using a visitor approach? Well, I already started to split the generators from the jsptree. The current code generation from generators will be ( when we're done with refactoring ) the 'visitors'. Right now the generators are both data representation and processing. I see no problem with using the same tree model, as long as the processing is refactored into visitors. I don't mean to restart old debates here, but I would like to know what the reasoning behind this is. To me it seems that having a tree of generators is the opposite of modular, since it means that the JSP page tree is entirely opaque. My mistake - by tree of generators I meant the current data model minus the code generation. So you'll have a ExpressionNode, ForwardNode, etc. You wrote that 3.4 could be used to upgrade the Jasper in 3.3. What did you mean by that, then? I interpreted you to mean that you could take Jasper 3.4 and drop it into Tomcat 3.3 and have that work, but apparently that was wrong. That doesn't mean the interfaces inside jasper34 will remain the same ! Yes, you should be able to drop jasper 3.4 inside 3.3, or jetty ( or even 4.0 - when we're done with the 1.2 features ) and have it work. The interface between jasper34 ( and 33 ) and tomcat3.3 is a tomcat Interceptor, tomcat has no special knowledge about jasper internals. Costin
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup Bootstrap.java
remm01/08/28 18:27:37 Modified:catalina/src/share/org/apache/catalina/startup Bootstrap.java Log: - If it does not exist, the value of catalina.home should also be the value of user.dir. Revision ChangesPath 1.24 +19 -14 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/Bootstrap.java Index: Bootstrap.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/Bootstrap.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- Bootstrap.java2001/08/15 00:55:25 1.23 +++ Bootstrap.java2001/08/29 01:27:36 1.24 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/Bootstrap.java,v 1.23 2001/08/15 00:55:25 craigmcc Exp $ - * $Revision: 1.23 $ - * $Date: 2001/08/15 00:55:25 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/Bootstrap.java,v 1.24 2001/08/29 01:27:36 remm Exp $ + * $Revision: 1.24 $ + * $Date: 2001/08/29 01:27:36 $ * * * @@ -85,7 +85,7 @@ * class path and therefore not visible to application level classes. * * @author Craig R. McClanahan - * @version $Revision: 1.23 $ $Date: 2001/08/15 00:55:25 $ + * @version $Revision: 1.24 $ $Date: 2001/08/29 01:27:36 $ */ public final class Bootstrap { @@ -237,7 +237,7 @@ ArrayList list = new ArrayList(); // Add the common/classes directory if it exists -File classes = new File(System.getProperty(catalina.home), +File classes = new File(getCatalinaHome(), common + File.separator + classes); if (classes.exists() classes.canRead() classes.isDirectory()) { @@ -256,8 +256,7 @@ } // Add all JAR files in the common/lib directory if it exists -File directory = new File(System.getProperty(catalina.home), - common/lib); +File directory = new File(getCatalinaHome(), common/lib); if (!directory.exists() || !directory.canRead() || !directory.isDirectory()) { System.out.println(Directory + directory.getAbsolutePath() @@ -313,7 +312,7 @@ ArrayList list = new ArrayList(); // Add the server/classes directory if it exists -File classes = new File(System.getProperty(catalina.home), +File classes = new File(getCatalinaHome(), server + File.separator + classes); if (classes.exists() classes.canRead() classes.isDirectory()) { @@ -332,8 +331,7 @@ } // Add all JAR files in the server/lib directory if it exists -File directory = new File(System.getProperty(catalina.home), - server/lib); +File directory = new File(getCatalinaHome(), server/lib); if (!directory.exists() || !directory.canRead() || !directory.isDirectory()) { System.out.println(Directory + directory.getAbsolutePath() @@ -387,8 +385,7 @@ ArrayList list = new ArrayList(); // Add the classes directory if it exists -File classes = new File(System.getProperty(catalina.home), -classes); +File classes = new File(getCatalinaHome(), classes); if (classes.exists() classes.canRead() classes.isDirectory()) { try { @@ -406,8 +403,7 @@ } // Add all JAR files in the lib directory if it exists -File directory = new File(System.getProperty(catalina.home), - lib); +File directory = new File(getCatalinaHome(), lib); if (!directory.exists() || !directory.canRead() || !directory.isDirectory()) { System.out.println(Directory + directory.getAbsolutePath() @@ -453,6 +449,15 @@ return (loader); +} + + +/** + * Get the value of the catalina.home environment variable. + */ +private static String getCatalinaHome() { +return System.getProperty(catalina.home, + System.getProperty(user.dir)); }
Re: Extending Server.xml configurability (for additional classpaths)
On Mon, 27 Aug 2001, Rick Mann wrote: Date: Mon, 27 Aug 2001 19:20:08 -0700 From: Rick Mann [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Extending Server.xml configurability (for additional classpaths) I've seen lots of discussion on the user list desiring the ability to have additional classpaths available to web applications, but not necessarily available to all web apps. Historical note - Having been one of the primary answerers of questions on TOMCAT-USER for the last couple of years, I've accumulated a feel for the most commonly repeated classes of questions for Tomcat 3.0 - 3.2: * Configuration of Apache connector * Classpath problems * Everything else With 3.3 and 4.0, the second category of questions has totally disappeared -- the mechanism in use is clearly understood (all JAR files in the lib directory are automatically made available to all web apps), and it skips the need for users who have never seen an environment variable before from having to care about them. My conclusion, then, is that this change (to ignore the CLASSPATH environment variable) was very positive, and it would be *extremely* difficult to convince me to go back to the problem-causing approach. Ideally, this could be specified in the web.xml file, but that would require changing a spec, and I can think of some arguments against doing so anyway. Spec changes *cannot* happen here. The appropriate feedback address is [EMAIL PROTECTED]. But, perhaps it would be possible to add classpath specifications in the Server.xml file. Inside a context tag, you could specify something like this: additional-classpath~someuser/somedir/classesadditional-classpath Multiple occurrences of this would just add to the locations where classes can be found. An alternative for us would be to do something with the class loaders in our own web apps, if that's possible, but I'd like to see Tomcat have the functionality. Certainly, such a thing is possible. I would still argue that it's *not* desireable. Disk space costs are so trivial that it's just not an issue -- the only valid point for discussion is the management of your application deployment processes. And it is very feasible to set up processes to take advantage of the existing machinery to create a stable, predicatable, runtime environment without using classpaths at all (in the same way that Ant lets you totally free yourself from worrying about classpaths at compile time). Can someone give me some pointers to get started adding this particular configuration tag? I'd really appreciate it. BTW, I'm currently working with the 4.0b7 codebase. Thanks! You would need to change at least the following code: * org.apache.catalina.core.StandardContext - Add methods to store the additional classpath variables included in server.xml * org.apache.catalina.startup.Catalina - Add additional XmlMapper rules to recognize the additional-classpath element and call the corresponding storage methods on the context * (Several classes) - Ripple down the collected extra classpath things into the initialization of the web app class loader. Note, however, that doing this kind of thing makes your application both more fragile (you've got to get that many more configuration settings just right in order for your app to work) and that much more Tomcat-dependent (since this is not a feature that is necessarily portable). Craig McClanahan
cvs commit: jakarta-tomcat-4.0 tomcat.nsi
remm01/08/28 18:28:50 Modified:.tomcat.nsi Log: - Use user.dir property to specify the Catalina path, instead of catalina.home. Revision ChangesPath 1.13 +4 -4 jakarta-tomcat-4.0/tomcat.nsi Index: tomcat.nsi === RCS file: /home/cvs/jakarta-tomcat-4.0/tomcat.nsi,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- tomcat.nsi2001/07/18 23:14:03 1.12 +++ tomcat.nsi2001/08/29 01:28:50 1.13 @@ -1,6 +1,6 @@ ; Tomcat 4 script for Nullsoft Installer -; $Id: tomcat.nsi,v 1.12 2001/07/18 23:14:03 remm Exp $ +; $Id: tomcat.nsi,v 1.13 2001/08/29 01:28:50 remm Exp $ Name jakarta-tomcat-4.0 Caption Jakarta Tomcat 4.0 @@ -69,7 +69,7 @@ SetOutPath $INSTDIR\bin File /oname=tomcat.exe bin\tomcat.exe - ExecWait '$INSTDIR\bin\tomcat.exe -install Jakarta Tomcat $2\jre\bin\hotspot\jvm.dll -Djava.class.path=$INSTDIR\bin\bootstrap.jar -Dcatalina.home=$INSTDIR -start org.apache.catalina.startup.BootstrapService -params start -stop org.apache.catalina.startup.BootstrapService -params stop -out $INSTDIR\logs\stdout.log -err $INSTDIR\logs\stderr.log' + ExecWait '$INSTDIR\bin\tomcat.exe -install Jakarta Tomcat $2\jre\bin\hotspot\jvm.dll -Djava.class.path=$INSTDIR\bin\bootstrap.jar -Duser.dir=$INSTDIR -start org.apache.catalina.startup.BootstrapService -params start -stop org.apache.catalina.startup.BootstrapService -params stop -out $INSTDIR\logs\stdout.log -err $INSTDIR\logs\stderr.log' ClearErrors @@ -114,12 +114,12 @@ CreateShortCut $SMPROGRAMS\Jakarta Tomcat 4.0\Start Tomcat.lnk \ $2\bin\java.exe \ - '-jar -Dcatalina.home=$INSTDIR $INSTDIR\bin\bootstrap.jar start' \ + '-jar -Duser.dir=$INSTDIR $INSTDIR\bin\bootstrap.jar start' \ $INSTDIR\tomcat.ico 0 SW_SHOWNORMAL CreateShortCut $SMPROGRAMS\Jakarta Tomcat 4.0\Stop Tomcat.lnk \ $2\bin\java.exe \ - '-jar -Dcatalina.home=$INSTDIR $INSTDIR\bin\bootstrap.jar stop' \ + '-jar -Duser.dir=$INSTDIR $INSTDIR\bin\bootstrap.jar stop' \ $INSTDIR\tomcat.ico 0 SW_SHOWMINIMIZED SetOutPath $SMPROGRAMS\Jakarta Tomcat 4.0\Configuration
Re: Follow Up: 403 error-page N/W
On Tue, 28 Aug 2001, Bragg, Casey wrote: Date: Tue, 28 Aug 2001 00:09:08 -0500 From: Bragg, Casey [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Follow Up: 403 error-page N/W I found one more detail... My 403 error page works if the 403 is caused by a filter, but it doesn't work if caused by JDBCRealm. That makes sense, given the current implementation of error pages. Right now, it's performed immediately after the filter chain returns -- but the processing is already done by the time the JDBCRealm valve can throw a 403 error. This will take some slight refactoring to fix. Craig
embedded tc
Could this ever happen or am I doing something silly? Keith Index: src/share/org/apache/tomcat/startup/EmbededTomcat.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/EmbededTomcat.java, v retrieving revision 1.50 diff -u -b -r1.50 EmbededTomcat.java --- src/share/org/apache/tomcat/startup/EmbededTomcat.java 2001/08/23 15:13:47 1.50 +++ src/share/org/apache/tomcat/startup/EmbededTomcat.java 2001/08/29 00:46:50 @@ -705,7 +705,9 @@ String cp=System.getProperty(tc_path_add); cp=IntrospectionUtils.classPathAdd(commonCP,cp); cp=IntrospectionUtils.classPathAdd(appsCP,cp); + if (cp != null) { System.getProperties().put(tc_path_add,cp); + } contextM.setParentLoader(parentCL); contextM.setCommonLoader(commonCL);
Re: Bug in tag lib implementation
On Tue, 28 Aug 2001, Jin Yu wrote: Date: Tue, 28 Aug 2001 10:24:24 -0400 From: Jin Yu [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: '[EMAIL PROTECTED]' [EMAIL PROTECTED] Subject: Bug in tag lib implementation Hi, According to my interpretation of the JSP 1.1 spec, the following code should be legal. I've changed the name of the tag from foo to foo.test. Page 99 of the spec states that name can be any NMTOKEN. Since foo.test is a NMTOKEN it should be a legal name. I think this is the same as bug #3019. I've tested this on Tomcat 3.2.3, 3.3, and 4.0b7. They all throw exception similiar to the one below. It appears that the problem is that the tag name is concatenated with some other text to created varible names in the generated JSP without checking the name for illegal variable name characters and replacing them. Is my interpretation of the spec correct? I believe so. This is an implementation issue in all versions of Jasper. Has this problem been fixed already? Not yet. How can I submit a fix to the problem that my co-worker has come up with? The best general approach is to submit a bug report to http://nagoya.apache.org/bugzilla and attach your fix as an attachment. What version of tomcat will such a fix be accepted for? If I'm understanding you correctly, this is already reported against Tomcat 4.0 as Bugzilla #3019. A proposed fix would accellerate this getting addressed for this version. Thanks, Jin Craig McClanahan ---updated example-taglib.tld !-- A simple Tag -- !-- foo tag -- tag namefoo.test/name tagclassexamples.FooTag/tagclass teiclassexamples.FooTagExtraInfo/teiclass bodycontentJSP/bodycontent info Perform a server side action; uses 3 mandatory attributes /info - updated foo.jsp from examples -- html !-- Copyright (c) 1999 The Apache Software Foundation. All rights reserved. -- body %@ taglib uri=http://java.apache.org/tomcat/examples-taglib; prefix=eg % Radio stations that rock: ul eg:foo.test att1=98.5 att2=92.3 att3=107.7 li%= member %/li /eg:foo.test /ul - exception seen in the browser -- Error: 500 Location: /examples/jsp/simpletag/foo.jsp Internal Servlet Error: org.apache.jasper.JasperException: Unable to compile class for JSPD:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002f jsp_0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:65: Invalid declaration. examples.FooTag _jspx_th_eg_foo.test_0 = new examples.FooTag(); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:66: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setPageContext(pageContext); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:67: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setParent(null); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:68: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt1(98.5); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:69: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt2(92.3); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:70: Undefined variable, class, or package name: _jspx_th_eg_foo _jspx_th_eg_foo.test_0.setAtt3(107.7); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:72: Invalid declaration. int _jspx_eval_eg_foo.test_0 = _jspx_th_eg_foo.test_0.doStartTag(); ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:73: Undefined variable or class name: _jspx_eval_eg_foo if (_jspx_eval_eg_foo.test_0 == Tag.EVAL_BODY_INCLUDE) ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp _0002fsimpletag_0002ffoo_0002ejspfoo_jsp_0.java:75: Undefined variable or class name: _jspx_eval_eg_foo if (_jspx_eval_eg_foo.test_0 != Tag.SKIP_BODY) { ^ D:\Java\Tomcat\jakarta-tomcat-3.2.3\work\localhost_8080%2Fexamples\_0002fjsp
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http HttpConnector.java
remm01/08/28 18:44:07 Modified:catalina/src/share/org/apache/catalina/connector/http HttpConnector.java Log: - Fix race conditions during HTTP connector shutdown. Patch submitted by Michael Newman newman at mindless.com Revision ChangesPath 1.23 +53 -52 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http/HttpConnector.java Index: HttpConnector.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http/HttpConnector.java,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- HttpConnector.java2001/08/23 22:32:10 1.22 +++ HttpConnector.java2001/08/29 01:44:07 1.23 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http/HttpConnector.java,v 1.22 2001/08/23 22:32:10 craigmcc Exp $ - * $Revision: 1.22 $ - * $Date: 2001/08/23 22:32:10 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/connector/http/HttpConnector.java,v 1.23 2001/08/29 01:44:07 remm Exp $ + * $Revision: 1.23 $ + * $Date: 2001/08/29 01:44:07 $ * * * @@ -96,7 +96,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.22 $ $Date: 2001/08/23 22:32:10 $ + * @version $Revision: 1.23 $ $Date: 2001/08/29 01:44:07 $ */ @@ -108,6 +108,12 @@ /** + * The codeService/code we are associated with (if any). + */ +private Service service = null; + + +/** * The accept count for this Connector. */ private int acceptCount = 10; @@ -252,12 +258,6 @@ /** - * The codeService/code we are associated with (if any). - */ -private Service service = null; - - -/** * The string manager for this package. */ private StringManager sm = @@ -316,6 +316,28 @@ /** + * Return the codeService/code with which we are associated (if any). + */ +public Service getService() { + +return (this.service); + +} + + +/** + * Set the codeService/code with which we are associated (if any). + * + * @param service The service that owns this Engine + */ +public void setService(Service service) { + +this.service = service; + +} + + +/** * Return the connection timeout for this Connector. */ public int getConnectionTimeout() { @@ -733,28 +755,6 @@ /** - * Return the codeService/code with which we are associated (if any). - */ -public Service getService() { - -return (this.service); - -} - - -/** - * Set the codeService/code with which we are associated (if any). - * - * @param service The service that owns this Engine - */ -public void setService(Service service) { - -this.service = service; - -} - - -/** * Return the TCP no delay flag value. */ public boolean getTcpNoDelay() { @@ -982,16 +982,18 @@ } catch (IOException e) { //if (debug = 3) //log(run: Accept returned IOException, e); -if (started !stopped) -log(accept: , e); try { -//if (debug = 3) -//log(run: Closing server socket); -serverSocket.close(); -if (!stopped) { -//if (debug = 3) -//log(run: Reopening server socket); -serverSocket = open(); +synchronized (threadSync) { +if (started !stopped) +log(accept: , e); +if (!stopped) { +//if (debug = 3) +//log(run: Closing server socket); +serverSocket.close(); +//if (debug = 3) +//log(run: Reopening server socket); +serverSocket = open(); +} } //if (debug = 3) //log(run: IOException processing completed); @@ -1054,12 +1056,10 @@
cvs commit: jakarta-tomcat/src/doc tomcat-ug.html
larryi 01/08/28 18:49:06 Modified:src/doc tomcat-ug.html Log: More miscellaneous updates. Fixed Configuring Classes table to display better in Netscape Navigator. Updated some installation info. Revision ChangesPath 1.12 +108 -68 jakarta-tomcat/src/doc/tomcat-ug.html Index: tomcat-ug.html === RCS file: /home/cvs/jakarta-tomcat/src/doc/tomcat-ug.html,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- tomcat-ug.html2001/08/27 13:54:39 1.11 +++ tomcat-ug.html2001/08/29 01:49:05 1.12 @@ -1,10 +1,10 @@ !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN html head -!-- $Id: tomcat-ug.html,v 1.11 2001/08/27 13:54:39 larryi Exp $ -- +!-- $Id: tomcat-ug.html,v 1.12 2001/08/29 01:49:05 larryi Exp $ -- !-- Copyright 1999-2001 Apache Software Foundation -- meta http-equiv=Content-Type content=text/html; charset=iso-8859-1 -link rel=stylesheet href=style.css +link rel=stylesheet type=text/css href=style.css titleTomcat User's Guide/title !-- Changed by: Costin Manolache, 20-Mar-2000 -- !-- Changed by: Gal Shachor, 27-Mar-2000 -- @@ -276,35 +276,20 @@ ul lia href=http://jakarta.apache.org/site/binindex.html;Download/a the -appropriate jakarta-tomcat-ilt;versiongt;/i binary file./li +appropriate jakarta-tomcat-ilt;versiongt;/i binary file./lip liUnzip the file into some directory (say /usr/local or C:\). This should create a new subdirectory named - ttquot;jakarta-tomcat-ilt;versiongt;/iquot;/tt./li + codequot;jakarta-tomcat-ilt;versiongt;/iquot;/code./lip liIn a shell or DOS window, change to the - ttquot;jakarta-tomcat-ilt;versiongt;/iquot;/tt directory - and set a new environment variable (a name=tomcat_home_envTOMCAT_HOME/a) - to point to the root directory of your Tomcat hierarchy. The exact directory may - vary from system to system; check your local file system to be sure where Tomcat - is installed. - ol - liOn Win32 systems you should type: br -ttbigset TOMCAT_HOME=c:\jakarta-tomcat-ilt;versiongt;/i - /big/tt/li - liOn UNIX (using bash/sh) you should type: br - ttbigTOMCAT_HOME=/usr/local/jakarta-tomcat-ilt;versiongt;/i ; export TOMCAT_HOME - /big/tt/li - liOn UNIX (using tcsh) you should type: br -ttbigsetenv TOMCAT_HOME=/usr/local/jakarta-tomcat-ilt;versiongt;/i - /big/tt/li - /ol/li + codequot;jakarta-tomcat-ilt;versiongt;/iquot;/code directory./lip -liSet the environment variable JAVA_HOME to point to the root + liSet the environment variable JAVA_HOME to point to the root directory of your JDK hierarchy. You may optionally add the Java interpreter to your PATH environment variable. The exact directory may vary from system to system. Check your local file system to be sure - where Java is installed. + where Java is installed.p ol liWin32:br ttbig @@ -324,7 +309,61 @@ setenv PATH=$JAVA_HOME/bin:$PATHbr /big/tt /li - /ol/li + /ol/lip + + liYou may optionally set the TOMCAT_HOME environment variable. If + the supplied shell/batch scripts are executed from + ttquot;jakarta-tomcat-ilt;versiongt;/iquot;/tt or from + its quot;binquot; subdirectory, then they will successfully set + TOMCAT_HOME for you if not already set. If you wish to execute + these shell/batch scripts from other directories, you must set + TOMCAT_HOME explicitely.p +ol + liOn Win32 systems you should type: br + ttbigset TOMCAT_HOME=c:\jakarta-tomcat-ilt;versiongt;/i + /big/tt/li + liOn UNIX (using bash/sh) you should type: br + ttbigTOMCAT_HOME=/usr/local/jakarta-tomcat-ilt;versiongt;/i ; export TOMCAT_HOME + /big/tt/li + liOn UNIX (using tcsh) you should type: br + ttbigsetenv TOMCAT_HOME=/usr/local/jakarta-tomcat-ilt;versiongt;/i + /big/tt/li +/ol/lip + + liIf you are using Win9x, you will need to deal with the potential +quot;Out of environment spacequot; problem, if you haven't already. +There are several ways to deal with this.p +ol + liA global solution is to add a quot;SHELLquot; command to your + codeCONFIG.SYS/code file. Click
Re: embedded tc
Quoting Keith Wannamaker [EMAIL PROTECTED]: Could this ever happen or am I doing something silly? Keith [snip] + if (cp != null) { System.getProperties().put(tc_path_add,cp); + } Not sure if it could possibly happen or not. Just to add my $.02 to the above, however, it might be good to have an else clause either toss a message to the command-line (if skipping the put() call might cause problems later on down the line) or write a message to log (if it's not that big of a deal). - Christopher /** * Pleurez, pleurez, mes yeux, et fondez vous en eau! * La moitiƩ de ma vie a mis l'autre au tombeau. *---Cornelle */
RE: Extending Server.xml configurability (for additional classpaths)
I've seen lots of discussion on the user list desiring the ability to have additional classpaths available to web applications, but not necessarily available to all web apps. ...mainly because people don't take the time to understand the class loading mechanism, and ask for things they wouldn't otherwise, if they knew what was going on =) This happens a lot of times when people are learning new technology. My conclusion, then, is that this change (to ignore the CLASSPATH environment variable) was very positive, and it would be *extremely* difficult to convince me to go back to the problem-causing approach. +10 (to ignore CLASSPATH) - r
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/core ContextManager.java Request.java
costin 01/08/28 22:01:24 Modified:src/share/org/apache/tomcat/core ContextManager.java Request.java Log: Extra messages and checks. Revision ChangesPath 1.190 +4 -0 jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java Index: ContextManager.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v retrieving revision 1.189 retrieving revision 1.190 diff -u -r1.189 -r1.190 --- ContextManager.java 2001/08/21 04:55:39 1.189 +++ ContextManager.java 2001/08/29 05:01:24 1.190 @@ -1090,6 +1090,10 @@ else ri=req.getContext().getContainer(). getInterceptors( Container.H_handleError ); + if( ri==null ) { + log( handleError with no error handlers + req + + req.getContext()); + return; + } for( int i=0; i ri.length; i++ ) { status=ri[i].handleError( req, res, t ); if( status!=0 ) return; 1.110 +5 -0 jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java Index: Request.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v retrieving revision 1.109 retrieving revision 1.110 diff -u -r1.109 -r1.110 --- Request.java 2001/08/17 04:02:54 1.109 +++ Request.java 2001/08/29 05:01:24 1.110 @@ -72,6 +72,7 @@ import java.security.Principal; import java.io.IOException; +import java.io.CharConversionException; import java.util.Enumeration; import java.util.Hashtable; @@ -430,6 +431,10 @@ handleQueryParameters(); params.processParameters( formData, 0, available ); + } catch(java.io.CharConversionException cex ) { + contextM.log(CharConversionException processing parameters: + + this ++ cex.toString()); + } catch(IOException ex ) { ex.printStackTrace(); // XXX should we throw exception or log ?
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/server Ajp13.java Ajp13Interceptor.java Ajp13Packet.java
costin 01/08/28 22:08:07 Modified:src/share/org/apache/tomcat/modules/server Ajp13.java Ajp13Interceptor.java Ajp13Packet.java Log: Bug fix - under certain conditions the POST data was messed up. This doesn't happen with browsers, but it did happened with the test application, because the body was sent in a different tcp packet. We do receive a body packet just after the headers ( we could delay that - in ajp14 ), and this can be void. Improved debugging ( part of the search for the bug ) Revision ChangesPath 1.23 +38 -7 jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13.java Index: Ajp13.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13.java,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- Ajp13.java2001/08/23 03:08:39 1.22 +++ Ajp13.java2001/08/29 05:08:07 1.23 @@ -211,6 +211,7 @@ // This is a touch cargo-cultish, but I think wise. blen = 0; pos = 0; + if( dL0 ) d( recycle()); headersWriter.recycle(); } @@ -382,6 +383,7 @@ // immediately after MessageBytes clB=headers.getValue(content-length); int contentLength = (clB==null) ? -1 : clB.getInt(); + if( dL 0 ) d(Content-Length: + contentLength ); if(contentLength 0) { req.setContentLength( contentLength ); /* Read present data */ @@ -389,10 +391,18 @@ if(err 0) { return 500; } - - blen = inBuf.peekInt(); + + // We may get an empty packet ( no data available right now ) pos = 0; - inBuf.getBytes(bodyBuff); + blen=0; + if( inBuf.getLen() != 0 ) { + blen = inBuf.peekInt(); + int cpl=inBuf.getBytes(bodyBuff); + if( dL 0 ) + d( Copy into body buffer + bodyBuff + + cpl ++ + blen + + new String( bodyBuff, 0, cpl )); + } + } return 200; // Success @@ -438,6 +448,9 @@ if(pos + len = blen) { // Fear the off by one error // Sanity check b.length off + len? System.arraycopy(bodyBuff, pos, b, off, len); + if( dL 0 ) + d(doRead1: + pos + + len + + blen + + + new String( b, off, len ) + + Thread.currentThread()); pos += len; return len; } @@ -451,6 +464,9 @@ int c = bytesRemaining toCopy ? bytesRemaining : toCopy; System.arraycopy(bodyBuff, pos, b, off, c); + if( dL 0 ) d(doRead2: + pos + + len + + blen + + c + + + new String( b, off, len ) + + +new String( bodyBuff, pos, len )); toCopy-= c; @@ -481,20 +497,28 @@ inBuf.reset(); inBuf.appendByte(JK_AJP13_GET_BODY_CHUNK); inBuf.appendInt(MAX_READ_SIZE); + if( dL0 ) d(refillReadBuffer + Thread.currentThread()); send(inBuf); int err = receive(inBuf); if(err 0) { throw new IOException(); } - + + // No data received. + if( inBuf.getLen() == 0 ) { + pos=0; + blen=0; + return false; + } blen = inBuf.peekInt(); pos = 0; - inBuf.getBytes(bodyBuff); + int cpl=inBuf.getBytes(bodyBuff); + if( dL 0 ) d( Copy into body buffer2 + bodyBuff + + cpl + + blen ++ + new String( bodyBuff, 0, cpl )); return (blen 0); -} - +} // Servlet Output Support = /** @@ -665,6 +689,7 @@ } total_read += rd; } + if( dL0 ) msg.dump(Ajp13.receive() + rd + + len ); return total_read; } @@ -679,6 +704,7 @@ byte b[] = msg.getBuff(); int len = msg.getLen(); out.write( b, 0, len ); + if( dL0 ) msg.dump(Ajp13.send()); } /** @@ -695,5 +721,10 @@ if(null !=in) { in.close(); } +} + +private static final int dL=0; +private void d(String s ) { + System.err.println( Ajp13: + s ); } } 1.12 +13 -5 jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java Index: Ajp13Interceptor.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 ---
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/collections SimpleHashtable.java
costin 01/08/28 22:08:40 Modified:src/share/org/apache/tomcat/util/collections SimpleHashtable.java Log: Small fix in SimpleHashtable, we can have calls to nextElement without hasMore. Revision ChangesPath 1.5 +5 -1 jakarta-tomcat/src/share/org/apache/tomcat/util/collections/SimpleHashtable.java Index: SimpleHashtable.java === RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/collections/SimpleHashtable.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- SimpleHashtable.java 2001/07/19 05:50:46 1.4 +++ SimpleHashtable.java 2001/08/29 05:08:40 1.5 @@ -97,7 +97,7 @@ * it makes a significant difference when normalizing attributes, * which is done for each start-element construct. * - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ public final class SimpleHashtable implements Enumeration { @@ -166,6 +166,7 @@ public Enumeration keys() { currentBucket = 0; current = null; + hasMoreElements(); return this; } @@ -197,6 +198,9 @@ throw new IllegalStateException (); retval = current.key; current = current.next; + // Advance to the next position ( we may call next after next, + // without hasMore ) + hasMoreElements(); return retval; }