Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > URLConnection bug?

Reply
Thread Tools

URLConnection bug?

 
 
Howard Rubin - change nospam to nyx
Guest
Posts: n/a
 
      01-13-2004
The Microsoft JVM seems to have a bug reading multiple URLs.

My test applet opens URLs in this sequence:
1. A URL that returns a basically empty HTML page
2. A URL that streams data for 2 seconds.
3. The same URL from step 1.
The problem is that #3 returns the tail end of #2's data instead of the
same data as #1, in spite of the fact that I close the InputStream,
call the garbage collector, and run the finalizers.

To see this in action, open
http://test.stream.wallst.com/JreBugTest.htm
and click the 'Go' button. Output will display in the applet and
also in the Java console.

This only occurs with Microsoft's JVM, not Sun's or others I've tried.
Am I missing something, or is there some other way to close a URLConnection?

Source code for the applet and isapi streaming dll are included in
the JAR file, and appended here as well:

---------- applet source ------------
import java.awt.*;
import java.applet.*;
import java.net.*;
import java.io.*;

public class datatest extends Applet
{
java.awt.Button button1 = new java.awt.Button();
StringBuffer m_s1 = new StringBuffer(),
m_s2 = new StringBuffer();

// Called when 'Go' button is pressed
class Listener implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent event) {
m_s1.setLength(0); m_s2.setLength(0); repaint();
final String sBase = getCodeBase().getHost(), sFile = getCodeBase().getFile();
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_C URSOR));

// Demonstrate different output from 2 calls to empty.htm
for (int i=0; i<2; ++i) {
System.gc(); System.runFinalization();

////////////////////////////////////////////////////////////////
// Get HTML data from empty.htm
////////////////////////////////////////////////////////////////
String sHtmlUrl = "http://" + sBase + sFile + "empty.htm";
System.out.println(getHtmlData(i==0 ? m_s1 : m_s2, sHtmlUrl));

////////////////////////////////////////////////////////////////
// Get partial stream data between 2 calls to empty.htm
////////////////////////////////////////////////////////////////
if (i == 0) {
String sStreamUrl = "http://" + sBase + sFile + "streamtest.dll";
StringBuffer s = new StringBuffer();
getHtmlData(s, sStreamUrl);
}
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAUL T_CURSOR));
}
}

StringBuffer getHtmlData(StringBuffer sContent, String sUrl) {
URL url = null;
try { url = new URL(sUrl); }
catch (MalformedURLException e) { exceptionReport(e); }

URLConnection conn = null;
try { conn = url.openConnection(); }
catch (IOException e) { exceptionReport(e); }

java.io.InputStream in = null;
try {
in = conn.getInputStream();
int nextByte;
for (int i=0; i<15 && (nextByte = in.read()) != -1; ++i)
sContent.append((char)nextByte);
}
catch (IOException e) { exceptionReport(e); }
finally {
if (in != null)
try { in.close(); }
catch (IOException e) { exceptionReport(e); }
}
return sContent;
}


void exceptionReport(Throwable e) {
System.out.println(e.getMessage());
e.printStackTrace(System.out);
}

public void init()
{
setLayout(null);
setSize(426,266);
button1.setLabel("Go");
add(button1);
button1.setBounds(36,12,60,24);

Listener lListener = new Listener();
button1.addActionListener(lListener);
}

public void paint(Graphics g) {
g.drawString("1st call to empty.htm: " + m_s1.toString(), 10, 120);
g.drawString("2nd call to empty.htm: " + m_s2.toString(), 10, 140);
g.drawString("Both should be: \"<html> <head> </head> <body>\"", 10, 160);
}
}
---------- isapi source ------------

#include "stdafx.h"
#include <stdio.h>

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = HSE_VERSION;
strncpy(pVer->lpszExtensionDesc, "Data streaming ISA", HSE_MAX_EXT_DLL_NAME_LEN);

return TRUE;
}
BOOL WINAPI TerminateExtension(DWORD dwFlags)
{
return TRUE;
}

void ProcessRequest(void* p)
{
EXTENSION_CONTROL_BLOCK* pECB = static_cast<EXTENSION_CONTROL_BLOCK*>(p);

// Send header
static const char szStatus[] = "200 OK",
szHeader[] = "Content-Type: application/octet-stream\r\n"
"Cache-Control: no-cache\r\n"
"Expires: Sat, 01 Jan 2000 00:00:00 GMT\r\n"
"\r\n";
static HSE_SEND_HEADER_EX_INFO header = { szStatus, szHeader, sizeof szStatus - 1, sizeof szHeader - 1, TRUE };
pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, (void*)&header, NULL, NULL);

char buffer[20];
for (int i=0; i<20; ++i)
{
sprintf(buffer, "%02d|", i);
DWORD dw = strlen(buffer);
pECB->WriteClient(pECB->ConnID, (void*)buffer, &dw, HSE_IO_SYNC);
Sleep(100);
}
pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, NULL, NULL, NULL);
}

DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK* pECB)
{
_beginthread(ProcessRequest, 0, pECB);
return HSE_STATUS_PENDING;
}
 
Reply With Quote
 
 
 
 
Andrew Thompson
Guest
Posts: n/a
 
      01-13-2004
"Howard Rubin - change nospam to nyx" <(E-Mail Removed)> wrote
in message news:(E-Mail Removed)...
| The Microsoft JVM seems to have a bug reading multiple URLs.

I wish I had a $ for every time I
heard 'Microsoft', 'JVM' and 'bug'
in the same sentence...

[ non-valid groups trimmed.. ]

--
Andrew Thompson
* http://www.PhySci.org/ PhySci software suite
* http://www.1point1C.org/ 1.1C - Superluminal!
* http://www.AThompson.info/andrew/ personal site


 
Reply With Quote
 
 
 
 
Leo Gaggl
Guest
Posts: n/a
 
      01-13-2004

Andrew Thompson wrote:

> I wish I had a $ for every time I
> heard 'Microsoft', 'JVM' and 'bug'
> in the same sentence...


And if you drop the 'JVM' you could stop working and join Billy G. on
the Fortune 500








 
Reply With Quote
 
ppcdev
Guest
Posts: n/a
 
      01-13-2004
Leo Gaggl <(E-Mail Removed)-8.com> wrote in message news:<(E-Mail Removed)>...
> Andrew Thompson wrote:
>
> > I wish I had a $ for every time I
> > heard 'Microsoft', 'JVM' and 'bug'
> > in the same sentence...

>
> And if you drop the 'JVM' you could stop working and join Billy G. on
> the Fortune 500
>
>


why use microsoft java ? isn't java an ibm stuff ?
 
Reply With Quote
 
Howard Rubin - change nospam to nyx
Guest
Posts: n/a
 
      01-13-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (ppcdev) wrote:
>why use microsoft java ? isn't java an ibm stuff ?


The microsoft jvm/jre is installed on most windows PCs, and sun's
download is too big for our customers on modem connections.
 
Reply With Quote
 
Howard Rubin - change nospam to nyx
Guest
Posts: n/a
 
      01-13-2004
The Microsoft JVM seems to have a bug reading multiple URLs.

My test applet opens URLs in this sequence:
1. A URL that returns a basically empty HTML page
2. A URL that streams data for 2 seconds.
3. The same URL from step 1.
The problem is that #3 returns the tail end of #2's data instead of the
same data as #1, in spite of the fact that I close the InputStream,
call the garbage collector, and run the finalizers.

To see this in action, open
http://test.stream.wallst.com/JreBugTest.htm
and click the 'Go' button. Output will display in the applet and
also in the Java console.

This only occurs with Microsoft's JVM, not Sun's or others I've tried.
Am I missing something, or is there some other way to close a URLConnection?

Source code for the applet and isapi streaming dll are included in
the JAR file, and appended here as well:

---------- applet source ------------
>import java.awt.*;
>import java.applet.*;
>import java.net.*;
>import java.io.*;
>
>public class datatest extends Applet
>{
> java.awt.Button button1 = new java.awt.Button();
> StringBuffer m_s1 = new StringBuffer(),
> m_s2 = new StringBuffer();
>
> // Called when 'Go' button is pressed
> class Listener implements java.awt.event.ActionListener {
> public void actionPerformed(java.awt.event.ActionEvent event) {
> m_s1.setLength(0); m_s2.setLength(0); repaint();
> final String sBase = getCodeBase().getHost(), sFile =
>getCodeBase().getFile();
> setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_C URSOR));
>
> // Demonstrate different output from 2 calls to empty.htm
> for (int i=0; i<2; ++i) {
> System.gc(); System.runFinalization();
>
> ////////////////////////////////////////////////////////////////
> // Get HTML data from empty.htm
> ////////////////////////////////////////////////////////////////
> String sHtmlUrl = "http://" + sBase + sFile + "empty.htm";
> System.out.println(getHtmlData(i==0 ? m_s1 : m_s2, sHtmlUrl));
>
> ////////////////////////////////////////////////////////////////
> // Get partial stream data between 2 calls to empty.htm
> ////////////////////////////////////////////////////////////////
> if (i == 0) {
> String sStreamUrl = "http://" + sBase + sFile +
>"streamtest.dll";
> StringBuffer s = new StringBuffer();
> getHtmlData(s, sStreamUrl);
> }
> }
> setCursor(Cursor.getPredefinedCursor(Cursor.DEFAUL T_CURSOR));
> }
> }
>
> StringBuffer getHtmlData(StringBuffer sContent, String sUrl) {
> URL url = null;
> try { url = new URL(sUrl); }
> catch (MalformedURLException e) { exceptionReport(e); }
>
> URLConnection conn = null;
> try { conn = url.openConnection(); }
> catch (IOException e) { exceptionReport(e); }
>
> java.io.InputStream in = null;
> try {
> in = conn.getInputStream();
> int nextByte;
> for (int i=0; i<15 && (nextByte = in.read()) != -1; ++i)
> sContent.append((char)nextByte);
> }
> catch (IOException e) { exceptionReport(e); }
> finally {
> if (in != null)
> try { in.close(); }
> catch (IOException e) { exceptionReport(e); }
> }
> return sContent;
> }
>
>
> void exceptionReport(Throwable e) {
> System.out.println(e.getMessage());
> e.printStackTrace(System.out);
> }
>
> public void init()
> {
> setLayout(null);
> setSize(426,266);
> button1.setLabel("Go");
> add(button1);
> button1.setBounds(36,12,60,24);
>
> Listener lListener = new Listener();
> button1.addActionListener(lListener);
> }
>
> public void paint(Graphics g) {
> g.drawString("1st call to empty.htm: " + m_s1.toString(), 10, 120);
> g.drawString("2nd call to empty.htm: " + m_s2.toString(), 10, 140);
> g.drawString("Both should be: \"<html> <head> </head> <body>\"",
>10, 160);
> }
>}

