I'm stumped on an unusual problem. I'm running java 1.3 and Apache JServ (don't ask, I inherited this set up), using JSSE. One of the things we do with our app involves some xml communication over SSL.
Starting last week, the time for the SSL communication jumped from about 15 seconds to around 3 minutes.
Here is the bit of code that does the actual communication. An example function call would be:
contactService("ShipConfirm", "ups.app/xml");
and the function definition:
public void contactService(String service, String prefix) throws Exception {
HttpURLConnection connection;
URL url;
// the next 2 variables are stored elsewhere in the object
// these values are just examples of one invocation
String protocol = "https";
String hostname = "wwwcie.ups.com";
String urlStr = protocol + "://" + hostname + "/" + prefix + "/" + service;
// so for this test urlString = "https://wwwcie.ups.com/ups.app/xml/ShipConfirm";
try {
if (protocol.equalsIgnoreCase("https")) {
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.getProperties().put("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
}
url = new URL(urlString);
// Trace.log is a convenience class that will print to a log file and include a timestamp
Trace.log("open connection to " + urlString);
connection = (HttpURLConnection) url.openConnection();
// openConnection takes about 20 seconds now, before 1 or 2 seconds
Trace.log("opened connection to " + urlString);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
// XmlIn is an already generated xml file stored in a StringBuffer, declared elsewhere
String queryString = XmlIn.toString();
Trace.log("xml connection to " + urlString);
connection.connect();
// connect takes about 3 minutes 10 seconds now, before 15 seconds
Trace.log("xml connection complete " + urlString);
OutputStream out = connection.getOutputStream();
out.write(queryString.getBytes());
out.close();
String data = "";
try {
// on the server this is actually a separate function
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
int letter = 0;
while ((letter = reader.read()) != -1)
buffer.append((char) letter);
}
catch (Exception e) {
// Trace.major is like Trace.log, but is a higher severity
Trace.major("Cannot read from URL" + e.toString());
throw e;
}
finally {
try {
reader.close();
}
catch (IOException io) {
Trace.major("Error closing URLReader!");
throw io;
}
}
data = buffer.toString(); // actually a return statement on server
}
catch (Exception e) {
Trace.major("Error in reading URL Connection" + e.getMessage());
throw e;
}
XmlOut = new StringBuffer(data); // XmlOut is a StringBuffer declared elsewhere
}
catch (Exception e1) {
Trace.major("Error sending data to server" + e1.toString());
}
}
Besides a couple of new Trace.log statements to pin down the what, exactly, is taking so long, I haven't touched this code in the year+ since I've inherited it. There haven't been any changes in the network setup for the last 3 weeks, either (last change was new reverse lookup zone for our internal network).
Any idea why the HttpURLConnection.connect() would take so long? Or any idea how I can find out what is going on for those 3 minutes? In my search so far, I found -Djava.net.debug=ssl,handshake,data and added it to my startup parameters, but in my frustration, I must have overlooked what I need do to make it show up in my logs.
I set up a tcpdump on the server to listen on the IP that I'm trying to connect to and the "xml connection to" log statement prints, then about 3 minutes and 10 seconds goes by, then tcpdump reports that we actually send the packets to the other server, then we get a response and print the "xml connection complete" log message. URL and HttpURLConnection are not subclassed at all.
To make things even more interesting, I broke out this code, and wrote a small test program. The test program has some minor changes (pulling the xml data from an already existing file, mainly), and this version runs lickety-split (about 5 seconds).
Any help or pointers would be greatly appreciated. Let me know if I can provide any more information.
Thanks,
Andy