Remy, thanks for the response. Some more information on the issue:
Printing out the value of resource.retrieveSessionInstance() for each of the
threads shows that sometimes the HttpClient objects for more than one
WebdavResource is the same, which I'm not sure is a problem or not (I would
think it would be because HttpClient maintains state about the connection).
There is some logic in WebdavSession.getSessionInstance() that keeps clients
in a HashMap keyed off of httpURL.getAuthority(). Wouldn't that be the same
for connections to the same machine?
Also, I was able to reproduce some other exceptions more easily by slowing
the rate at which new threads are created. These exceptions plus the
exerciser program used to cause them are attached (may have to run it a few
times to reproduce them). Pardon the large message.
thanks,
Pete
output:
-----
Making DAV Connection...
HttpClient: org.apache.commons.httpclient.HttpClient@6102dc
Making DAV Connection...
Making DAV Connection...
Making DAV Connection...
connect time = 3205
java.lang.IllegalArgumentException: port out range:-1
HttpClient: org.apache.commons.httpclient.HttpClient@4741d6
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at
org.apache.commons.httpclient.HttpClient.openConnection(HttpClient.java:764)
at
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:412)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2452
)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2421
)
at
org.apache.webdav.lib.WebdavResource.setNamedProp(WebdavResource.java:650)
at
org.apache.webdav.lib.WebdavResource.setBasicProperties(WebdavResource.java:
637)
at
org.apache.webdav.lib.WebdavResource.setProperties(WebdavResource.java:1541)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:988)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1007)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1086)
at
org.apache.webdav.lib.WebdavResource.<init>(WebdavResource.java:256)
at
ExchangeWebdavTest$ExchangeWebdavThread.run(ExchangeWebdavTest.java:115)
at java.lang.Thread.run(Unknown Source)
java.lang.IllegalArgumentException: port out range:-1
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at
org.apache.commons.httpclient.HttpClient.openConnection(HttpClient.java:764)
at
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:412)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2452
)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2421
)
at
org.apache.webdav.lib.WebdavResource.setNamedProp(WebdavResource.java:650)
at
org.apache.webdav.lib.WebdavResource.setBasicProperties(WebdavResource.java:
637)
at
org.apache.webdav.lib.WebdavResource.setProperties(WebdavResource.java:1541)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:988)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1007)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1086)
at
org.apache.webdav.lib.WebdavResource.<init>(WebdavResource.java:256)
at
ExchangeWebdavTest$ExchangeWebdavThread.run(ExchangeWebdavTest.java:115)
at java.lang.Thread.run(Unknown Source)
Making DAV Connection...
connect time = 5007
java.io.IOException: Socket Closed
at java.net.PlainSocketImpl.getOutputStream(Unknown Source)
at java.net.Socket$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.Socket.getOutputStream(Unknown Source)
at
org.apache.commons.httpclient.HttpClient.openConnection(HttpClient.java:768)
at
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:412)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2452
)
at
org.apache.webdav.lib.WebdavResource.propfindMethod(WebdavResource.java:2421
)
at
org.apache.webdav.lib.WebdavResource.setNamedProp(WebdavResource.java:650)
at
org.apache.webdav.lib.WebdavResource.setBasicProperties(WebdavResource.java:
637)
at
org.apache.webdav.lib.WebdavResource.setProperties(WebdavResource.java:1541)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:988)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1007)
at
org.apache.webdav.lib.WebdavResource.setHttpURL(WebdavResource.java:1086)
at
org.apache.webdav.lib.WebdavResource.<init>(WebdavResource.java:256)
at
ExchangeWebdavTest$ExchangeWebdavThread.run(ExchangeWebdavTest.java:115)
at java.lang.Thread.run(Unknown Source)
-----
source code to new exerciser to reproduce thread issue:
-----
import java.io.*;
import java.util.*;
import org.apache.util.*;
import org.apache.webdav.lib.*;
import org.apache.webdav.lib.methods.*;
/**
*
* Class description.
*
* @author PHeist (07/01)
*/
public class ExchangeWebdavTest
{
/**
* Method description.
*
* @author PHeist (07/01)
*/
public ExchangeWebdavTest
(
)
{
}
/**
* Main.
*
* @author PHeist (07/01)
*/
public static void main
(
String[] args
)
{
for (int i = 0; i < Integer.parseInt (args[1]); i++)
{
ExchangeWebdavTest test = new ExchangeWebdavTest();
Thread thr = new Thread (test.new ExchangeWebdavThread (new String
(args[0])));
thr.start ();
try
{
Thread.sleep (1000L);
}
catch (InterruptedException ie)
{
}
}
}
/**
*
* Exchange WebDAV thread.
*
* @author PHeist (07/01)
*/
public class ExchangeWebdavThread
implements Runnable
{
private String i_sUrl;
/**
* Constructor.
*
* @author PHeist (07/01)
*/
public ExchangeWebdavThread
(
String sUrl
)
{
i_sUrl = sUrl;
}
/**
* Method description.
*
* @author PHeist (07/01)
*/
public void run
(
)
{
WebdavResource resource = null;
try
{
System.out.println ("Making DAV Connection...");
HttpURL url = new HttpURL (i_sUrl);
url.setUserInfo ("CLUSTER\\PHeist", "pheist");
long lStart = System.currentTimeMillis ();
resource = new WebdavResource (url);
System.out.println ("HttpClient: " + resource.retrieveSessionInstance());
Enumeration props = resource.propfindMethod(Integer.MAX_VALUE);
int i = 0;
while (props.hasMoreElements())
{
ResponseEntity entity = (ResponseEntity) props.nextElement();
Enumeration responseProperties = entity.getProperties();
while (responseProperties.hasMoreElements())
{
Property responseProp = (Property) responseProperties.nextElement();
}
}
System.out.println ("connect time = " + (System.currentTimeMillis() -
lStart));
}
catch (Exception e)
{
e.printStackTrace ();
}
finally
{
if (null != resource)
try
{
resource.close ();
}
catch (IOException ioe)
{
}
}
}
} // ExchangeWebdavThread
} // ExchangeWebdavTest
-----
-----Original Message-----
From: Remy Maucherat [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, July 11, 2001 2:15 PM
To: [EMAIL PROTECTED]
Subject: Re: thread-safety issue with webdav client library (and tip on
connecting to Exchange 2K)
----- Original Message -----
From: "Pete Heist" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, July 11, 2001 7:58 AM
Subject: thread-safety issue with webdav client library (and tip on
connecting to Exchange 2K)
...
> Nextly, there is an issue with thread-safety that appers to be in the
Slide
> WebDAV client library and is simple to reproduce. At the bottom of this
> email is source code written to Slide 1.0.11 that causes the error. It
> simply creates N number of threads to do a PROPFIND for all properties.
> (This exerciser really doesn't need to connect to Exchange 2K- any WebDAV
> server should be fine.) An example command line to run it with five
threads
> is as follows:
>
> java ExchangeWebdavTest http://server/exchange/Mailbox/Inbox 5
>
> Occasionally all five threads will succeed, but much of the time output
will
> be like:
Thanks for the report.
I look at your code, and it's fine, as you have one Webdav client associated
with each thread.
I think the problem is that the WebdavResource uses some static fields,
which need to be removed. Thanks for the code, that will help me fix the
issue.
...
Remy