---------- isapi source ------------
>
>#include "stdafx.h"
>#include <stdio.h>
>
>BOOL APIENTRY DllMain( HANDLE hModule,
> DWORD ul_reason_for_call,
> LPVOID lpReserved
> )
>{
> return TRUE;
>}
>
>BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
>{
> pVer->dwExtensionVersion = HSE_VERSION;
> strncpy(pVer->lpszExtensionDesc, "Data streaming ISA",
>HSE_MAX_EXT_DLL_NAME_LEN);
>
> return TRUE;
>}
>BOOL WINAPI TerminateExtension(DWORD dwFlags)
>{
> return TRUE;
>}
>
>void ProcessRequest(void* p)
>{
> EXTENSION_CONTROL_BLOCK* pECB = static_cast<EXTENSION_CONTROL_BLOCK*>(p);
>
> // Send header
> static const char szStatus[] = "200 OK",
> szHeader[] = "Content-Type: application/octet-stream\r\n"
> "Cache-Control: no-cache\r\n"
> "Expires: Sat, 01 Jan 2000 00:00:00 GMT\r\n"
> "\r\n";
> static HSE_SEND_HEADER_EX_INFO header = { szStatus, szHeader, sizeof
>szStatus - 1, sizeof szHeader - 1, TRUE };
> pECB->ServerSupportFunction(pECB->ConnID,
>HSE_REQ_SEND_RESPONSE_HEADER_EX, (void*)&header, NULL, NULL);
>
> char buffer[20];
> for (int i=0; i<20; ++i)
> {
> sprintf(buffer, "%02d|", i);
> DWORD dw = strlen(buffer);
> pECB->WriteClient(pECB->ConnID, (void*)buffer, &dw, HSE_IO_SYNC);
> Sleep(100);
> }
> pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_DONE_WITH_SESSION,
>NULL, NULL, NULL);
>}
>
>DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK* pECB)
>{
> _beginthread(ProcessRequest, 0, pECB);
> return HSE_STATUS_PENDING;
>}



 
Reply With Quote
 
Andrew Thompson
Guest
Posts: n/a
 
      01-14-2004
"Howard Rubin - change nospam to nyx" <(E-Mail Removed)> wrote
in message news:(E-Mail Removed)...
| (E-Mail Removed) (ppcdev) wrote:
| >why use microsoft java ? isn't java an ibm stuff ?
|
| The microsoft jvm/jre is installed on most windows PCs, and
sun's
| download is too big for our customers on modem connections.

That is unfortunate.

By the way. Sorry for diverting your original
thread, I noticed you had to resubmit it in
an effort not to let the question get lost in the
quagmire of MS bashing.

I am not _that_ experienced with applets
and URL connections, but if I have time
later I will have a look over it. (Never
attempted one with multiple connections..)

I hope you get an answer that
solves the problem.

--
Andrew Thompson
* http://www.PhySci.org/ PhySci software suite
* http://www.1point1C.org/ 1.1C - Superluminal!
* http://www.AThompson.info/andrew/ personal site


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
OutputStream from a URLConnection produces an OutOfMemory OutputStream from a URLConnection produces an OutOfMemory WinstonSmith_101@hotmail.com Java 2 10-25-2006 04:45 PM
write a string from URLConnection to a servlet dave Java 0 12-03-2003 07:47 PM
Problems encoding in utf8 with urlconnection response Bronwyn Howard Java 0 10-01-2003 06:10 AM
URLConnection to WebService gets FileNotFoundException Brock Jones Java 0 09-04-2003 12:10 AM
URLConnection and proxy Kristoffel Java 0 07-27-2003 08:27 PM



Advertisments