RE: [Proposal] Tomcat and Cactus (Repost)
Thanks to speak your mind Costin. At least you answered. I would have liked more feedback from other committers. For the time being I'll prepare a cactification script for Tomcat that will be delivered with Cactus. BTW, is there any problem if we create in cactusland a specially packaged Tomcat version that is cactus-aware ? I'm not sure yet we want to follow that route but if we wanted to do this and put it in the cactus release directory, would you see any problem ? I'll repost in 6 months ... :-) Thanks -Vincent Sidenote: I believe Cactus could very effectively be used as a regression testing tool for the Tomcat project. It has already discovered problems in the past. I haven't looked at the Watchdog project but it could be either a replacement or a complement to it. You should try it at some point. I would love to hear comments of what you don't like/do like. Quick start up guide for Tomcat is available here : http://jakarta.apache.org/cactus/1.4/howto_tomcat.html (needs only 10 minutes). -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 24 May 2002 19:41 To: Tomcat Users List Cc: List Tomcat-Dev Subject: Re: [Proposal] Tomcat and Cactus (Repost) On Fri, 24 May 2002, Vincent Massol wrote: I'm reposting in the secret hope that I got no response to this email I sent last week because no one saw it in the flood of Tomcat emails ! If I get no answer this time, I will understand that no one finds this of interest and will try again in 6 months - 1 year :-) I think it would be a good idea :-), there is already far too much going on, with all the new features and changes ( jmx, 4.1, jk2, jasper2, coyote, etc ). Costin Thanks -Vincent Hi Tomcat developers, This is a proposal to bring Jakarta Tomcat and Jakarta Cactus (http://jakarta.apache.org/cactus) closer. I hope you'll like it. (0) Rationale Jakarta Cactus is a unit testing framework for testing Servlet, Taglibs and Filters. Jakarta Tomcat is a Servlet engine (Servlet, Taglibs, Filters). They are both part of the Jakarta community. At the moment, there are no existing Servlet container that have an easy way to unit test Servlets. The idea is to bring this ease of use to Tomcat by making it easy to use Cactus within Tomcat (in other words, add a unit testing service to Tomcat). (1) Scope of the proposal a) To bundle Cactus within Tomcat so that it provides a unique ease of use for Tomcat users who wishes to test their servlet code b) To make Cactus the official Tomcat test framework for end users (1) From the point of view of Tomcat users By providing the bundling defined in point (2) below, Tomcat end users would only have to do the following to test their code (see http://jakarta.apache.org/cactus/1.4/howto_tomcat.html, steps 4 to 6) : a) Create Cactus test classes in their WEB-INF/classes directory b) Open a browser and type the URL of the Cactus test runner, passing the name of the test class (see the link above for details) (2) Cactus bundling in Tomcat Bundling Cactus in Tomcat means (see steps 1 to 3 on the above link) : a) Adding the following jars to common/lib : cactus.jar, junit.jar, httpclient.jar, aspectjrt.jar (total of 423 KB) b) Adding the Cactus servlet test runner and redirector servlet and mappings in conf/web.xml (3) Versions The target Tomcat version for this proposal is 4.0 and greater. The Cactus one is 1.4 and greater (note that Cactus 1.4 is not released yet and is still in CVS - It can be downloaded from the nightly build). Comments, ideas ? Thank you -Vincent (from the Cactus team) -- To unsubscribe, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] For additional commands, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:tomcat-dev- [EMAIL PROTECTED] For additional commands, e-mail: mailto:tomcat-dev- [EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: [Proposal] Tomcat and Cactus (Repost)
That defeats the purpose of that Tomcat integration. The idea is that the Cactus jars would be part of the common libraries of a Tomcat installation so that each web application does not have to include the cactus jars and setup in its own war ... The idea is to bring testing as a service provided by the container, not the other way around. -Vincent -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 25 May 2002 23:39 To: Tomcat Users List Cc: 'Tomcat Developers List' Subject: RE: [Proposal] Tomcat and Cactus (Repost) I would prefer to see a self-contained WAR file ( or a set of self-contained wars ). Costin On Sat, 25 May 2002, Vincent Massol wrote: Thanks to speak your mind Costin. At least you answered. I would have liked more feedback from other committers. For the time being I'll prepare a cactification script for Tomcat that will be delivered with Cactus. BTW, is there any problem if we create in cactusland a specially packaged Tomcat version that is cactus-aware ? I'm not sure yet we want to follow that route but if we wanted to do this and put it in the cactus release directory, would you see any problem ? I'll repost in 6 months ... :-) Thanks -Vincent Sidenote: I believe Cactus could very effectively be used as a regression testing tool for the Tomcat project. It has already discovered problems in the past. I haven't looked at the Watchdog project but it could be either a replacement or a complement to it. You should try it at some point. I would love to hear comments of what you don't like/do like. Quick start up guide for Tomcat is available here : http://jakarta.apache.org/cactus/1.4/howto_tomcat.html (needs only 10 minutes). -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: 24 May 2002 19:41 To: Tomcat Users List Cc: List Tomcat-Dev Subject: Re: [Proposal] Tomcat and Cactus (Repost) On Fri, 24 May 2002, Vincent Massol wrote: I'm reposting in the secret hope that I got no response to this email I sent last week because no one saw it in the flood of Tomcat emails ! If I get no answer this time, I will understand that no one finds this of interest and will try again in 6 months - 1 year :-) I think it would be a good idea :-), there is already far too much going on, with all the new features and changes ( jmx, 4.1, jk2, jasper2, coyote, etc ). Costin Thanks -Vincent Hi Tomcat developers, This is a proposal to bring Jakarta Tomcat and Jakarta Cactus (http://jakarta.apache.org/cactus) closer. I hope you'll like it. (0) Rationale Jakarta Cactus is a unit testing framework for testing Servlet, Taglibs and Filters. Jakarta Tomcat is a Servlet engine (Servlet, Taglibs, Filters). They are both part of the Jakarta community. At the moment, there are no existing Servlet container that have an easy way to unit test Servlets. The idea is to bring this ease of use to Tomcat by making it easy to use Cactus within Tomcat (in other words, add a unit testing service to Tomcat). (1) Scope of the proposal a) To bundle Cactus within Tomcat so that it provides a unique ease of use for Tomcat users who wishes to test their servlet code b) To make Cactus the official Tomcat test framework for end users (1) From the point of view of Tomcat users By providing the bundling defined in point (2) below, Tomcat end users would only have to do the following to test their code (see http://jakarta.apache.org/cactus/1.4/howto_tomcat.html, steps 4 to 6) : a) Create Cactus test classes in their WEB-INF/classes directory b) Open a browser and type the URL of the Cactus test runner, passing the name of the test class (see the link above for details) (2) Cactus bundling in Tomcat Bundling Cactus in Tomcat means (see steps 1 to 3 on the above link) : a) Adding the following jars to common/lib : cactus.jar, junit.jar, httpclient.jar, aspectjrt.jar (total of 423 KB) b) Adding the Cactus servlet test runner and redirector servlet and mappings in conf/web.xml (3) Versions The target Tomcat version for this proposal is 4.0 and greater. The Cactus one is 1.4 and greater (note that Cactus 1.4 is not released yet and is still in CVS - It can be downloaded from the nightly build). Comments, ideas ? Thank you -Vincent (from the Cactus team) -- To unsubscribe, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] For additional commands, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:tomcat-dev- [EMAIL PROTECTED] For additional commands, e-mail: mailto:tomcat-dev- [EMAIL PROTECTED
[Proposal] Tomcat and Cactus (Repost)
I'm reposting in the secret hope that I got no response to this email I sent last week because no one saw it in the flood of Tomcat emails ! If I get no answer this time, I will understand that no one finds this of interest and will try again in 6 months - 1 year :-) Thanks -Vincent Hi Tomcat developers, This is a proposal to bring Jakarta Tomcat and Jakarta Cactus (http://jakarta.apache.org/cactus) closer. I hope you'll like it. (0) Rationale Jakarta Cactus is a unit testing framework for testing Servlet, Taglibs and Filters. Jakarta Tomcat is a Servlet engine (Servlet, Taglibs, Filters). They are both part of the Jakarta community. At the moment, there are no existing Servlet container that have an easy way to unit test Servlets. The idea is to bring this ease of use to Tomcat by making it easy to use Cactus within Tomcat (in other words, add a unit testing service to Tomcat). (1) Scope of the proposal a) To bundle Cactus within Tomcat so that it provides a unique ease of use for Tomcat users who wishes to test their servlet code b) To make Cactus the official Tomcat test framework for end users (1) From the point of view of Tomcat users By providing the bundling defined in point (2) below, Tomcat end users would only have to do the following to test their code (see http://jakarta.apache.org/cactus/1.4/howto_tomcat.html, steps 4 to 6) : a) Create Cactus test classes in their WEB-INF/classes directory b) Open a browser and type the URL of the Cactus test runner, passing the name of the test class (see the link above for details) (2) Cactus bundling in Tomcat Bundling Cactus in Tomcat means (see steps 1 to 3 on the above link) : a) Adding the following jars to common/lib : cactus.jar, junit.jar, httpclient.jar, aspectjrt.jar (total of 423 KB) b) Adding the Cactus servlet test runner and redirector servlet and mappings in conf/web.xml (3) Versions The target Tomcat version for this proposal is 4.0 and greater. The Cactus one is 1.4 and greater (note that Cactus 1.4 is not released yet and is still in CVS - It can be downloaded from the nightly build). Comments, ideas ? Thank you -Vincent (from the Cactus team) -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
[tomcat 4.1dev] Starting in another directory problem
Hi, I'm having problem starting Tomcat 4.1dev (i.e. latest nightly build 18/1/2002) when I use catalina.base to start it from another directory. It works fine with Tomcat 4.0, Tomcat 4.0.1 and Tomcat 4.0.2b2 but _not_ with Tomcat 4.1dev. The error is attached. Here's my start script : java classname=org.apache.catalina.startup.Bootstrap fork=yes jvmarg value=-Dcatalina.home=${tomcat.home.40}/ jvmarg value=-Dcatalina.base=${out.tomcat40.dir}/ arg value=start/ classpath !-- This is to allow the use of -Dbuild.sysclasspath=only when starting Ant - Meaning that all jars need to be on the initial classpath -- pathelement path=${java.class.path}/ !-- These are ignore if -Dbuild.sysclasspath=only is used -- fileset dir=${tomcat.home.40} include name=bin/bootstrap.jar/ /fileset /classpath /java Any idea why this worked before (on older versions of Tomcat) and is now failing ? Thanks -Vincent P.S. : java.class.path = C:\apps\jdk1.3.1_01\lib\tools.jar;C:\apps\jakarta-ant-1.4.1\lib\xerces.j ar;C:\apps\jakarta-ant-1.4.1\lib\xalan-2.2.0-D8.jar;C:\apps\jakarta-ant- 1.4.1\lib\stylebook-1.0-b3_xalan-2.jar;C:\apps\jakarta-ant-1.4.1\lib\rhi no.jar;C:\apps\jakarta-ant-1.4.1\lib\resolver.jar;C:\apps\jakarta-ant-1. 4.1\lib\mockobjects.jar;C:\apps\jakarta-ant-1.4.1\lib\logkit.jar;C:\apps \jakarta-ant-1.4.1\lib\junit.jar;C:\apps\jakarta-ant-1.4.1\lib\jrefactor y.jar;C:\apps\jakarta-ant-1.4.1\lib\jaxp.jar;C:\apps\jakarta-ant-1.4.1\l ib\jakarta-ant-1.4.1-optional.jar;C:\apps\jakarta-ant-1.4.1\lib\fop-0_20 _1-dev.jar;C:\apps\jakarta-ant-1.4.1\lib\cocoon.jar;C:\apps\jakarta-ant- 1.4.1\lib\cactus.jar;C:\apps\jakarta-ant-1.4.1\lib\cactus-ant.jar;C:\app s\jakarta-ant-1.4.1\lib\bsf.jar;C:\apps\jakarta-ant-1.4.1\lib\batik-libs .jar;C:\apps\jakarta-ant-1.4.1\lib\avalon-framework.jar;C:\apps\jakarta- ant-1.4.1\lib\avalon-excalibur.jar;C:\apps\jakarta-ant-1.4.1\lib\aspectj tools.jar;C:\apps\jakarta-ant-1.4.1\lib\aspectjrt.jar;C:\apps\jakarta-an t-1.4.1\lib\aspectj-ant.jar;C:\apps\jakarta-ant-1.4.1\lib\ant.jar [java] start_tomcat_40: [java] [java] log4j:WARN No appenders could be found for logger (org.apache.commons.digester). [java] [java] log4j:WARN Please initialize the log4j system properly. [java] [java] HttpConnector Opening server socket on all host IP addresses [java] [java] Starting service Tomcat-Standalone [java] [java] Apache Tomcat/4.1-dev [java] [java] HostConfig[localhost]: Deploying web application archive test.war [java] [java] StandardHost[localhost]: Installing web application at context path /test from URL jar:file:/home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test.war!/ [java] [java] HttpConnector[8082] Starting background thread [java] [java] StandardHost[localhost]: MAPPING configuration error for request URI [java] [java] WebappLoader[/test]: Deploying class repositories to work directory /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/work/localhost/test [java] [java] WebappLoader[/test]: Deploy class files /WEB-INF/classes to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/classes [java] [java] WebappLoader[/test]: Deploy JAR /WEB-INF/lib/aspectjrt.jar to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/lib/aspectjrt.jar [java] [java] WebappLoader[/test]: Deploy JAR /WEB-INF/lib/cactus.jar to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/lib/cactus.jar [java] [java] WebappLoader[/test]: Deploy JAR /WEB-INF/lib/httpclient.jar to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/lib/httpclient.jar [java] [java] WebappLoader[/test]: Deploy JAR /WEB-INF/lib/junit.jar to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/lib/junit.jar [java] [java] WebappLoader[/test]: Deploy JAR /WEB-INF/lib/log4j.jar to /home/rubys/jakarta/jakarta-cactus/target/servlet23/dist/sample/target/test/tomcat40/webapps/test/WEB-INF/lib/log4j.jar [java] [java] StandardManager[/test]: Seeding random number generator class java.security.SecureRandom [java] [java] StandardManager[/test]: Seeding of random number generator has been completed [java] [java] ContextConfig[/test]: Configured an authenticator for method BASIC [java] [java] StandardWrapper[/test:default]: Loading container servlet default [java] [java] StandardWrapper[/test:invoker]:
[tomcat4] Basic Authentication problem
Hello, I am trying to add basic authentication for a servlet. This should be a simple task and I'm quite sure I'm doing something stupid ... but I'm failing to find the reason (note: I have it working on Tomcat 3.3). I'm getting a 401 error. I have the following directory structure : myroot |_ conf |_ tomcat-users.xml |_ web.xml |_ server.xml |_ webapps |_ mywebapp.war My server.xml is : Server port=8005 shutdown=SHUTDOWN debug=0 Service name=Tomcat-Standalone Connector className=org.apache.catalina.connector.http.HttpConnector port=8080 minProcessors=5 maxProcessors=75 acceptCount=10 debug=0/ Engine name=Standalone defaultHost=localhost debug=0 Realm className=org.apache.catalina.realm.MemoryRealm / Host name=localhost debug=0 appBase=full path to myroot/webapps /Host /Engine /Service /Server My tomcat-users.xml is : tomcat-users user name=testuser password=testpwd roles=test / /tomcat-users And my web.xml in mywebapp.war is : [...] servlet servlet-nameServletRedirectorSecure/servlet-name servlet-classorg.apache.cactus.server.ServletTestRedirector/servlet-c lass /servlet servlet-mapping servlet-nameServletRedirector/servlet-name url-pattern/ServletRedirector/url-pattern /servlet-mapping security-constraint web-resource-collection web-resource-nameSecurityRestriction/web-resource-name descriptionProtect the Cactus redirector servlet./description url-pattern/ServletRedirectorSecure/url-pattern http-methodGET/http-method http-methodPOST/http-method /web-resource-collection auth-constraint descriptionAuthorized Users Group/description role-nametest/role-name /auth-constraint user-data-constraint transport-guaranteeNONE/transport-guarantee /user-data-constraint /security-constraint login-config auth-methodBASIC/auth-method /login-config security-role descriptionTest role/description role-nametest/role-name /security-role I am starting Tomcat as follows in Ant (where ${out.tomcat40.full.dir} point to the absolute path to myroot and ${tomcat.home.40} to where Tomcat 4 is installed) : java classname=org.apache.catalina.startup.Bootstrap fork=yes jvmarg value=-Dcatalina.home=${tomcat.home.40}/ arg value=-config/ arg value=${out.tomcat40.full.dir}/conf/server.xml/ arg value=start/ classpath !-- This is to allow the use of -Dbuild.sysclasspath=only when starting Ant - Meaning that all jars need to be on the initial classpath -- pathelement path=${java.class.path}/ !-- These are ignore if -Dbuild.sysclasspath=only is used -- fileset dir=${tomcat.home.40} include name=bin/bootstrap.jar/ include name=server/catalina.jar/ /fileset /classpath /java Any idea ? Thanks -Vincent -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED]
[Tomcat 3.3] Strange behaviour w/ mixed POST/GET request
I have a strange behaviour in Tomcat 3.3 that does not happen either in Tomcat 4.x or in Tomcat 3.2.x (or any other servlet engine for the matter : Orion, Resin, WebLogic). It looks like voodoo for me and I have trouble understanding what's happening. I am sending several different HTTP requests (using HttpURLConnection) to the server and depending on the order I get or do not get an error. When I get the error, it is the typical : Connection aborted by peer: JVM_recv in socket input stream read java.net.SocketException: Connection aborted by peer: JVM_recv in socket inp ut stream read at java.net.SocketInputStream.socketRead(Native Method) I am doing one special request in which I send _both_ GET parameters (in the URL) and parameters in the request body (POST method). The other requests are only GET requests. If I call the mixed POST/GET request first, followed by the other GET requests then everything is fine. However, if I start by doing on GET request and then followed by the mixed POST/GET one, I get the connection aborted by peer error. Any idea ? Any known issues with mixed POST/GET requests ? Thanks a lot for any hint as I'm beginning to tear my hair ... :-) -Vincent -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED]
RE: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request
-Original Message- From: ian silvester [mailto:[EMAIL PROTECTED]] Sent: 21 December 2001 15:18 To: Tomcat Users List Subject: Re: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request Hmm. The fact that you only get this behaviour in 3.3 suggests very strongly a problem in that release. Is there any reason why you can't use a different release and avoid the error? Because in the framework I am working on (Jakarta Cactus), I need to support all servlet engines (including Tomcat 3.3) :-) That aside, I have seen this error under different circumstances - doing a response.sendredirect in a JSP _after_ having already output HTML to the browser. For this to error is fair enough - its supposedly outside the HTTP spec. to send redirects after having started outputting HTML (in ASP, MS being the hand-holders that they are, attempting to do this throws a runtime error so as to avoid unexpected behaviour). Could your code be construed as doing something similar? If yes, then you cannot guarantee that it will work on all combintaions of browser and server. There is no sendredirect in my code but I may be doing something not in the spec ... As suggested by Larry Isaacs, I'm going to open a bug in bugzilla with details on the test case. However, it is going to take some time as I need to extract the relevant portion from the code. I hoped someone was going to say something like : yes, we know, we have an issue when you're sending parameter in the URL at the same time as in the request body ... :-) In the meantime (before I finish extracting the code), some more information on the code logic (client side) : 1/ open an http connection to Tomcat 3.3 using HttpURLConnection and read all returned data (with attached AutoReadHttpURLConnection class) : HttpURLConnection connection = helper.connect(theRequest); connection = new AutoReadHttpURLConnection(connection); // Trigger the transfer of data connection.getInputStream(); On the server side, some code is executed and a result is set in the application context. 2/ open a second connection to the server using HttpURLConnection and get the test result (sent back as an ObjectOutputStream) Repeat 1/ and 2/ for all the requests I mentioned in my previous mail (the mixed POST/GET one and the other GET ones). Thanks -Vincent ian - Original Message - From: Vincent Massol [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, December 21, 2001 2:44 PM Subject: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request I have a strange behaviour in Tomcat 3.3 that does not happen either in Tomcat 4.x or in Tomcat 3.2.x (or any other servlet engine for the matter : Orion, Resin, WebLogic). It looks like voodoo for me and I have trouble understanding what's happening. I am sending several different HTTP requests (using HttpURLConnection) to the server and depending on the order I get or do not get an error. When I get the error, it is the typical : Connection aborted by peer: JVM_recv in socket input stream read java.net.SocketException: Connection aborted by peer: JVM_recv in socket inp ut stream read at java.net.SocketInputStream.socketRead(Native Method) I am doing one special request in which I send _both_ GET parameters (in the URL) and parameters in the request body (POST method). The other requests are only GET requests. If I call the mixed POST/GET request first, followed by the other GET requests then everything is fine. However, if I start by doing on GET request and then followed by the mixed POST/GET one, I get the connection aborted by peer error. Any idea ? Any known issues with mixed POST/GET requests ? Thanks a lot for any hint as I'm beginning to tear my hair ... :-) -Vincent -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED] -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED] AutoReadHttpURLConnection.java Description: Binary data -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED]
RE: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request
-Original Message- From: ian silvester [mailto:[EMAIL PROTECTED]] Sent: 21 December 2001 15:18 To: Tomcat Users List Subject: Re: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request Hmm. The fact that you only get this behaviour in 3.3 suggests very strongly a problem in that release. Is there any reason why you can't use a different release and avoid the error? Please also note that it seems to happen only on some platforms. For example it works on RedHat Linux w/JDK 1.3.1_01 (this is the platform which is hosting GUMP and the tests are run every night with Tomcat 3.3 - see http://jakarta.apache.org/builds/gump/latest/jakarta-cactus-22.html), but seems to fail on SunOS w/JDK 1.3.1_01 (not verified myself, I was told). It also fails on my platforms, which are Windows 2000 / Windows XP with JDK 1.3.1_01 Thanks -Vincent That aside, I have seen this error under different circumstances - doing a response.sendredirect in a JSP _after_ having already output HTML to the browser. For this to error is fair enough - its supposedly outside the HTTP spec. to send redirects after having started outputting HTML (in ASP, MS being the hand-holders that they are, attempting to do this throws a runtime error so as to avoid unexpected behaviour). Could your code be construed as doing something similar? If yes, then you cannot guarantee that it will work on all combintaions of browser and server. ian - Original Message - From: Vincent Massol [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, December 21, 2001 2:44 PM Subject: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request I have a strange behaviour in Tomcat 3.3 that does not happen either in Tomcat 4.x or in Tomcat 3.2.x (or any other servlet engine for the matter : Orion, Resin, WebLogic). It looks like voodoo for me and I have trouble understanding what's happening. I am sending several different HTTP requests (using HttpURLConnection) to the server and depending on the order I get or do not get an error. When I get the error, it is the typical : Connection aborted by peer: JVM_recv in socket input stream read java.net.SocketException: Connection aborted by peer: JVM_recv in socket inp ut stream read at java.net.SocketInputStream.socketRead(Native Method) I am doing one special request in which I send _both_ GET parameters (in the URL) and parameters in the request body (POST method). The other requests are only GET requests. If I call the mixed POST/GET request first, followed by the other GET requests then everything is fine. However, if I start by doing on GET request and then followed by the mixed POST/GET one, I get the connection aborted by peer error. Any idea ? Any known issues with mixed POST/GET requests ? Thanks a lot for any hint as I'm beginning to tear my hair ... :-) -Vincent -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED] -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED] -- To unsubscribe: mailto:[EMAIL PROTECTED] For additional commands: mailto:[EMAIL PROTECTED] Troubles with the list: mailto:[EMAIL PROTECTED]
RE: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request (NOT solved)
I have spoken a bit too fast ... :-( It worked 3 times in a row and then started failing again, same as before. It failed even after removing all connection.disconnect() and all close on streams related to the connection but the failure rate seems to be lower ... I've just run the tests 10 times and the result is : Ok, ok, nok, ok, ok, ok, nok, nok, nok, nok I've tried to write a sample test case to reproduce it but cannot (in other words, it works all the time with the simple test case). I'm a bit stuck and don't know what to do now ... Any idea ? Thanks -Vincent -Original Message- From: Vincent Massol [mailto:[EMAIL PROTECTED]] Sent: 21 December 2001 17:27 To: 'Tomcat Users List' Subject: RE: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request (solved) I have found the reason ... My code was the equivalent of : URL url = new URL(http://localhost:8080/examples/snoop?param1=value1;); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); connection.setRequestProperty(Content-type, application/x-www-form-urlencoded); PrintWriter out = new PrintWriter(connection.getOutputStream()); out.print(param2=value2); out.close(); connection.connect(); connection.getInputStream().close(); And this throws an error. The problem is with the last line which works fine with all other servlet engines but not Tomcat 3.3. If I change it to : connection.disconnect(); it now works fine. This probably means that when the connection is closed it tries to close the underlying input stream and does not verify if it is already closed (or something like this). Thanks and sorry for the trouble. -Vincent -Original Message- From: Vincent Massol [mailto:[EMAIL PROTECTED]] Sent: 21 December 2001 16:15 To: 'Tomcat Users List' Cc: 'Larry Isaacs' Subject: RE: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request -Original Message- From: ian silvester [mailto:[EMAIL PROTECTED]] Sent: 21 December 2001 15:18 To: Tomcat Users List Subject: Re: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request Hmm. The fact that you only get this behaviour in 3.3 suggests very strongly a problem in that release. Is there any reason why you can't use a different release and avoid the error? Because in the framework I am working on (Jakarta Cactus), I need to support all servlet engines (including Tomcat 3.3) :-) That aside, I have seen this error under different circumstances - doing a response.sendredirect in a JSP _after_ having already output HTML to the browser. For this to error is fair enough - its supposedly outside the HTTP spec. to send redirects after having started outputting HTML (in ASP, MS being the hand-holders that they are, attempting to do this throws a runtime error so as to avoid unexpected behaviour). Could your code be construed as doing something similar? If yes, then you cannot guarantee that it will work on all combintaions of browser and server. There is no sendredirect in my code but I may be doing something not in the spec ... As suggested by Larry Isaacs, I'm going to open a bug in bugzilla with details on the test case. However, it is going to take some time as I need to extract the relevant portion from the code. I hoped someone was going to say something like : yes, we know, we have an issue when you're sending parameter in the URL at the same time as in the request body ... :-) In the meantime (before I finish extracting the code), some more information on the code logic (client side) : 1/ open an http connection to Tomcat 3.3 using HttpURLConnection and read all returned data (with attached AutoReadHttpURLConnection class) : HttpURLConnection connection = helper.connect(theRequest); connection = new AutoReadHttpURLConnection(connection); // Trigger the transfer of data connection.getInputStream(); On the server side, some code is executed and a result is set in the application context. 2/ open a second connection to the server using HttpURLConnection and get the test result (sent back as an ObjectOutputStream) Repeat 1/ and 2/ for all the requests I mentioned in my previous mail (the mixed POST/GET one and the other GET ones). Thanks -Vincent ian - Original Message - From: Vincent Massol [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, December 21, 2001 2:44 PM Subject: [Tomcat 3.3] Strange behaviour w/ mixed POST/GET request I have a strange behaviour in Tomcat 3.3 that does not happen either in Tomcat 4.x or in Tomcat 3.2.x (or any other servlet engine for the matter : Orion, Resin, WebLogic). It looks like voodoo for me and I have trouble understanding what's happening. I am
Re: [repost] Re: Limitations in using a different Ajp port than the standard ? (WAS Re: SAAAAAAAM! :))
ok, as no one is interested by the subject, I'll reply to my own question :) By looking at the source code, I have found a workaround to stop Tomcat 3.3 on a custom AJP12 port and with a ContextManager home different from tomcat.home : Instead of using java -classpath tomcat.jar org.apache.tomcat.Main -stop use: java -classpath stop-tomcat.jar org.apache.tomcatStopTomcat -ajp12 path to ajp file I still find it strange that the behaviour changed as Tomcat 3.2.2 and Tomcat 4.0 behave the same. Only 3.3 is different. I still don't know if it is a bug or a feature ... :) Thanks -Vincent - Original Message - From: Vincent Massol [EMAIL PROTECTED] To: [EMAIL PROTECTED] Cc: Pier P. Fumagalli [EMAIL PROTECTED]; [EMAIL PROTECTED]; Sam Ruby [EMAIL PROTECTED] Sent: Sunday, August 05, 2001 9:24 PM Subject: [repost] Re: Limitations in using a different Ajp port than the standard ? (WAS Re: SAAAM! :)) Hi, I would like to use different ports than the standard Tomcat ones. For the HTTP listener, it works fine. However I am having trouble for the Ajp listener which is used to stop tomcat. The issue is the following : * When I start Tomcat I use my own server.xml file which is located in my own directory (I start Tomcat using the -config switch). In server.xml I also set the ContextManager home to be my own directory. So Tomcat generates an ajp12.id file in _that_ directory (and not into Tomcat home directory, which is normal and fine). The tomcat home directory is set to be the directory where I have installed Tomcat. * No, when I want to stop Tomcat, it seems Tomcat looks for an ajp12.id file but in the ${tomcat.home}/conf and _not_ in the directory defined in the ContextManager home or where my server.xml file is. In other words, it seems it is not possible to start 2 instances of Tomcat and only stop one running instance (the one with the different ajp port) by using only one Tomcat installation ? Is that a bug, a feature or have I forgotten something ? Please note that it only fails on Tomcat 3.3 (I have tried it on 3.3-b1 and on the nighlty build of 2/8/2001). It works fine on Tomcat 3.2.1 and on Tomcat 4.0. Find below my start, stop scripts and relevant portion of server.xml Thanks a lot. -Vincent start script --- target name=start_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target stop script --- target name=stop_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-stop/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target server.xml [...] RequestInterceptor className=org.apache.tomcat.modules.server.Ajp12Interceptor tomcatAuthentication=false port=8777 / - Original Message - From: Sam Ruby [EMAIL PROTECTED] To: Pier P. Fumagalli [EMAIL PROTECTED] Cc: Vincent Massol [EMAIL PROTECTED] Sent: Thursday, August 02, 2001 2:27 AM Subject: Re: SAAAM! :) Vincent, can you take a look at changing the port numbers from 8080 to something unique? Preferably, something controlable via a property? Pier - I was doing a test build of some changes to cactus...sorry. - Sam Ruby Pier P. Fumagalli [EMAIL PROTECTED] on 08/01/2001 09:23:49 PM To: Sam Ruby/Raleigh/IBM@IBMUS cc: Subject: SAAAM! :) What's going on on Nagoya and Tomcat 4.0? Huh? :) You little brat binding to my network ports and giving me BindExceptions :) Can you remove the config for the WARP connector from your TC4 configuration? Cheers :) Pier
[repost] Re: Limitations in using a different Ajp port than the standard ? (WAS Re: SAAAAAAAM! :))
Hi, I would like to use different ports than the standard Tomcat ones. For the HTTP listener, it works fine. However I am having trouble for the Ajp listener which is used to stop tomcat. The issue is the following : * When I start Tomcat I use my own server.xml file which is located in my own directory (I start Tomcat using the -config switch). In server.xml I also set the ContextManager home to be my own directory. So Tomcat generates an ajp12.id file in _that_ directory (and not into Tomcat home directory, which is normal and fine). The tomcat home directory is set to be the directory where I have installed Tomcat. * No, when I want to stop Tomcat, it seems Tomcat looks for an ajp12.id file but in the ${tomcat.home}/conf and _not_ in the directory defined in the ContextManager home or where my server.xml file is. In other words, it seems it is not possible to start 2 instances of Tomcat and only stop one running instance (the one with the different ajp port) by using only one Tomcat installation ? Is that a bug, a feature or have I forgotten something ? Please note that it only fails on Tomcat 3.3 (I have tried it on 3.3-b1 and on the nighlty build of 2/8/2001). It works fine on Tomcat 3.2.1 and on Tomcat 4.0. Find below my start, stop scripts and relevant portion of server.xml Thanks a lot. -Vincent start script --- target name=start_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target stop script --- target name=stop_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-stop/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target server.xml [...] RequestInterceptor className=org.apache.tomcat.modules.server.Ajp12Interceptor tomcatAuthentication=false port=8777 / - Original Message - From: Sam Ruby [EMAIL PROTECTED] To: Pier P. Fumagalli [EMAIL PROTECTED] Cc: Vincent Massol [EMAIL PROTECTED] Sent: Thursday, August 02, 2001 2:27 AM Subject: Re: SAAAM! :) Vincent, can you take a look at changing the port numbers from 8080 to something unique? Preferably, something controlable via a property? Pier - I was doing a test build of some changes to cactus...sorry. - Sam Ruby Pier P. Fumagalli [EMAIL PROTECTED] on 08/01/2001 09:23:49 PM To: Sam Ruby/Raleigh/IBM@IBMUS cc: Subject: SAAAM! :) What's going on on Nagoya and Tomcat 4.0? Huh? :) You little brat binding to my network ports and giving me BindExceptions :) Can you remove the config for the WARP connector from your TC4 configuration? Cheers :) Pier
Re: Limitations in using a different Ajp port than the standard ? (WAS Re: SAAAAAAAM! :))
FYI, it works on Tomcat 3.2.2 ... but not on Tomcat 3.3-b1 and not with the nighlty build of today (2/8/2001) ... -Vincent - Original Message - From: Vincent Massol [EMAIL PROTECTED] To: [EMAIL PROTECTED] Cc: Pier P. Fumagalli [EMAIL PROTECTED]; [EMAIL PROTECTED]; Sam Ruby [EMAIL PROTECTED] Sent: Thursday, August 02, 2001 2:16 PM Subject: Limitations in using a different Ajp port than the standard ? (WAS Re: SAAAM! :)) Hi, I would like to use different ports than the standard Tomcat ones. For the HTTP listener, it works fine. However I am having trouble for the Ajp listener which is used to stop tomcat. The issue is the following : * When I start Tomcat I use my own server.xml file which is located in my own directory (I start Tomcat using the -config switch). In server.xml I also set the ContextManager home to be my own directory. So Tomcat generates an ajp12.id file in _that_ directory (and not into Tomcat home directory, which is normal and fine). The tomcat home directory is set to be the directory where I have installed Tomcat. * No, when I want to stop Tomcat, it seems Tomcat looks for an ajp12.id file but in the ${tomcat.home}/conf and _not_ in the directory defined in the ContextManager home or where my server.xml file is. In other words, it seems it is not possible to start 2 instances of Tomcat and only stop one running instance (the one with the different ajp port) by using only one Tomcat installation ? Is that a bug, a feature or have I forgotten something ? Find below my start, stop scripts and relevant portion of server.xml Thanks a lot. -Vincent start script --- target name=start_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target stop script --- target name=stop_tomcat_33 java classname=org.apache.tomcat.startup.Main fork=yes jvmarg value=-Dtomcat.home=${tomcat.home.33}/ arg value=-stop/ arg value=-config/ arg value=${out.tomcat33.full.dir}/conf/server.xml/ classpath pathelement location=${java.home}/../lib/tools.jar/ fileset dir=${tomcat.home.33}/lib include name=tomcat.jar/ /fileset /classpath /java /target server.xml [...] RequestInterceptor className=org.apache.tomcat.modules.server.Ajp12Interceptor tomcatAuthentication=false port=8777 / - Original Message - From: Sam Ruby [EMAIL PROTECTED] To: Pier P. Fumagalli [EMAIL PROTECTED] Cc: Vincent Massol [EMAIL PROTECTED] Sent: Thursday, August 02, 2001 2:27 AM Subject: Re: SAAAM! :) Vincent, can you take a look at changing the port numbers from 8080 to something unique? Preferably, something controlable via a property? Pier - I was doing a test build of some changes to cactus...sorry. - Sam Ruby Pier P. Fumagalli [EMAIL PROTECTED] on 08/01/2001 09:23:49 PM To: Sam Ruby/Raleigh/IBM@IBMUS cc: Subject: SAAAM! :) What's going on on Nagoya and Tomcat 4.0? Huh? :) You little brat binding to my network ports and giving me BindExceptions :) Can you remove the config for the WARP connector from your TC4 configuration? Cheers :) Pier
Re: WebappClassLoader question
Hi Craig, Thanks again. I have tried it again and it still doesn't work. I'll narrow a bit more my example. C.java --- public class C extend D { ... } --- D.java --- import junit.framework.*; public class D extends TestCase { ... } --- and the exact code in class B: B.java --- public class B { public B() { } public doSomething() { D testInstance = null; try { testClass = Class.forName(C); Constructor constructor = testClass.getConstructor(new Class[] { String.class }); testInstance = (D)constructor.newInstance(new Object[] { something }); } catch (Exception e) { log(I would have thought here); } } } The error I am getting between before error and after error is java.lang.NoClassDefFoundError: junit/framework/TestCase. ... so yes, class D (which depends on JUnit) is explicitely mentionned in class B. So, what you said in your first email is that it is normal (although yo have to agree it is very hard to debug and track and means I'll have to put a try catch around B myB = new B() in class A, which looks at bit surnatural ... :-) (I'll need to put a good comment to explain it at least!). ... then in your second email you say it is working fine with the I would have thought here message printed ... so that's why I'm resending these additional details. Classes A, B, and D are in a jar under WEB-INF/lib Class C is in WEB-INF/classes Any idea. If not, I'll try to make the most simple example that reproduces what I have and I'll send it over. Thanks a lot. -Vincent - Original Message - From: Craig R. McClanahan [EMAIL PROTECTED] To: [EMAIL PROTECTED] Cc: Vincent Massol [EMAIL PROTECTED] Sent: Thursday, July 26, 2001 10:08 PM Subject: Re: WebappClassLoader question On Thu, 26 Jul 2001, Craig R. McClanahan wrote: Hmm, I just tried a case like what you have below. As long as B does not explicitly reference class C, then it works. In other words, in my example where you've got the // call the method by reflection comment, I added Object c = myClass.newInstance(); and got the class not found exception at I would have thought here. On the other hand, if I changed the above line to: C c = (C) myClass.newInstance(); (and compiled with class C on the compiler classpath, but not in the webapp), then I get the error in between before error and after error. This makes sense, because the latter statement makes B explicitly dependent on C, where the former doesn't. I'll mess around some more, playing with JAR-ing up some but not all the classes involved. One more follow-up ... this works correctly for me with A and B in a jar file under /WEB-INF/lib, and C unpacked under /WEB-INF/classes as well. Craig Craig On Thu, 26 Jul 2001, Vincent Massol wrote: Thanks Craig, However I am still not sure this mechanism explains the problem I had. It is not easy to describe in word so I'll write it in java code instead. A.java public class A implements HttpServlet { public void doGet() { log(before error); B myB = new B(); log(after error); } } B.java public class B { public B() { } public doSomething() { try { Class myClass = Class.forName(C); // call the method by reflection ... } catch (Exception e) { log(I would have thought here); } } } C.java import junit.framework.*; public class C extends TestCase { ... } Now all of this is packaged in a war, classes A and B and in a jar put in WEB-INF/lib and class C is put in WEB-INF/classes. The junit jar is *not* put in WEB-INF/lib. Calling the servlet A result in an error occurring between the logs before error and after error and the log I would have thought here is never printed because the error happens _before_ ... This is what I don't understand. Any idea ? Thanks a lot -Vincent - Original Message - From: Craig R. McClanahan [EMAIL PROTECTED] To: [EMAIL PROTECTED]; Vincent Massol [EMAIL PROTECTED] Sent: Thursday, July 26, 2001 6:18 PM Subject: Re: WebappClassLoader question On Thu, 26 Jul 2001, Vincent Massol wrote: Thanks Alex, I don't think the standard classloader mechanism is involved here. I believe it is a 'feature' of Tomcat and more specifically of it's WebappClassLoader. When you do standard java code and you have the following situation : 1st - 2nd --- (using reflection) -- 3rd (not in classpath) then the error always happen in the 2nd class and you can put the code between a try catch block and you'll be able to catch the ClassNotFoundException. However what happens here is that the error happens when calling a method on the 1st class that instanciates the 2nd class ! This is what I don't understand. Am I dreaming or is this a behaviour of Tomcat 4
Re: WebappClassLoader question
- Original Message - From: Andrew Inggs [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, July 27, 2001 10:01 AM Subject: RE: WebappClassLoader question Hi Vincent You seem to be missing at least two things here: 1. In your original post you said: When I access the servlet, I get a ClassNotFoundException on a JUnit class. So far it is normal ... When I debugged it, I have actually found that the error was happening when ServletTestRedirector was instancianting MyProxyClass (which does _not_ make use of JUnit) and before it was calling its method. This does not look right. You say MyProxyClass does not make use of JUnit, but it *does*. This is the line that causes it to: testInstance = (ServletTestCase)constructor.newInstance(new Object[] { theMethod }); You see here you are explicitly referencing ServletTestCase which extends junit.framework.TestCase, this introduces the dependency. That's true. I may have used the wrong word. What I meant is that the MyProxyClass did not have a JUnit import statement, meaning it did not make a _direct_ use of JUnit. But as you point out, ServletTestCase does make a direct use of JUnit. 2. You seem to be assuming that NoClassDefFoundError extends Exception, but it doesn't. If you want to catch a NoClassDefFoundError you'll have to catch it directly, or one of its superclasses (java.lang.LinkageError, java.lang.Error, or java.lang.Throwable). This is why I would have thought here never gets printed out: } catch (Exception e) { log(I would have thought here); } That's also true but that's the question I am asking ... ! Why do I get a NoClassDefFoundError whereas I was expecting a ClassNotFoundException ! Please see Craig's answer and my other posts for a better description of what error I am getting and what I am trying to achieve. As an aside, I'm not sure what you are trying to achieve here? You don't have junit.jar in your classpath, and then you're say you get this strange error. The details aside, isn't that what you'd expect :-)? Even if you hadn't referenced ServletTestCase directly, you still wouldn't have been able to instantiate it using reflection without junit.jar in the classpath. What are you really trying to achieve? As Alex kindly answered on the list, I would like to catch this error nicely (when junit.jar is not in the classpath) so that I can display a good and relevant message for the end user, telling him to put the class on the class path ... When I debugged the code to know why I wasn't catching the exception, I noticed that the error happened in a strange place, i.e. the first class in the chain of dependencies and that's what I find strange. I have had no previous experience of this kind of class loading mechanism and I find it very very hard to debug (It means you have to put try catch blocks everywhere in your first class being called in your webapp if you want to catch for possible error resulting from classes not in the classapth !). -- Andrew Thanks Andrew for your help! -Vincent
[Summary] Re: WebappClassLoader question
Thanks to all who helped on this. Andrew was right, and Craig too and I was wrong ! Here is what happened. My code was written like this : ServletTestCase testInstance = null; try { testClass = Class.forName(theClassName); Constructor constructor = testClass.getConstructor(new Class[] { String.class }); testInstance = (ServletTestCase)constructor.newInstance(new Object[] { theMethod }); } catch (Exception e) { As Andrew pointed out, this would never have caught the NoClassDefFoundError error because it is not a subclass of Exception. Modifying it to Throwable did not help. However the error was that ServletTestCase was defined outside the try catch block and thus the error was thrown there and would be caught in the first class because I was catching Throwable there ... So it is a stupid error. However I learnt how the Tomcat class loader worked which I didn't know. I also learned that the error raised when a class is not found by the class loader was NoClassDefFoundError and not (as I thought initially) ClassNotFoundException ! So I'll to rewrite my code as follows : Object dummy; -- cannot use ServletTestCase here as it might raise a NoClassDefFoundError! try { testClass = Class.forName(theClassName); Constructor constructor = testClass.getConstructor(new Class[] { String.class }); dummy = (ServletTestCase)constructor.newInstance(new Object[] { theMethod }); --- need the cast to catch NoClassDefFoundError } catch (Exception e) { ... } ServletTestCase testInstance = (ServletTestCase)dummy; ... which I don't find that easy to write at first ... (I'll need to put some comments to explain the trick) ! You might say, why catch this error and not let it be thrown by the container itself ... However the problem with this is that the error that gets displayed does not give any clue that the initial problem was a NoClassDefFoundError, it just prints the following in the console : [java] StandardWrapperValve[ServletRedirector]: Servlet.service() for servlet ServletRedirector threw exception [java] javax.servlet.ServletException: Servlet execution threw an exception [java] javax.servlet.ServletException: Servlet execution threw an exception [java] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application FilterChain.java:269) which is absolutely not explicit ! Wouldn't it be possible to improve Tomcat so that it chains the exception and also prints the original excpetion in the console ? Thanks again. -Vincent - Original Message - From: Andrew Inggs [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Friday, July 27, 2001 10:01 AM Subject: RE: WebappClassLoader question Hi Vincent You seem to be missing at least two things here: 1. In your original post you said: When I access the servlet, I get a ClassNotFoundException on a JUnit class. So far it is normal ... When I debugged it, I have actually found that the error was happening when ServletTestRedirector was instancianting MyProxyClass (which does _not_ make use of JUnit) and before it was calling its method. This does not look right. You say MyProxyClass does not make use of JUnit, but it *does*. This is the line that causes it to: testInstance = (ServletTestCase)constructor.newInstance(new Object[] { theMethod }); You see here you are explicitly referencing ServletTestCase which extends junit.framework.TestCase, this introduces the dependency. 2. You seem to be assuming that NoClassDefFoundError extends Exception, but it doesn't. If you want to catch a NoClassDefFoundError you'll have to catch it directly, or one of its superclasses (java.lang.LinkageError, java.lang.Error, or java.lang.Throwable). This is why I would have thought here never gets printed out: } catch (Exception e) { log(I would have thought here); } As an aside, I'm not sure what you are trying to achieve here? You don't have junit.jar in your classpath, and then you're say you get this strange error. The details aside, isn't that what you'd expect :-)? Even if you hadn't referenced ServletTestCase directly, you still wouldn't have been able to instantiate it using reflection without junit.jar in the classpath. What are you really trying to achieve? -- Andrew
Re: WebappClassLoader question
Thanks Craig, However I am still not sure this mechanism explains the problem I had. It is not easy to describe in word so I'll write it in java code instead. A.java public class A implements HttpServlet { public void doGet() { log(before error); B myB = new B(); log(after error); } } B.java public class B { public B() { } public doSomething() { try { Class myClass = Class.forName(C); // call the method by reflection ... } catch (Exception e) { log(I would have thought here); } } } C.java import junit.framework.*; public class C extends TestCase { ... } Now all of this is packaged in a war, classes A and B and in a jar put in WEB-INF/lib and class C is put in WEB-INF/classes. The junit jar is *not* put in WEB-INF/lib. Calling the servlet A result in an error occurring between the logs before error and after error and the log I would have thought here is never printed because the error happens _before_ ... This is what I don't understand. Any idea ? Thanks a lot -Vincent - Original Message - From: Craig R. McClanahan [EMAIL PROTECTED] To: [EMAIL PROTECTED]; Vincent Massol [EMAIL PROTECTED] Sent: Thursday, July 26, 2001 6:18 PM Subject: Re: WebappClassLoader question On Thu, 26 Jul 2001, Vincent Massol wrote: Thanks Alex, I don't think the standard classloader mechanism is involved here. I believe it is a 'feature' of Tomcat and more specifically of it's WebappClassLoader. When you do standard java code and you have the following situation : 1st - 2nd --- (using reflection) -- 3rd (not in classpath) then the error always happen in the 2nd class and you can put the code between a try catch block and you'll be able to catch the ClassNotFoundException. However what happens here is that the error happens when calling a method on the 1st class that instanciates the 2nd class ! This is what I don't understand. Am I dreaming or is this a behaviour of Tomcat 4 ? The web app class loader in Tomcat 4 is based on java.net.URLClassLoader, and has the same basic class loading behavior. In particular, when a class A is loaded, all the classes that A directly references (i.e. listed in import statements, used as a variable declaration, and so on) are also loaded. This is done recursively on the referenced classes, until the entire tree of references is resolved. If the load for class A fails, you will get ClassNotFoundException. However, if the load for one of the referenced classes fails, you will typically get NoClassDefError instead (and the class named in the error message may or may not be the one that is actually missing, which complicates debugging this problem tremendously :-). A good rule of thumb to avoid this kind of problem -- if you need to add classes to your CLASSPATH at compile time (when rebuilding the entire app), be sure all of those classes are visible to the web app at runtime. Using reflection, on the other hand, lets you defer loading of dependent classes until runtime, and you can deal with ClassNotFoundException errors that you might run into. Note however that, even if you load a class dynamically, *that* class still contains direct references to other classes that must all be resolved in the manner described above. Thanks -Vincent Craig McClanahan PS: One place where the Tomcat 4 class loader *does* vary from the usual class loader behavior is in the order of places it looks to load a class. The usual pattern in Java2 is to delegate to the parent class loader first, then look locally. Tomcat 4 does the opposite -- it checks in /WEB-INF/classes and /WEB-INF/lib of your web application *before* looking up the parent class loader chain. This means that, if you have a class in the $CATALINA_HOME/lib directory (shared across web apps), and a version of that same class in your web app, the version in your webapp wins. - Original Message - From: Alex Fernández [EMAIL PROTECTED] To: [EMAIL PROTECTED] Sent: Wednesday, July 25, 2001 3:44 PM Subject: Re: WebappClassLoader question Hi Vincent! I've run into the same situation a couple of times, when one class uses a second class, and this second class uses a third one that is not present. 1st - 2nd - 3rd (missing) One would think that instantiating the 2nd should give an error, but that loading the 2nd and/or instantiating the 1st should be ok. In fact, all of the behaviors raise exceptions. The following paragraph in ClassLoader javadoc might be of help: The methods and constructors of objects created by a class loader may reference other classes. To determine the class(es) referred to, the Java virtual machine calls the loadClass method of the class loader that originally created the class. Or, to find out what the JVM is doing, the spec is here: http://java.sun.com/docs/books/vmspec/ Hope it helps. Un saludo, Alex. Vincent Massol wrote
WebappClassLoader question
Hi, Here is the situation : * I have a class that makes use of JUnit (by extending the JUnit TestCase class). Let's call it ServletTestCase * I have a second class that is used to call a method in ServletTestCase, let's call it MyProxyClass * I have a thirdclass (a servlet) that does _not_ make use of JUnit. Let's call it ServletTestRedirector. This class actually instanciate MyProxyClass and calls one of its method. * I package these classes in a war file and I _don't_ include junit.jar in this war file When I access the servlet, I get a ClassNotFoundException on aJUnit class. So far it is normal ... When I debugged it, I have actually found that the error was happening when ServletTestRedirector was instancianting MyProxyClass (which does _not_ make use of JUnit) and before it was calling its method. Here is the stack trace I got : java.lang.NoClassDefFoundError: junit/framework/TestCaseat java.lang.ClassLoader.defineClass0(Native Method)at java.lang.ClassLoader.defineClass(ClassLoader.java:486)at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:111)at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1475)at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:836)at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1215)at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1098)at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)at org.apache.commons.cactus.server.ServletTestRedirector.doPost(ServletTestRedirector.java:143) Here is what I imagined is happening (tell me if this correct or wrong !) : As MyProxyClass is within the war file, the WebappClassLoader gets called to load it. The WebappClassLoader, in trying tofind out the correct class, actually loads some other class in memory, and thus the ServletTestCase, which fails to load because the junit jar is not in the classpath. Is that correct ? Don't you find it strange that the error about the missing class is reported when calling a class that has nothing to do with the problem ? It gets very hard to catch errors ... For example, in MyProxyClass, the code that calls the ServletTestCase method is as follows : ServletTestCase testInstance = null; try { testClass = Class.forName(theClassName); Constructor constructor = testClass.getConstructor(new Class[] { String.class }); testInstance = (ServletTestCase)constructor.newInstance(new Object[] { theMethod }); } catch (Exception e) { logger.debug("Error instanciating class [" + theClassName + "]", e); e.printStackTrace(); throw new ServletException("Error instanciating class [" + theClassName + "]", e); } And there is never anyexception caught here because the error happens earlier in the call stack, when the ServletTestRedirector instanciates MyProxyClass ... ... or am I missing something ? :) Thanks -Vincent Massol