Classpath Ordering: Questions, and possible contrib.
Hi folks, I've been having a peek at the Tomcat main CVS branch in respect of its classloading behaviour. Apologies if I have missed any discussion - I have only just subscribed, and I did not find much in the tomcat-dev archives a couple of days ago. It appears to me that ClassLoading is not quite right in a couple of respects ( ie. not working 'as advertised' ), and if you're willing, I'd like to have a go at a couple of patches for it. Here's the list of things that I consider to be broken, based on the understandings that: A) the hierarchy should go: SystemCL | -- LAYER 1 lib/common CL / \ -- LAYER 2 lib/container lib/apps CL |-- LAYER 3 WEB-INF/libsame CL, but with URLs WEB-INF/classes from both dirs, in this order... B) a classloader which failed to find a class will delegate to it's parent a'la JDK 2 style, with the delegation behaviour in: JDK 1.2+ java.net.URLClassLoader JDK 1.1 org.apache.tomcat.util.compat.SimpleClassLoader List of broken behaviours: 1) LAYER 1 and LAYER 2 are broken ( do not delegate to parent ) org.apache.tomcat.modules.config.ProfileLoader [ -r ] line 320: commonLoader is set to be its own parent, if there was previously a commonLoader, or the System CL if not. line 331: ( same, with appLoader ) line 343: ( same, with containerLoader ) this is also a potential memory leak after a while, if initClassLoaders() is called more than once. 2) LAYER 3 bypasses straight to the System CL: there is a piece of code in org.apache.tomcat.modules.config.LoaderInterceptor11 [ ( line 197 - 207 ) if( useAL !context.isTrusted() ) { if( debug 0 ) log( Using webapp loader + context.isTrusted()); parent=cm.getParentLoader(); } else if( useNoParent ) { if( debug 0 ) log( Using no parent loader ); parent=null; } else { if( debug 0 ) log( Using container loader ); parent=this.getClass().getClassLoader(); } I am not really sure why this piece of code is as it is. note: - useAL is set by setUseApplicationLoader( boolean ). I could find no callers of this method in the source, but the method is still public. - same story for useNoParent, which is set by setUseNoParent( boolean ) - since useAL is initialised in the constructor to false, it would appear that if(1) is never called. - since useNoParent also defaults to false, it would appear that if(2) is never called - so it must always default to if(3), and this line does NOT gurarantee delegation to the container loader! ( expected Context.getContextManager().getContainerLoader() instead ) 3) Inconsistent directory-scanning behaviours org.apache.tomcat.modules.config.ProfileLoader [ -r ] makes use of IntrospectionUtils, but orb.apache.tomcat.core.LoaderInterceptor11 [ -r ] does not ... as a result of this, there are different behaviours in classloading with respect to the recursion of directories. Here's a list of questions I need answered to make some improvements: 0) Are there good historical reasons why the above behaviours are as they are? 1) is it OK to not use the IntrospectionUtils when constructing classpaths? I find its API a little awkward. ( Would factor out classpath-ish utilities into their own Class, deprecate existing classpath-ish methods on IntrospectionUtils ). 1b) assuming yes, what package should that class be placed into? 2) is it OK to introduce the following new behaviour that allows the user to specify order in directories where classloading occurs? IF there is a file called 'classpath.properties' ( call it what you like ), in the root directory of a classpath location, or in any of its descended directories, AND that file contains a line 'org.apache.tomcat.classpath.order=comma_separated_list_of_files' THAT for each item in comma_separated_list_of_files which is actually an immediate child of the directory according to the filesystem, it is placed into the classpath in that particular order. Unorded entries would be appended to to the end of the list for that directory. [ I already have an implementation of this if anyone wants to see it first. Also, I am prepared to writup the user-documentation before actually doing it. ] 3) where is the appropriate place to put user-documentation about classloading behaviour? 4) is there a test ( eg. JUnit test? ) or test-suite ( eg. WatchDog? ) or test web-app, that verifies
Classpath Ordering: Questions, and possible contrib. (fwd)
I provided for, but did not include, the actual file versions in my analysis: Also, I mis-package-named a couple of them, oops. The files I refer to are: org.apache.tomcat.modules.config.ProfileLoader [ -r 1.5 ] org.apache.tomcat.modules.config.LoaderInterceptor11 [ -r 1.12 ] ...sorry 'bout that! David. David Bullock - http://www.lisasoft.com/ Sun Certified Programmer for Java 2 The key ingredients of success are a crystal-clear goal, a realistic attack plan to achieve that goal, and consistent, daily action to reach that goal. Steve Maguire, Debugging the Development Process.
Re: [jtc] anybody build iis plugin lately
when i try to use jtc/jk/native/iis/isapi.ds[wp], i get errors that look like this: The file g:\dev\jakarta\jakarta-tomcat-connectors\jk\native\iis\isapi.dsp has been modified and cannot be loaded as a Developer Studio project. I haven't noticed that with IIS, but I got the same thing when I hand edited the dsapi.dsp file for the Domino connector. It seems that, although Microsoft have implemented a textual file format for the Visual Studio project files if you actually edit them outside Visual Studio something breaks! This is presumably to protect us from ourselves. Please don't get me started... I've just verified here that some types of edit are OK on dsp files so I'm not sure what triggers this message. In the absence of anyone else volunteering I'd be happy to have a look at this -- I've got several IIS boxes (for my sins) on which I can test it. ideas?? by the way, it'd be nice to have an nmake file here... if someone could generate one :) I can probably do that too unless anyone else is a more appropriate volunteer. i've also be tossing around the idea of a plain old gnu makefile too... but i suppose an nmake file would be better for most people. if the dsp works for you, andy, you should be able to simply export isapi.mak and check that in. thanks :)
Re: [jtc] anybody build iis plugin lately
kevin seguin wrote: I can probably do that too unless anyone else is a more appropriate volunteer. i've also be tossing around the idea of a plain old gnu makefile too... but i suppose an nmake file would be better for most people. if the dsp works for you, andy, you should be able to simply export isapi.mak and check that in. I haven't looked at it, but I'll have a go at it later tonight. -- Andy Armstrong, Tagish
Re: Classpath Ordering: Questions, and possible contrib.
Hi David, Thanks for this report, I'm impressed on your deep understanding of the subject. Class loading is one of the most difficult areas, and until Nacho implemented most of the new loader scheme we had lots of problems. ( that happened few months ago ). Here's the list of things that I consider to be broken, based on the understandings that: A) the hierarchy should go: SystemCL | -- LAYER 1 lib/common CL / \ -- LAYER 2 lib/container lib/apps CL |-- LAYER 3 WEB-INF/libsame CL, but with URLs WEB-INF/classes from both dirs, in this order... You are absolutely right, that's the intended hierarchy. What's important is that lib/container and the webapps are sibling, and standard parent delegation is used ( with all jaxp-like problems avoided by the fact that the webapps no longer 'see' libs used by container ). List of broken behaviours: 1) LAYER 1 and LAYER 2 are broken ( do not delegate to parent ) org.apache.tomcat.modules.config.ProfileLoader [ -r ] ProfileLoader is not actively used right now, it needs more testing. It's goal is to go one step forward and allow: - another layer for webapps, allowing groups ( subsets ) of webapps to share some libs ( that are not shared by all webapps ). Webapps need to share libs in order to be able to communicate ( internal include, forward, etc - the attributes must be loaded by the same loader). But the global webapps classloader is not good as it'll again create versioning problems ( all apps on the server will share it, but on a big server you may have multiple groups of cooperating apps ) - for container, allow use of a mechanism similar with webapps, where different modules can be inserted/reloaded at runtime, without restarting the server. What have to be common ( and fixed ) is the core ( which shouldn't change anyway ), the config modules and the context mapper. All other modules ( auth, session, etc ) can be loaded as context modules - and as a consequence it is possible to reload them, add, etc. ( I'm trying to start this with jasper34 - package it as a trusted/special webapp, and allow people to upgrade it easily - next step will be hot upgrade ) Now, regarding the bugs you found - thanks for reviewing and taking the time to find them. line 320: commonLoader is set to be its own parent, if there was previously a commonLoader, or the System CL if not. This is the commonLoader for the _profile_. Each profile represents a refinement of the main class loaders. A profile is a group of webapps, sharing common jars - for example they may all use jasper34 ( while other groups will keep using jasper33 ). In this case, jasper34 will be part of the container/jasper34 class loader ( child of container class loader ). The real problem is that we can't have multiple inheritance for the class loader hierarchy - I'm still trying to figure out an intuitive way to represent that. It's easy for container profile ( i.e. jasper34, modules that are used only for some apps and could be reloaded without restarting the server ), it's easy for webapps profiles ( like groups of webapps sharing a jaxp impl. ). It's not easy for common, and it's not easy to put them togheter. That's why ProfileLoader is not enabled ( or used ) right now. this is also a potential memory leak after a while, if initClassLoaders() is called more than once. Initialization happens only at startup ( or soft server reload - but that part is not even started ) 2) LAYER 3 bypasses straight to the System CL: if( useAL !context.isTrusted() ) { if( debug 0 ) log( Using webapp loader + context.isTrusted()); parent=cm.getParentLoader(); } else if( useNoParent ) { if( debug 0 ) log( Using no parent loader ); parent=null; } else { if( debug 0 ) log( Using container loader ); parent=this.getClass().getClassLoader(); } I am not really sure why this piece of code is as it is. note: - useAL is set by setUseApplicationLoader( boolean ). I could find no callers of this method in the source, but the method is still public. The config mechansim will call this ( using introspection ) if the user add an attribute useApplicationLoader=true in LoaderIntercepotor element in server.xml. - same story for useNoParent, which is set by setUseNoParent( boolean ) Same - it's an user option that defines how the webapp should behave. Both 1 and 2 are triggered by user settings ( for example the /admin app will have trusted attribute set, i.e. case 3). The default setting is useApplicationLoader=true, as part of server.xml ( I'll fix it in LoaderInterceptor
cvs commit: jakarta-tomcat-connectors/jk/native/common jk_ajp14_worker.c
costin 01/06/23 09:04:12 Modified:jk/native/common jk_ajp14_worker.c Log: Small fix - if validation fails ( like I forgot to add the secret ), then destroy will try to free() a constant ( since strdup didn't happened ). We set it to null, the init will fail if the user doesn't specify a valid option. ( the stack trace was: #0 0x40095ce8 in pthread_mutex_lock () from /lib/libpthread.so.0 #1 0x401230a8 in free () from /lib/libc.so.6 #2 0x401d2364 in destroy (pThis=0xb414, l=0x8165df8) at ../common/jk_ajp14_worker.c:156 #3 0x401d56f8 in wc_create_worker (name=0x8168038 ajp14, init_data=0x81674f8, rc=0xb468, we=0x401e275c, l=0x8165df8) at ../common/jk_worker.c:170 #4 Revision ChangesPath 1.8 +2 -2 jakarta-tomcat-connectors/jk/native/common/jk_ajp14_worker.c Index: jk_ajp14_worker.c === RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_ajp14_worker.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- jk_ajp14_worker.c 2001/06/22 08:33:56 1.7 +++ jk_ajp14_worker.c 2001/06/23 16:04:12 1.8 @@ -58,7 +58,7 @@ /*** * Description: AJP14 next generation Bi-directional protocol. * * Author: Henri Gomez [EMAIL PROTECTED] * - * Version: $Revision: 1.7 $ * + * Version: $Revision: 1.8 $ * ***/ #include jk_context.h @@ -299,7 +299,7 @@ memset(aw-login, 0, sizeof(jk_login_service_t)); aw-login-negociation = (AJP14_CONTEXT_INFO_NEG | AJP14_PROTO_SUPPORT_AJP14_NEG); - aw-login-web_server_name = MyApache; + aw-login-web_server_name = NULL; // must be set in init aw-ep_cache_sz= 0; aw-ep_cache = NULL;
Re: [jtc] anybody build iis plugin lately
I've fixed isapi.dsp and added an nmake Makefile (isapi.mak). I also had to fix a vouple of syntax errors in jk_isapi_plugin.c that I think were changes that Henri made in an attempt to bring the IIS connector in line with the latest jk code. One of the changes Henri had made was similar to a change he made in the Domino connector. For now I've commented out the lines in question, which I don't think will break anything, but to incorporate that change fully in the Domino connector I had to make some non trivial changes to the code to defer initialisation of the worker map until the first request is seen by the connector. I think I'd have to do the same thing with the IIS connector to make it work (basically the problem is that Henri's code is looking for the name of the server which isn't available either from IIS or from Domino until you're inside a real request). I can go ahead and make the necessary changes, but I'm concious that I might be stepping on someone else's toes given that I'm not really the maintainer of the IIS connector. Should I go ahead and do it? Andy Armstrong wrote: kevin seguin wrote: I can probably do that too unless anyone else is a more appropriate volunteer. i've also be tossing around the idea of a plain old gnu makefile too... but i suppose an nmake file would be better for most people. if the dsp works for you, andy, you should be able to simply export isapi.mak and check that in. I haven't looked at it, but I'll have a go at it later tonight. -- Andy Armstrong, Tagish -- Andy Armstrong, Tagish
Anyone know why the ISAPI redirector works how it does?
I've been looking at the source of the ISAPI redirector (initially to get it to build again -- it seems to have broken), and wondering why it works the way it does. It provides both an HttpFilterProc and an HttpExtensionProc. The HttpFilterProc looks for incoming requests that are elligable to be handled by Tomcat and, if it finds one, it rewrites the request so that it will be passed to the HttpExtensionProc for processing. From a cursory glance at the ISAPI documentation it seems that this could all be handled in HttpFilterProc. Does anyone know what I'm missing? If there isn't a clear reason why it's implemented like this I might try and build a new ISAPI filter that works the same way as the Domino DSAPI filter. It should make request handling slightly faster, simplify the code and might make it possible to have some source in common between the Domino and IIS redirectors. -- Andy Armstrong, Tagish
Re: Classpath Ordering: Questions, and possible contrib.
On Sat, 23 Jun 2001 [EMAIL PROTECTED] wrote: Hi David, Thanks for this report, I'm impressed on your deep understanding of the subject. Class loading is one of the most difficult areas, and until Nacho implemented most of the new loader scheme we had lots of problems. ( that happened few months ago ). Here's the list of things that I consider to be broken, based on the understandings that: A) the hierarchy should go: SystemCL | -- LAYER 1 lib/common CL / \ -- LAYER 2 lib/container lib/apps CL |-- LAYER 3 WEB-INF/libsame CL, but with URLs WEB-INF/classes from both dirs, in this order... You are absolutely right, that's the intended hierarchy. One thing you might want to note for the future is that, in servlet 2.3, the order of loading in the web-app classloader is specified to be reversed from this (i.e. WEB-INF/classes first, then WEB-INF/lib). The new spec also permits a web-app classloader to override classes in parent classloaders by using a look then delegate policy, rather than delegate than look in the usual Java2 fashion. (Tomcat 4's classloaders do both of these things, against a very similar overall hierarchy.) Neither of these behaviors is specified for 2.2, so you're pretty much free to do what you want. But you should think about implementing similar policies now, to improve the portability of apps to containers supporting 2.3. Costin Craig
Re: [jtc] anybody build iis plugin lately
I've fixed isapi.dsp and added an nmake Makefile (isapi.mak). I also had to fix a vouple of syntax errors in jk_isapi_plugin.c that I think were changes that Henri made in an attempt to bring the IIS connector in line with the latest jk code. One of the changes Henri had made was similar to a change he made in the Domino connector. For now I've commented out the lines in question, which I don't think will break anything, but to incorporate that change fully in the Domino connector I had to make some non trivial changes to the code to defer initialisation of the worker map until the first request is seen by the connector. I think I'd have to do the same thing with the IIS connector to make it work (basically the problem is that Henri's code is looking for the name of the server which isn't available either from IIS or from Domino until you're inside a real request). I can go ahead and make the necessary changes, but I'm concious that I might be stepping on someone else's toes given that I'm not really the maintainer of the IIS connector. Should I go ahead and do it? i haven't seen much movement in the iis connector for a while, and i have no idea whose baby it is :) i'd say go for it if you have some ideas to improve/fix it. people who are interested will see your changes and can view the diffs and if they have problems, they can speak up ;-)
Re: Anyone know why the ISAPI redirector works how it does?
well, i've never even looked at the iis connector, and i am by no means an isapi expert, but what you describe does sound odd... i was under the impression that the isapi filter was doing all of the work. didn't know there was an extension involved as well. perhaps you can, instead of mucking with the existing iis connector, just create a new one that uses only HttpFilterProc. that'd be cool with me :) Andy Armstrong wrote: I've been looking at the source of the ISAPI redirector (initially to get it to build again -- it seems to have broken), and wondering why it works the way it does. It provides both an HttpFilterProc and an HttpExtensionProc. The HttpFilterProc looks for incoming requests that are elligable to be handled by Tomcat and, if it finds one, it rewrites the request so that it will be passed to the HttpExtensionProc for processing. From a cursory glance at the ISAPI documentation it seems that this could all be handled in HttpFilterProc. Does anyone know what I'm missing? If there isn't a clear reason why it's implemented like this I might try and build a new ISAPI filter that works the same way as the Domino DSAPI filter. It should make request handling slightly faster, simplify the code and might make it possible to have some source in common between the Domino and IIS redirectors. -- Andy Armstrong, Tagish
cvs commit: jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33 Ajp13.java Ajp14.java Ajp14Interceptor.java
costin 01/06/23 12:04:35 Modified:jk/java/org/apache/ajp/tomcat33 Ajp13.java Ajp14.java Ajp14Interceptor.java Log: Few fixes on Ajp14. First, added many comments and make sure Ajp14Interceptor is fine. I plan few more changes to make it clearer, but it should be fine for now ( it's probably better than existing code in 3.3 ) Added few debug statements ( including display of the command name ). Started to add code from Ajp13, to avoid getting lost in inheritance. Ajp14 will replace Ajp13 completely, there are many improvements that need to be done to make ajp14 much faster and better. Right now I get a failure on reading the credentials, I'll fix it later this afternoon ( have to go now ). Revision ChangesPath 1.3 +2 -0 jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp13.java Index: Ajp13.java === RCS file: /home/cvs/jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp13.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Ajp13.java2001/06/22 10:32:21 1.2 +++ Ajp13.java2001/06/23 19:04:34 1.3 @@ -239,6 +239,7 @@ */ public int receiveNextRequest(Request req) throws IOException { + System.out.println(XXX); // XXX The return values are awful. int err = receive(hBuf); @@ -650,6 +651,7 @@ * was an error. **/ protected int receive(AjpPacket msg) throws IOException { + System.out.println(); // XXX If the length in the packet header doesn't agree with the // actual number of bytes read, it should probably return an error // value. Also, callers of this method never use the length 1.2 +264 -146 jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14.java Index: Ajp14.java === RCS file: /home/cvs/jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Ajp14.java2001/06/22 10:35:45 1.1 +++ Ajp14.java2001/06/23 19:04:34 1.2 @@ -96,167 +96,183 @@ */ public class Ajp14 extends Ajp13 { - // AJP14 commands - - // Initial Login Phase (web server - servlet engine) - public static final byte JK_AJP14_LOGINIT_CMD = 0x10; - - // Second Login Phase (servlet engine - web server), md5 seed is received - public static final byte JK_AJP14_LOGSEED_CMD = 0x11; - - // Third Login Phase (web server - servlet engine), md5 of seed + secret is sent - public static final byte JK_AJP14_LOGCOMP_CMD = 0x12; - - // Login Accepted (servlet engine - web server) - public static final byte JK_AJP14_LOGOK_CMD = 0x13; +// Original AJP13 commands +// Prefix codes for message types from server to container +public static final byte JK_AJP13_FORWARD_REQUEST = 2; +public static final byte JK_AJP13_SHUTDOWN = 7; + +// Prefix codes for message types from container to server +public static final byte JK_AJP13_SEND_BODY_CHUNK = 3; +public static final byte JK_AJP13_SEND_HEADERS = 4; +public static final byte JK_AJP13_END_RESPONSE = 5; +public static final byte JK_AJP13_GET_BODY_CHUNK= 6; + + + +// New AJP14 commands + +// Initial Login Phase (web server - servlet engine) +public static final byte JK_AJP14_LOGINIT_CMD= 0x10; + +// Second Login Phase (servlet engine - web server), md5 seed is received +public static final byte JK_AJP14_LOGSEED_CMD= 0x11; + +// Third Login Phase (web server - servlet engine), md5 of seed + secret is sent +public static final byte JK_AJP14_LOGCOMP_CMD= 0x12; + +// Login Accepted (servlet engine - web server) +public static final byte JK_AJP14_LOGOK_CMD = 0x13; - // Login Rejected (servlet engine - web server), will be logged +// Login Rejected (servlet engine - web server), will be logged public static final byte JK_AJP14_LOGNOK_CMD= 0x14; - - // Context Query (web server - servlet engine), which URI are handled by servlet engine ? - public static final byte JK_AJP14_CONTEXT_QRY_CMD = 0x15; - - // Context Info (servlet engine - web server), URI handled response - public static final byte JK_AJP14_CONTEXT_INFO_CMD = 0x16; - - // Context Update (servlet engine - web server), status of context changed - public static final byte JK_AJP14_CONTEXT_UPDATE_CMD=
cvs commit: jakarta-tomcat-4.0/tester/web/WEB-INF web.xml
craigmcc01/06/23 12:27:24 Modified:tester/src/bin tester.xml tester/web/WEB-INF web.xml Added: tester/src/tester/org/apache/tester Context00.java Context01.java Context02.java ContextBean.java Log: Add a set of unit tests for servlet context attributes. NOTE: If you uncomment the clearAttributes() call in StandardContext, and then run the ServletContext target in tester.xml, the application restart will fail on ClassNotFoundException errors on the listeners and filters. Revision ChangesPath 1.51 +52 -1 jakarta-tomcat-4.0/tester/src/bin/tester.xml Index: tester.xml === RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/bin/tester.xml,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- tester.xml2001/06/20 22:37:06 1.50 +++ tester.xml2001/06/23 19:27:24 1.51 @@ -15,7 +15,7 @@ taskdef name=tester classname=org.apache.tester.TestClient/ - target name=all depends=ROOT,Authentication,CaseSensitive,Decoding,ErrorPage,FilterRequest,FilterResponse,Jndi,RequestDispatcher,Resources,ServletRequest,ServletResponse,HttpSession,XercesTest,SSITest,CGITest/ + target name=all depends=ROOT,Authentication,CaseSensitive,Decoding,ErrorPage,FilterRequest,FilterResponse,Jndi,RequestDispatcher,Resources,ServletContext,ServletRequest,ServletResponse,HttpSession,XercesTest,SSITest,CGITest/ target name=ROOT @@ -852,6 +852,57 @@ debug=${debug} request=${context.path}/Resources06?path=/WEB-INF outContent=Resources06 PASSED/ + + /target + + + target name=ServletContext + +!-- == Servlet Context Attributes -- + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/Context00 + outContent=Context00 PASSED/ + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/Context01 + outContent=Context01 PASSED/ + +!-- NOTE: Assign role manager to user tomcat for this to work -- +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + inHeaders=Authorization:Basic dG9tY2F0OnRvbWNhdA== + request=${manager.path}/reload?path=${reload.path} + outContent=OK - Reloaded application at context path ${reload.path}/ + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/Context02 + outContent=Context02 PASSED/ + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/WrappedContext00 + outContent=Context00 PASSED/ + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/WrappedContext01 + outContent=Context01 PASSED/ + +!-- NOTE: Assign role manager to user tomcat for this to work -- +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + inHeaders=Authorization:Basic dG9tY2F0OnRvbWNhdA== + request=${manager.path}/reload?path=${reload.path} + outContent=OK - Reloaded application at context path ${reload.path}/ + +tester host=${host} port=${port} protocol=${protocol} + debug=${debug} + request=${context.path}/WrappedContext02 + outContent=Context02 PASSED/ /target 1.1 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Context00.java Index: Context00.java === /* = * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999, 2000 The Apache Software Foundation. * * All rights reserved.* * * * = * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * *notice, this list of
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardContext.java
craigmcc01/06/23 12:50:31 Modified:catalina/src/share/org/apache/catalina/core StandardContext.java Log: When reloading an application, call the init() method of all load-on-startup servlets so that they can restore any required application specific state that is required. These servlets will be called in the same order as when the application was first started, based on the load-on-startup values. Revision ChangesPath 1.65 +59 -48 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java Index: StandardContext.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v retrieving revision 1.64 retrieving revision 1.65 diff -u -r1.64 -r1.65 --- StandardContext.java 2001/06/23 19:25:24 1.64 +++ StandardContext.java 2001/06/23 19:50:30 1.65 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.64 2001/06/23 19:25:24 craigmcc Exp $ - * $Revision: 1.64 $ - * $Date: 2001/06/23 19:25:24 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.65 2001/06/23 19:50:30 craigmcc Exp $ + * $Revision: 1.65 $ + * $Date: 2001/06/23 19:50:30 $ * * * @@ -141,7 +141,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.64 $ $Date: 2001/06/23 19:25:24 $ + * @version $Revision: 1.65 $ $Date: 2001/06/23 19:50:30 $ */ public class StandardContext @@ -2392,6 +2392,9 @@ } } +// Reinitialize all load on startup servlets +loadOnStartup(children); + // Unbinding thread unbindThread(); @@ -3133,6 +3136,56 @@ /** + * Load and initialize all servlets marked load on startup in the + * web application deployment descriptor. + * + * @param children Array of wrappers for all currently defined + * servlets (including those not declared load on startup) + */ +public void loadOnStartup(Container children[]) { + +// Collect load on startup servlets that need to be initialized +TreeMap map = new TreeMap(); +for (int i = 0; i children.length; i++) { +Wrapper wrapper = (Wrapper) children[i]; +int loadOnStartup = wrapper.getLoadOnStartup(); +if (loadOnStartup 0) +continue; +if (loadOnStartup == 0) // Arbitrarily put them last +loadOnStartup = Integer.MAX_VALUE; +Integer key = new Integer(loadOnStartup); +ArrayList list = (ArrayList) map.get(key); +if (list == null) { +list = new ArrayList(); +map.put(key, list); +} +list.add(wrapper); +} + +// Load the collected load on startup servlets +Iterator keys = map.keySet().iterator(); +while (keys.hasNext()) { +Integer key = (Integer) keys.next(); +ArrayList list = (ArrayList) map.get(key); +Iterator wrappers = list.iterator(); +while (wrappers.hasNext()) { +Wrapper wrapper = (Wrapper) wrappers.next(); +try { +wrapper.load(); +} catch (ServletException e) { +log(sm.getString(standardWrapper.loadException, + getName()), e); +// NOTE: load errors (including a servlet that throws +// UnavailableException from tht init() method) are NOT +// fatal to application startup +} +} +} + +} + + +/** * Start this Context component. * * @exception LifecycleException if a startup error occurs @@ -3219,51 +3272,9 @@ log(Posting standard context attributes); postWelcomeFiles(); } - -// Collect load on startup servlets that need to be initialized -if (debug = 1) -log(Identifying load-on-startup servlets); -TreeMap map = new TreeMap(); -Container children[] = findChildren(); -for (int i = 0; i children.length; i++) { -Wrapper wrapper = (Wrapper) children[i]; -int loadOnStartup = wrapper.getLoadOnStartup(); -if (loadOnStartup 0) -continue; -if (loadOnStartup == 0) // Arbitrarily put them last -loadOnStartup = Integer.MAX_VALUE; -
Re: [jtc] anybody build iis plugin lately
kevin seguin wrote: I've fixed isapi.dsp and added an nmake Makefile (isapi.mak). I also had to fix a vouple of syntax errors in jk_isapi_plugin.c that I think were changes that Henri made in an attempt to bring the IIS connector in line with the latest jk code. One of the changes Henri had made was similar to a change he made in the Domino connector. For now I've commented out the lines in question, which I don't think will break anything, but to incorporate that change fully in the Domino connector I had to make some non trivial changes to the code to defer initialisation of the worker map until the first request is seen by the connector. I think I'd have to do the same thing with the IIS connector to make it work (basically the problem is that Henri's code is looking for the name of the server which isn't available either from IIS or from Domino until you're inside a real request). I can go ahead and make the necessary changes, but I'm concious that I might be stepping on someone else's toes given that I'm not really the maintainer of the IIS connector. Should I go ahead and do it? i haven't seen much movement in the iis connector for a while, and i have no idea whose baby it is :) i'd say go for it if you have some ideas to improve/fix it. people who are interested will see your changes and can view the diffs and if they have problems, they can speak up ;-) Yup I think I'll give it a bash. -- Andy Armstrong, Tagish
Re: Anyone know why the ISAPI redirector works how it does?
kevin seguin wrote: well, i've never even looked at the iis connector, and i am by no means an isapi expert, but what you describe does sound odd... i was under the impression that the isapi filter was doing all of the work. didn't know there was an extension involved as well. It's not a big deal -- just two entry points into the same DLL, so you wouldn't notice from outside, but it does seem a bit odd. perhaps you can, instead of mucking with the existing iis connector, just create a new one that uses only HttpFilterProc. that'd be cool with me :) I'll give it a go. It might be next week unless I go to the office and grab a box to make into an IIS server for home. Still, what else are weekends for. -- Andy Armstrong, Tagish
Re: Classpath Ordering: Questions, and possible contrib.
On Sat, 23 Jun 2001, Craig R. McClanahan wrote: A) the hierarchy should go: SystemCL | -- LAYER 1 lib/common CL / \ -- LAYER 2 lib/container lib/apps CL |-- LAYER 3 WEB-INF/libsame CL, but with URLs WEB-INF/classes from both dirs, in this order... You are absolutely right, that's the intended hierarchy. One thing you might want to note for the future is that, in servlet 2.3, the order of loading in the web-app classloader is specified to be reversed from this (i.e. WEB-INF/classes first, then WEB-INF/lib). The new spec also permits a web-app classloader to override classes in parent classloaders by using a look then delegate policy, rather than delegate than look in the usual Java2 fashion. (Tomcat 4's classloaders do both of these things, against a very similar overall hierarchy.) Neither of these behaviors is specified for 2.2, so you're pretty much free to do what you want. But you should think about implementing similar policies now, to improve the portability of apps to containers supporting 2.3. That's why we have pluggable loader - if someone wants such a behavior he's free to implement a loader. For servlet 2.2 we are not required, and I'm not going to. And it shouldn't matter anyway - since the common loader is supposed to have minimal stuff ( javax, other things that should not be overriden without major risks for security - even if the 2.3 spec would require them to be - I'm talking about some common utils ). I believe there are important security issues, but I'm sure the spec took this into consideration - so probably I'm wrong ( of course, this will be easy to verify later on, there are quite a few ways someone could try to exploit a reversed order - but again I'm sure this was taken care of and it'll be just the fun of trying :-). Costin
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardContext.java
remm01/06/23 14:55:39 Modified:catalina/src/share/org/apache/catalina/core StandardContext.java Log: - Reset the Jasper class loader when reloading, so that a new one will be created. Jasper was always using the old (destroyed) CL before. - Make the work directory attribute a protected attribute (since its value will never have to change). That protects it when clearing the attributes during a reload (before, the CL setup was failing after a reload because it couldn't find the work attribute). - Cleaned up a bit the binding / unbing order. Before, the old CL was still bound when reloading the classes for the listeners. This shouldn't have any real world effect, but it still is more correct this way. Revision ChangesPath 1.66 +36 -7 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java Index: StandardContext.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v retrieving revision 1.65 retrieving revision 1.66 diff -u -r1.65 -r1.66 --- StandardContext.java 2001/06/23 19:50:30 1.65 +++ StandardContext.java 2001/06/23 21:55:39 1.66 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.65 2001/06/23 19:50:30 craigmcc Exp $ - * $Revision: 1.65 $ - * $Date: 2001/06/23 19:50:30 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.66 2001/06/23 21:55:39 remm Exp $ + * $Revision: 1.66 $ + * $Date: 2001/06/23 21:55:39 $ * * * @@ -141,7 +141,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.65 $ $Date: 2001/06/23 19:50:30 $ + * @version $Revision: 1.66 $ $Date: 2001/06/23 21:55:39 $ */ public class StandardContext @@ -2305,8 +2305,8 @@ } // Clear all application-originated servlet context attributes -//if (context != null) -//context.clearAttributes(); +if (context != null) +context.clearAttributes(); // Shut down filters and application event listeners filterStop(); @@ -2321,6 +2321,12 @@ } } +// Binding thread +unbindThread(); + +// Dump the old Jasper loader +jasperLoader = null; + // Shut down our application class loader if ((loader != null) (loader instanceof Lifecycle)) { try { @@ -2352,6 +2358,18 @@ } } +// Binding thread +bindThread(); + +ClassLoader oldCtxClassLoader = +Thread.currentThread().getContextClassLoader(); + ClassLoader classLoader = loader.getClassLoader(); + +// Set the context class loader +if (classLoader != null) { +Thread.currentThread().setContextClassLoader(classLoader); +} + // Restart our session manager (AFTER naming context recreated/bound) if ((manager != null) (manager instanceof Lifecycle)) { try { @@ -2375,6 +2393,11 @@ } } +// Set the context class loader to the old class loader +if (classLoader != null) { +Thread.currentThread().setContextClassLoader(oldCtxClassLoader); +} + // Restart our currently defined servlets for (int i = 0; i children.length; i++) { if (!ok) @@ -3329,6 +3352,9 @@ // Unbinding thread unbindThread(); +// Dump the old Jasper loader +jasperLoader = null; + if (debug = 1) log(Stopping complete); @@ -3769,7 +3795,10 @@ // Set the appropriate servlet context attribute getServletContext().setAttribute(Globals.WORK_DIR_ATTR, dir); - +if (getServletContext() instanceof ApplicationContext) +((ApplicationContext) getServletContext()).setAttributeReadOnly +(Globals.WORK_DIR_ATTR); + }
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardWrapper.java
remm01/06/23 14:56:38 Modified:catalina/src/share/org/apache/catalina/core StandardWrapper.java Log: - Make sure the old CL is bound after loading the servlet class. If there was an exception, the new CL could remain bound. Revision ChangesPath 1.25 +40 -13 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java Index: StandardWrapper.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- StandardWrapper.java 2001/05/14 04:51:19 1.24 +++ StandardWrapper.java 2001/06/23 21:56:38 1.25 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.24 2001/05/14 04:51:19 craigmcc Exp $ - * $Revision: 1.24 $ - * $Date: 2001/05/14 04:51:19 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.25 2001/06/23 21:56:38 remm Exp $ + * $Revision: 1.25 $ + * $Date: 2001/06/23 21:56:38 $ * * * @@ -105,7 +105,7 @@ * make them efficient are counter-productive. * * @author Craig R. McClanahan - * @version $Revision: 1.24 $ $Date: 2001/05/14 04:51:19 $ + * @version $Revision: 1.25 $ $Date: 2001/06/23 21:56:38 $ */ public final class StandardWrapper @@ -785,24 +785,39 @@ log(sm.getString(standardWrapper.jasperLoader, getName())); } +// Set the context class loader +if (classLoader != null) { +Thread.currentThread().setContextClassLoader(classLoader); +} + // Load the specified servlet class from the appropriate class loader Class classClass = null; try { - if (classLoader != null) + if (classLoader != null) { classClass = classLoader.loadClass(actualClass); - else + } else { classClass = Class.forName(actualClass); +} } catch (ClassNotFoundException e) { unavailable(null); +// Restore the context ClassLoader + if (classLoader != null) { +Thread.currentThread().setContextClassLoader +(oldCtxClassLoader); +} throw new ServletException (sm.getString(standardWrapper.missingClass, actualClass), e); } if (classClass == null) { - unavailable(null); - throw new ServletException - (sm.getString(standardWrapper.missingClass, actualClass)); - } +unavailable(null); +if (classLoader != null) { +Thread.currentThread().setContextClassLoader +(oldCtxClassLoader); +} +throw new ServletException +(sm.getString(standardWrapper.missingClass, actualClass)); +} // Instantiate and initialize an instance of the servlet class itself Servlet servlet = null; @@ -810,10 +825,20 @@ servlet = (Servlet) classClass.newInstance(); } catch (ClassCastException e) { unavailable(null); +// Restore the context ClassLoader + if (classLoader != null) { +Thread.currentThread().setContextClassLoader +(oldCtxClassLoader); +} throw new ServletException (sm.getString(standardWrapper.notServlet, actualClass), e); } catch (Throwable e) { unavailable(null); +// Restore the context ClassLoader + if (classLoader != null) { +Thread.currentThread().setContextClassLoader +(oldCtxClassLoader); +} throw new ServletException (sm.getString(standardWrapper.instantiate, actualClass), e); } @@ -829,7 +854,6 @@ try { instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT, servlet); -Thread.currentThread().setContextClassLoader(classLoader); servlet.init(facade); instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet); @@ -852,8 +876,11 @@ throw new ServletException (sm.getString(standardWrapper.initException, getName()), f); } finally { -// restore the context ClassLoader -Thread.currentThread().setContextClassLoader(oldCtxClassLoader); +// Restore the
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader WebappLoader.java
remm01/06/23 15:30:05 Modified:catalina/src/share/org/apache/catalina/loader WebappLoader.java Log: - Don't copy the JARs to the work directory if filesystem based. Revision ChangesPath 1.7 +34 -20 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappLoader.java Index: WebappLoader.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappLoader.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- WebappLoader.java 2001/06/21 01:39:08 1.6 +++ WebappLoader.java 2001/06/23 22:30:04 1.7 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappLoader.java,v 1.6 2001/06/21 01:39:08 remm Exp $ - * $Revision: 1.6 $ - * $Date: 2001/06/21 01:39:08 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappLoader.java,v 1.7 2001/06/23 22:30:04 remm Exp $ + * $Revision: 1.7 $ + * $Date: 2001/06/23 22:30:04 $ * * * @@ -119,7 +119,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.6 $ $Date: 2001/06/21 01:39:08 $ + * @version $Revision: 1.7 $ $Date: 2001/06/23 22:30:04 $ */ public class WebappLoader @@ -608,12 +608,13 @@ // Construct a class loader based on our current repositories list try { - if (parentClassLoader == null) - classLoader = new WebappClassLoader(container.getResources()); - else - classLoader = new WebappClassLoader -(parentClassLoader, container.getResources()); +if (parentClassLoader == null) { +classLoader = new WebappClassLoader(container.getResources()); +} else { +classLoader = new WebappClassLoader +(parentClassLoader, container.getResources()); +} classLoader.setDebug(this.debug); classLoader.setDelegate(this.delegate); @@ -907,8 +908,18 @@ if (libDir != null) { -File destDir = new File(workDir, libPath); -destDir.mkdirs(); +boolean copyJars = false; +String absoluteLibPath = servletContext.getRealPath(libPath); + +File destDir = null; + +if (absoluteLibPath != null) { +destDir = new File(absoluteLibPath); +} else { +copyJars = true; +destDir = new File(workDir, libPath); +destDir.mkdirs(); +} // Looking up directory /WEB-INF/lib in the context try { @@ -929,18 +940,21 @@ destFile.getAbsolutePath())); Resource jarResource = (Resource) binding.getObject(); -if (copy(jarResource.streamContent(), - new FileOutputStream(destFile))) { -if (classpath.length() != 0) -classpath.append(File.pathSeparator); -classpath.append(destFile.getAbsolutePath()); +if (copyJars) { +if (!copy(jarResource.streamContent(), + new FileOutputStream(destFile))) +continue; } - + +if (classpath.length() != 0) +classpath.append(File.pathSeparator); +classpath.append(destFile.getAbsolutePath()); + JarFile jarFile = new JarFile(destFile); - + classLoader.addJar(filename, jarFile, destFile); addRepository(filename); - + } } catch (NamingException e) { // Silent catch: it's valid that no /WEB-INF/lib directory @@ -1255,7 +1269,7 @@ */ public void run() { - context.reload(); +context.reload(); }
[GUMP] Build Failure - Tomcat 3.x
This email is autogenerated from the output from: http://jakarta.apache.org/builds/gump/2001-06-23/jakarta-tomcat.html Buildfile: build.xml detect: msg.jdk12: [echo] Detected JDK1.2 msg.jsse: [echo] Detected JSSE msg.jtc: msg.jtj: msg.commons-dbcp: init: prepare: [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/conf [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/src [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/classes [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/lib [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/lib/apps [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/lib/container [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/lib/common [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/logs [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/bin [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/doc [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/webapps [mkdir] Created dir: /home/rubys/jakarta/jakarta-tomcat/build/tomcat/native [copy] Copying 10 files to /home/rubys/jakarta/jakarta-tomcat/build/tomcat/bin [copy] Copying 21 files to /home/rubys/jakarta/jakarta-tomcat/build/tomcat/conf [copy] Copying 43 files to /home/rubys/jakarta/jakarta-tomcat/build/tomcat/doc [copy] Copying 89 files to /home/rubys/jakarta/jakarta-tomcat/build/tomcat/native [copy] Copying 1 file to /home/rubys/jakarta/jakarta-tomcat/build/tomcat [copy] Copying 1 file to /home/rubys/jakarta/jakarta-tomcat/build/tomcat [copy] Copying 1 file to /home/rubys/jakarta/jakarta-tomcat/build/tomcat/lib/container [copy] Could not find file /opt/jaxp-1.1/parser.jar to copy. BUILD FAILED /home/rubys/jakarta/jakarta-tomcat/build.xml:153: Could not find file /opt/jaxp-1.1/parser.jar to copy. Total time: 6 seconds
RE: Anyone know why the ISAPI redirector works how it does?
I think this was done this way because every request on a IIS server pass the entire Filter Chain, so a request that takes longer to be served simply occupies the server thread more than necesssary , I'm -1 for this change ... Saludos , Ignacio J. Ortega -Mensaje original- De: Andy Armstrong [mailto:[EMAIL PROTECTED]] Enviado el: sábado 23 de junio de 2001 20:02 Para: Tomcat Dev Cc: Gal Shachor Asunto: Anyone know why the ISAPI redirector works how it does? I've been looking at the source of the ISAPI redirector (initially to get it to build again -- it seems to have broken), and wondering why it works the way it does. It provides both an HttpFilterProc and an HttpExtensionProc. The HttpFilterProc looks for incoming requests that are elligable to be handled by Tomcat and, if it finds one, it rewrites the request so that it will be passed to the HttpExtensionProc for processing. From a cursory glance at the ISAPI documentation it seems that this could all be handled in HttpFilterProc. Does anyone know what I'm missing? If there isn't a clear reason why it's implemented like this I might try and build a new ISAPI filter that works the same way as the Domino DSAPI filter. It should make request handling slightly faster, simplify the code and might make it possible to have some source in common between the Domino and IIS redirectors. -- Andy Armstrong, Tagish
Re: Anyone know why the ISAPI redirector works how it does?
Yes, but at the moment every IIS request gets passed to the filter chain /and/ to the extension. What I'm proposing /must/ be faster. Please explain your objection. Ignacio J. Ortega wrote: I think this was done this way because every request on a IIS server pass the entire Filter Chain, so a request that takes longer to be served simply occupies the server thread more than necesssary , I'm -1 for this change ... Saludos , Ignacio J. Ortega -Mensaje original- De: Andy Armstrong [mailto:[EMAIL PROTECTED]] Enviado el: sábado 23 de junio de 2001 20:02 Para: Tomcat Dev Cc: Gal Shachor Asunto: Anyone know why the ISAPI redirector works how it does? I've been looking at the source of the ISAPI redirector (initially to get it to build again -- it seems to have broken), and wondering why it works the way it does. It provides both an HttpFilterProc and an HttpExtensionProc. The HttpFilterProc looks for incoming requests that are elligable to be handled by Tomcat and, if it finds one, it rewrites the request so that it will be passed to the HttpExtensionProc for processing. From a cursory glance at the ISAPI documentation it seems that this could all be handled in HttpFilterProc. Does anyone know what I'm missing? If there isn't a clear reason why it's implemented like this I might try and build a new ISAPI filter that works the same way as the Domino DSAPI filter. It should make request handling slightly faster, simplify the code and might make it possible to have some source in common between the Domino and IIS redirectors. -- Andy Armstrong, Tagish -- Andy Armstrong, Tagish
Re: Classpath Ordering: Questions, and possible contrib.
On Sat, 23 Jun 2001 [EMAIL PROTECTED] wrote: On Sat, 23 Jun 2001, Glenn Nielsen wrote: I believe there are important security issues, but I'm sure the spec took this into consideration - so probably I'm wrong ( of course, this will be easy to verify later on, there are quite a few ways someone could try to exploit a reversed order - but again I'm sure this was taken care of and it'll be just the fun of trying :-). Yes there are security issues related to the Servlet 2.3 spec webapp CL. Fortunately, the Java SecurityManager can protect you if you use checkPackageDefinition() in the CL. This can prevent a Servlet 2.3 webapp CL from redefining system or other sensitive classes. That's only part of the problem and only part of the solution :-) I'm not going to argue to much about this - the archives of tomcat-dev are available, no need to repeat :-) It all depends on how you define 'sensitive classes' - what is not sensitive and how you decide so ? It's turning the problem around, from don't trust anything to don't trust specific things - and that's considered dangerous by some other people. Servlet 2.3 PFD2, defines sensitive for the purposes of conformance: J2SE and servlet API classes. I'm looking forward to see implementations and how they'll address the issues ( I'm very curious about drivers and libraries that require extra permissions - are you going to grant the permission on the whole app ? Add them to the list of sensitive ? The loader implementation will be fun - at least ). For now, tomcat3.3 should be ok - the recomended configuration is with minimal classes in common and classpath, webapps should be self-contained or use standard APIs - and those APIs are considered sensitive. That mean whatever is placed in Classpath and common is sensitive and can't be overriden ( and it is sensitive indeed - as it usually have bigger permissions than the app itself ). The container is in a separated classpath, so you can use anything inside without interfering with the webapps, and with the ProfileLoader it's easy to have fine control over what you make available to each webapp. Since what's sensitive is not defined ( I assume you can say 'javax and java', but then you're open to big problems ) the behavior should be ok even from servlet2.3 perspective - we treat everything in common/system as sensitive ( no risk taken ), and the app class loader has nothing to override :-) Everything in life is a tradeoff. With your delegate first model, you are out of luck if someone *has* installed a shareable library (like an XML parser or a JDBC driver) into the common directory, and you need a different version. Telling them but you shouldn't do that is not going to be satisfactory to all users. Anyway, I'm not suggesting that you MUST implement something similar -- I'm just suggesting that you would be nicer to your users if you anticipated some of the things that 2.3 does allow, and that are not specified in 2.2, to improve their migration experience. Costin Craig
RE: Anyone know why the ISAPI redirector works how it does?
AFAIK only the request that need to be served by the Extension , that is request that match the config present in UWM.P file are routed to the extension , that runs in other priority thread, if you serve the Tomcat request directly from the filter therad you are blocking the filter thread in Tomcat.., and i repeat *ALL* the request served by an IIS server are passed to ALL the filters..not only the Tomcat one.. so if the ISAPI extension were working like you are proposing you are blocking the main server thread waiting for tomcat to serve the request, many unrelated request will be slowed appreciably and the overall capacity of the server will be greatly impacted... I think there are good reasons to keep things as they are now...i dont found a good reason , apart from code complexity , to do what you are proposing ..but i'm not a ISAPI expert...I could be wrong.. i'm only repeating to you the reasons Gal said to my many time ago.. you can consult archives about May past year .. (i'm doing so now i wil try to document it ) But i'm open to test and help in what you are proposing .. i'm not trying to block you from doing so .. i'm only trying to left the old code as it is, you can do what you are proposing in another directory in jtc and call it with a funny name ( IISTHAR ? :), and we can test and use it as an alternative .. if everything works as you expect .. good .. if not we still have that good old code ... users need a escape way from developers. :) Saludos , Ignacio J. Ortega -Mensaje original- De: Andy Armstrong [mailto:[EMAIL PROTECTED]] Enviado el: domingo 24 de junio de 2001 1:18 Para: [EMAIL PROTECTED] Asunto: Re: Anyone know why the ISAPI redirector works how it does? Yes, but at the moment every IIS request gets passed to the filter chain /and/ to the extension. What I'm proposing /must/ be faster. Please explain your objection. Ignacio J. Ortega wrote: I think this was done this way because every request on a IIS server pass the entire Filter Chain, so a request that takes longer to be served simply occupies the server thread more than necesssary , I'm -1 for this change ... Saludos , Ignacio J. Ortega -Mensaje original- De: Andy Armstrong [mailto:[EMAIL PROTECTED]] Enviado el: sábado 23 de junio de 2001 20:02 Para: Tomcat Dev Cc: Gal Shachor Asunto: Anyone know why the ISAPI redirector works how it does? I've been looking at the source of the ISAPI redirector (initially to get it to build again -- it seems to have broken), and wondering why it works the way it does. It provides both an HttpFilterProc and an HttpExtensionProc. The HttpFilterProc looks for incoming requests that are elligable to be handled by Tomcat and, if it finds one, it rewrites the request so that it will be passed to the HttpExtensionProc for processing. From a cursory glance at the ISAPI documentation it seems that this could all be handled in HttpFilterProc. Does anyone know what I'm missing? If there isn't a clear reason why it's implemented like this I might try and build a new ISAPI filter that works the same way as the Domino DSAPI filter. It should make request handling slightly faster, simplify the code and might make it possible to have some source in common between the Domino and IIS redirectors. -- Andy Armstrong, Tagish -- Andy Armstrong, Tagish
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core StandardContext.java
craigmcc01/06/23 16:59:11 Modified:catalina/src/share/org/apache/catalina/core StandardContext.java Log: Remove a FIXME comment since we have dealt with this issue. Revision ChangesPath 1.68 +4 -7 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java Index: StandardContext.java === RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v retrieving revision 1.67 retrieving revision 1.68 diff -u -r1.67 -r1.68 --- StandardContext.java 2001/06/23 23:41:51 1.67 +++ StandardContext.java 2001/06/23 23:59:10 1.68 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.67 2001/06/23 23:41:51 craigmcc Exp $ - * $Revision: 1.67 $ - * $Date: 2001/06/23 23:41:51 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardContext.java,v 1.68 2001/06/23 23:59:10 craigmcc Exp $ + * $Revision: 1.68 $ + * $Date: 2001/06/23 23:59:10 $ * * * @@ -141,7 +141,7 @@ * * @author Craig R. McClanahan * @author Remy Maucherat - * @version $Revision: 1.67 $ $Date: 2001/06/23 23:41:51 $ + * @version $Revision: 1.68 $ $Date: 2001/06/23 23:59:10 $ */ public class StandardContext @@ -2261,9 +2261,6 @@ * of our class loader. It does not handle changes to the web application * deployment descriptor. If that has occurred, you should stop this * Context and create (and start) a new Context instance instead. - * p - * bFIXME/b: What about context attributes that have been created - * by servlets? ClassCastException? * * @exception IllegalStateException if the codereloadable/code * property is set to codefalse/code.
cvs commit: jakarta-tomcat-4.0/tester/web/WEB-INF web.xml
craigmcc01/06/23 17:00:07 Modified:tester/src/tester/org/apache/tester Context01.java ContextBean.java tester/web/WEB-INF web.xml Added: tester/src/tester/org/apache/tester ContextListener01.java Log: Extend the new context tests so that they check for correct calls to the appropriate context event listeners as well. Revision ChangesPath 1.2 +50 -9 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Context01.java Index: Context01.java === RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Context01.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Context01.java2001/06/23 19:27:24 1.1 +++ Context01.java2001/06/24 00:00:05 1.2 @@ -71,7 +71,7 @@ * present, which should be erased after a web application restart. * * @author Craig R. McClanahan - * @version $Revision: 1.1 $ $Date: 2001/06/23 19:27:24 $ + * @version $Revision: 1.2 $ $Date: 2001/06/24 00:00:05 $ */ public class Context01 extends HttpServlet { @@ -94,7 +94,9 @@ // Create and stash a context attribute if (ok) { -context.setAttribute(context01, This is Context01); +ContextBean bean = new ContextBean(); +bean.setStringProperty(Context01); +context.setAttribute(context01, bean); } // Ensure that we can retrieve the attribute successfully @@ -103,18 +105,57 @@ if (bean == null) { writer.println(Context01 FAILED - Cannot retrieve attribute); ok = false; -} else if (!(bean instanceof String)) { -writer.println(Context01 FAILED - Attribute instance of + - bean.getClass().getName()); -ok = false; -} else { -String value = (String) bean; -if (!This is Context01.equals(value)) { +} +if (ok) { +if (!(bean instanceof ContextBean)) { +writer.println(Context01 FAILED - Bean instance of + + bean.getClass().getName()); +ok = false; +} +} +if (ok) { +String value = ((ContextBean) bean).getStringProperty(); +if (!Context01.equals(value)) { writer.println(Context01 FAILED - Value = + value); ok = false; } } +if (ok) { +String lifecycle = ((ContextBean) bean).getLifecycle(); +if (!/add.equals(lifecycle)) { +writer.println(Context01 FAILED - Bean lifecycle is + + lifecycle); +ok = false; +} +} } + +// Ensure that we can update this attribute and check its lifecycle +if (ok) { +ContextBean bean = (ContextBean) context.getAttribute(context01); +context.setAttribute(context01, bean); +String lifecycle = bean.getLifecycle(); +if (!/add/rep.equals(lifecycle)) { +writer.println(Context01 FAILED - Bean lifecycle is + + lifecycle); +ok = false; +} +} + +// Ensure that we can remove this attribute and check its lifecycle +if (ok) { +ContextBean bean = (ContextBean) context.getAttribute(context01); +context.removeAttribute(context01); +String lifecycle = bean.getLifecycle(); +if (!/add/rep/rem.equals(lifecycle)) { +writer.println(Context01 FAILED - Bean lifecycle is + + lifecycle); +ok = false; +} +} + +// Add a bean back for the restart application test +context.setAttribute(context01, new ContextBean()); // Ensure that setAttribute(name, null) works correctly if (ok) { 1.2 +18 -2 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/ContextBean.java Index: ContextBean.java === RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/ContextBean.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ContextBean.java 2001/06/23 19:27:24 1.1 +++ ContextBean.java 2001/06/24 00:00:05 1.2 @@ -65,7 +65,7 @@ * Simple JavaBean to use for context attribute tests. * * @author Craig R. McClanahan - * @version
Re: Classpath Ordering: Questions, and possible contrib.
On Sat, 23 Jun 2001, Craig R. McClanahan wrote: Servlet 2.3 PFD2, defines sensitive for the purposes of conformance: J2SE and servlet API classes. Well, that's not very good if you have a sensitive driver ( a native JDBC for friver for example ) or similar. But if this is the definition - it'll be even more interesting to watch :-) With your delegate first model, you are out of luck if someone *has* installed a shareable library (like an XML parser or a JDBC driver) into the common directory, and you need a different version. Telling them but you shouldn't do that is not going to be satisfactory to all users. Interesting example. First of all, if the admin is installing a particular version of a JDBC driver - he probably has reasons to ( like the fact that the database in use _needs_ that particular version - something a webapp can't easily know ). Not to mention that the driver usually needs at least permission to connect to the database ( if not JNI ). It'll be even more fun to watch how the class loader deal with that ( do you grant permission ? bad luck for security. Don't allow the user to override that particular driver - bad luck, you brake the spec ). Even for XML - if the server admin has installed a particular XML parser in the common dir, he might have reasons to. Like a XML-based database, or maybe XSLTC ( which requires extra permissions, again ) - things a webapp can't control ( if it is portable ). Anyway, I'm not suggesting that you MUST implement something similar -- I'm just suggesting that you would be nicer to your users if you anticipated some of the things that 2.3 does allow, and that are not specified in 2.2, to improve their migration experience. I agree with that for most parts - for class loader I'm afraid I do not know any way to implement the 2.3 requirement that does not compromise security ( or risk other side-effects and the stability - class loaders are extremely sensitive ), so I can't help. I'm sure smarter people will prove I'm wrong ( since I believe the whole concept is broken ), and find a solution to all those issues. ( the same as I was proved wrong regarding the facades :-) Costin ( sorry, this is intersting - but I have some work to do, I think we already discussed this subject few months ago, nothing important changed )
cvs commit: jakarta-tomcat-4.0/tester/src/tester/org/apache/tester Context02.java
craigmcc01/06/23 17:08:25 Modified:tester/src/tester/org/apache/tester Context02.java Log: Check attribute lifecycle on the beans stored by Context00 and ContextListener01 as well. Revision ChangesPath 1.2 +37 -1 jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Context02.java Index: Context02.java === RCS file: /home/cvs/jakarta-tomcat-4.0/tester/src/tester/org/apache/tester/Context02.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Context02.java2001/06/23 19:27:24 1.1 +++ Context02.java2001/06/24 00:08:24 1.2 @@ -74,7 +74,7 @@ * be cleaned up during a restart. * * @author Craig R. McClanahan - * @version $Revision: 1.1 $ $Date: 2001/06/23 19:27:24 $ + * @version $Revision: 1.2 $ $Date: 2001/06/24 00:08:24 $ */ public class Context02 extends HttpServlet { @@ -114,6 +114,42 @@ writer.println(Context02 FAILED - context00 value + value); ok = false; +} else { +String lifecycle = ((ContextBean) bean).getLifecycle(); +if (!/add.equals(lifecycle)) { +writer.println(Context02 FAILED - + +context00 lifecycle + + lifecycle); +ok = false; +} +} +} +} + +// Check for the attribute from ContextListener01 +if (ok) { +Object bean = context.getAttribute(contextListener01); +if (bean == null) { +writer.println(Context02 FAILED - contextListener01 missing); +ok = false; +} else if (!(bean instanceof ContextBean)) { +writer.println(Context02 FAILED - contextListener01 class + + bean.getClass().getName()); +ok = false; +} else { +String value = ((ContextBean) bean).getStringProperty(); +if (!ContextListener01.equals(value)) { +writer.println(Context02 FAILED - contextListener01 + + value + value); +ok = false; +} else { +String lifecycle = ((ContextBean) bean).getLifecycle(); +if (!/add.equals(lifecycle)) { +writer.println(Context02 FAILED - + +contextListener01 lifecycle + + lifecycle); +ok = false; +} } } }
Re: Anyone know why the ISAPI redirector works how it does?
Ignacio J. Ortega wrote: AFAIK only the request that need to be served by the Extension , that is request that match the config present in UWM.P file are routed to the extension , that runs in other priority thread, if you serve the Tomcat request directly from the filter therad you are blocking the filter thread in Tomcat.., and i repeat *ALL* the request served by an IIS server are passed to ALL the filters..not only the Tomcat one.. so if the ISAPI extension were working like you are proposing you are blocking the main server thread waiting for tomcat to serve the request, many unrelated request will be slowed appreciably and the overall capacity of the server will be greatly impacted... Thanks Ignacio; I understand what you're saying now. If all the filters run in the same thread that implies that IIS handles all its requests in a single thread, which seems unlikely, but of course I could be wrong. I think there are good reasons to keep things as they are now...i dont found a good reason , apart from code complexity , to do what you are proposing ..but i'm not a ISAPI expert...I could be wrong.. i'm only repeating to you the reasons Gal said to my many time ago.. you can consult archives about May past year .. (i'm doing so now i wil try to document it ) I'd be interested in anything you can find. I don't expect it to involve too much work, so I'm going to build it and do some performance testing to find out if there are any problems. From what you're saying the performance problem to look for would be lots of Tomcat requests having an adverse affect on the performance for non-Tomcat IIS requests. But i'm open to test and help in what you are proposing .. i'm not trying to block you from doing so .. i'm only trying to left the old code as it is, you can do what you are proposing in another directory in jtc and call it with a funny name ( IISTHAR ? :), and we can test and use it as an alternative .. if everything works as you expect .. good .. if not we still have that good old code ... users need a escape way from developers. :) I'm putting it in a directory called 'isapi' and leaving 'iis' intact. In any case I have some more work to do on the existing IIS redirector to make it work properly with the latest jk code, but that's a separate issue, and I won't do anything too scary to the current IIS code. -- Andy Armstrong, Tagish
RE: Anyone know why the ISAPI redirector works how it does?
Hola Andy: Thanks Ignacio; I understand what you're saying now. If all the filters run in the same thread that implies that IIS handles all its requests in a single thread, which seems unlikely, but of course I could be wrong. What i'm trying to say is not that, is evident that IIS does not serve all the request from the same thread .. only that every filter is called in ALL the IIS request.. ergo if you start to block server threads in tomcat requests you are pushing innecesarily the IIS server... at least the thread pool that is used to serve requests.. I'd be interested in anything you can find. I don't expect it to involve too much work, so I'm going to build it and do some performance testing to find out if there are any problems. From what you're saying the performance problem to look for would be lots of Tomcat requests having an adverse affect on the performance for non-Tomcat IIS requests. This is the bad behaviour the filter+Extension mix is trying to avoid.. I'm putting it in a directory called 'isapi' and leaving 'iis' intact. In any case I have some more work to do on the existing IIS redirector to make it work properly with the latest jk code, but that's a separate issue, and I won't do anything too scary to the current IIS code. Thanks, this is was my -1 was intended for.. -- Andy Armstrong, Tagish Saludos , Ignacio J. Ortega
Re: Anyone know why the ISAPI redirector works how it does?
Ignacio J. Ortega wrote: Hola Andy: Thanks Ignacio; I understand what you're saying now. If all the filters run in the same thread that implies that IIS handles all its requests in a single thread, which seems unlikely, but of course I could be wrong. What i'm trying to say is not that, is evident that IIS does not serve all the request from the same thread .. only that every filter is called in ALL the IIS request.. ergo if you start to block server threads in tomcat requests you are pushing innecesarily the IIS server... at least the thread pool that is used to serve requests.. I would have thought that IIS's threading model was designed to handle that. There must be other cases where an in-process request can stall for a significant period of time; can it really be the case that this causes problems for the server as a whole? In any case I suspect I am about to find out ;-) I'd be interested in anything you can find. I don't expect it to involve too much work, so I'm going to build it and do some performance testing to find out if there are any problems. From what you're saying the performance problem to look for would be lots of Tomcat requests having an adverse affect on the performance for non-Tomcat IIS requests. This is the bad behaviour the filter+Extension mix is trying to avoid.. I understand that. What I'm saying is that if I can detect any performance degradation for non-Tomcat requests I will have failed. I'm putting it in a directory called 'isapi' and leaving 'iis' intact. In any case I have some more work to do on the existing IIS redirector to make it work properly with the latest jk code, but that's a separate issue, and I won't do anything too scary to the current IIS code. Thanks, this is was my -1 was intended for.. So, +1 for trying a different approach without breaking what's already there? -- Andy Armstrong, Tagish
RE: Classpath Ordering: Questions, and possible contrib.
Hola a Todos,David: Thanks for take a look in this area, is hard to test and has little to nothing review and is plenty of big traps ( as the last found ) .. One of the most hard things that TC33 does is to hide the complexity of JDK11 and 12 compatibility without to much hassle for the poor devs that deal with CL.., all that great work was made by Costin .. ( Perplexity was the word :))) I only did a some startup work ( Main class ) and test it.., and the big trick of it was to make Jasper work consistently when used as a servlet ( that is in webapp CL ) or when used as interceptor ( container CL ) .. and the trick now is to simply walk down the CL chain adding every Classpath found in the CL to the classpath of the java compiler used to compile JSPs think on it taking into account that this works well and trasparently ( mostly ) using JDK11 ( that has a non delegating CL scheme ) and JDK12 ( that uses the beloved and quick URLClassloader and a delegating scheme ).. this was the really hard part !!! ( More Comments intermixed ) Hi folks, I've been having a peek at the Tomcat main CVS branch in respect of its classloading behaviour. Apologies if I have missed any discussion - I have only just subscribed, and I did not find much in the tomcat-dev archives a couple of days ago. It appears to me that ClassLoading is not quite right in a couple of respects ( ie. not working 'as advertised' ), and if you're willing, I'd like to have a go at a couple of patches for it. Here's the list of things that I consider to be broken, based on the understandings that: A) the hierarchy should go: SystemCL | -- LAYER 1 lib/common CL / \ -- LAYER 2 lib/container lib/apps CL |-- LAYER 3 WEB-INF/libsame CL, but with URLs WEB-INF/classes from both dirs, in this order... B) a classloader which failed to find a class will delegate to it's parent a'la JDK 2 style, with the delegation behaviour in: JDK 1.2+ java.net.URLClassLoader JDK 1.1 org.apache.tomcat.util.compat.SimpleClassLoader Everything is right in your interpretation, but some historical insights will be helpful, everything was done thinking on a quick restoration of the old behaviour ( pre CL division ) .., more on that later List of broken behaviours: 1) LAYER 1 and LAYER 2 are broken ( do not delegate to parent ) org.apache.tomcat.modules.config.ProfileLoader [ -r ] line 320: commonLoader is set to be its own parent, if there was previously a commonLoader, or the System CL if not. line 331: ( same, with appLoader ) line 343: ( same, with containerLoader ) this is also a potential memory leak after a while, if initClassLoaders() is called more than once. Costin has explained ProfileLoader and TC33 out the box dont use it.. 2) LAYER 3 bypasses straight to the System CL: there is a piece of code in org.apache.tomcat.modules.config.LoaderInterceptor11 [ ( line 197 - 207 ) if( useAL !context.isTrusted() ) { if( debug 0 ) log( Using webapp loader + context.isTrusted()); parent=cm.getParentLoader(); } else if( useNoParent ) { if( debug 0 ) log( Using no parent loader ); parent=null; } else { if( debug 0 ) log( Using container loader ); parent=this.getClass().getClassLoader(); } I am not really sure why this piece of code is as it is. note: - useAL is set by setUseApplicationLoader( boolean ). I could find no callers of this method in the source, but the method is still public. - same story for useNoParent, which is set by setUseNoParent( boolean ) - since useAL is initialised in the constructor to false, it would appear that if(1) is never called. - since useNoParent also defaults to false, it would appear that if(2) is never called - so it must always default to if(3), and this line does NOT gurarantee delegation to the container loader! ( expected Context.getContextManager().getContainerLoader() instead ) IF(3) can be considered the old escape path to the pre CL division behaviour.., so a user can easily reverse the CL operation to the OLD Behaviour.., call it Flexibility Syndrome :) All that methods are called as a reaction to user configs called by introspection by the XML Mapper ( aka Digester in commons ), all this configs are on server.xml.. 3) Inconsistent directory-scanning behaviours org.apache.tomcat.modules.config.ProfileLoader [ -r ]
RE: Anyone know why the ISAPI redirector works how it does?
So, +1 for trying a different approach without breaking what's already there? My swahili is at times hard to understand :)) Yes i'm +1 on trying what you are proposing in another place on jtc tree and leaving iis as it is now.. I'm really courious about what you find .. every bit of performance is welcomed ever .. so if there is a bit waiting for tomcat lets catch it ..:)) i recall that i'd found the same architecture in other ISAPI modules like resin... Saludos , Ignacio J. Ortega -- Andy Armstrong, Tagish
cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader WebappClassLoader.java
remm01/06/23 18:16:07 Modified:catalina/src/share/org/apache/catalina/loader WebappClassLoader.java Log: - The call to findResourceInternal should be wrapped in a privileged action. Bug reported by Craig R. McClanahan Revision ChangesPath 1.6 +15 -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.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- WebappClassLoader.java2001/06/23 22:38:03 1.5 +++ WebappClassLoader.java2001/06/24 01:16:06 1.6 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v 1.5 2001/06/23 22:38:03 remm Exp $ - * $Revision: 1.5 $ - * $Date: 2001/06/23 22:38:03 $ + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v 1.6 2001/06/24 01:16:06 remm Exp $ + * $Revision: 1.6 $ + * $Date: 2001/06/24 01:16:06 $ * * * @@ -124,7 +124,7 @@ * * @author Remy Maucherat * @author Craig R. McClanahan - * @version $Revision: 1.5 $ $Date: 2001/06/23 22:38:03 $ + * @version $Revision: 1.6 $ $Date: 2001/06/24 01:16:06 $ */ public class WebappClassLoader extends URLClassLoader @@ -840,7 +840,7 @@ * * @param name Name of the resource to be found */ -public URL findResource(String name) { +public URL findResource(final String name) { if (debug = 3) log(findResource( + name + )); @@ -849,7 +849,16 @@ ResourceEntry entry = (ResourceEntry) resourceEntries.get(name); if (entry == null) { -entry = findResourceInternal(name, name); +if (securityManager != null) { +entry = (ResourceEntry) AccessController.doPrivileged +(new PrivilegedAction() { +public Object run() { +return findResourceInternal(name, name); +} +}, accessController); +} else { +entry = findResourceInternal(name, name); +} } if (entry != null) { url = entry.source;
AjpXXPacket
Ok, first change. Would it be ok with you if I just drop Ajp14Packet in jk, and use the plain ByteChunk, plus a Ajp14Marshall to implement the marshaling on top of ByteChunk ? The idea is that ( someday - soon I hope ) ByteChunk will be able ( via a Liaison or the o.a.t.util.compat ) to interoperate with nio, and I want to keep all communication around the buffers ( to make my life easier when I do that ). It would also help simplify the code. Another issue ( I already mentioned it ) - can we make Ajp14 independent, and remove the Ajp13 code from j-t-c/../tomcat33 ( the implementation from the main tree will remain and be used until Ajp14 is ready ) ? I'm now able to authenticate, there are few problems after that - but I hope tommorow I'll be able to use Ajp14 for most things. It's looking very good ( I still can't believe how easy it was to build ! ) Costin
Re: [jtc - coyote] couple questions about the Request object
1) why is Request final? i was planning on extending it in org.apache.ajp.AjpRequest, but can't do so since it's final. it's no big deal, i can create org.apache.ajp.AjpRequestAdapter instead, just kind of curious. Well, before, the primary use for extending the request and response was implementing the read and write methods. Well, now there are some interfaces which you can implement as separate objects. You can also associate additional parameters to the request or response, so I thought that extending wouldn't be needed. Maybe the output and input will be a buffer too, since now you can associate them to a stream. 2) any reason why there is no way to set/get attributes on Request? I thought it was servlet API specific, so I would implement them in the adapter. as mentioned, the reason i ask is i was planning on taking advantage of Request in org.apache.ajp so that a bunch of work wasn't duplicated. Remy
Re: AjpXXPacket
Ok, first change. Would it be ok with you if I just drop Ajp14Packet in jk, and use the plain ByteChunk, plus a Ajp14Marshall to implement the marshaling on top of ByteChunk ? The idea is that ( someday - soon I hope ) ByteChunk will be able ( via a Liaison or the o.a.t.util.compat ) to interoperate with nio, and I want to keep all communication around the buffers ( to make my life easier when I do that ). It would also help simplify the code. i have no problem with that. could that be done with ajp13 too?? Another issue ( I already mentioned it ) - can we make Ajp14 independent, and remove the Ajp13 code from j-t-c/../tomcat33 ( the implementation from the main tree will remain and be used until Ajp14 is ready ) ? some thoughts... seems like the right place for core ajpXX (1.3 and 1.4 for now) stuff is in org.apache.ajp, and only adapter/connector/interceptor code should be in o.a.a.tomcatXX. i guess i'm not quite clear on what your intentions are... are you only talking about removing the ajp13 interceptor stuff from o.a.a.tomcat33? I'm now able to authenticate, there are few problems after that - but I hope tommorow I'll be able to use Ajp14 for most things. It's looking very good ( I still can't believe how easy it was to build ! ) Costin
Jasper34
Hola Costin: Jasper34 pass Sanity tests on W2k using HTTP Standalone .. Saludos , Ignacio J. Ortega
Re: Classpath Ordering: Questions, and possible contrib.
[EMAIL PROTECTED] wrote: On Sat, 23 Jun 2001, Glenn Nielsen wrote: I believe there are important security issues, but I'm sure the spec took this into consideration - so probably I'm wrong ( of course, this will be easy to verify later on, there are quite a few ways someone could try to exploit a reversed order - but again I'm sure this was taken care of and it'll be just the fun of trying :-). Yes there are security issues related to the Servlet 2.3 spec webapp CL. Fortunately, the Java SecurityManager can protect you if you use checkPackageDefinition() in the CL. This can prevent a Servlet 2.3 webapp CL from redefining system or other sensitive classes. That's only part of the problem and only part of the solution :-) I'm not going to argue to much about this - the archives of tomcat-dev are available, no need to repeat :-) Are you refering to class loading security, or class loading in general? It all depends on how you define 'sensitive classes' - what is not sensitive and how you decide so ? It's turning the problem around, from don't trust anything to don't trust specific things - and that's considered dangerous by some other people. Thats the beauty of the Java SecurityManager. As Craig mentioned, certain packages are automatically restricted from being defined or accessed by a webapp in Tomcat 4. But if the system administrator for Tomcat 4 decides they want to restrict definition or access to other packages, all they need to do is edit their $JAVA_HOME/jre/lib/java.security properties file. Then grant those permissions as needed in the policy file to any trusted webapps that may need them. By default, webapps would not have privileges to define and/or access those packages unless you explicitely granted them. Requiring use of the Java SecurityManager with Tomcat 4 has been discussed. I don't recall if a decision was reached on that. Regards, Glenn -- Glenn Nielsen [EMAIL PROTECTED] | /* Spelin donut madder| MOREnet System Programming | * if iz ina coment. | Missouri Research and Education Network | */ | --
JSP -en- masse mapping
On a site with lots of virtual hosts and .jsp files just about everywhere on lots of directory levels I was looking for a way to simplify and clarify the config. (Running tomcat 3.2.1 and mod_jk). But I've not been able to find in the documentation the right sort of magic to do something like: AddHandler jakarta-script .jsp rather than the JkMount /*.jsp ajp12 JkMount /Foo/*.jsp ajp12 'per-directory' looking kina jsp mapping. Is there any way to do this easily; (I know that the above happens to work) or am I just silly and do RTFM/source code again ? Any pointers appreciated. Dw