Hi,
I am new to XML and need some helps with SAX parser. I wish to use XML in a data stream through a socket. I choose SAX because of the potential endlessness of the doucment and the need to process an emenemt immediately as soon as any becomes available. About one day into a stress
test of my implementation, the receiving side throwed a SAXException because the parser consumed the whole swap space. Could anyone please tell me what I have done wrong? How can I release the resource once an element is processed?
I append a test case (Server.java & Client.java) similar to my implementation. It compiles and runs with JDK 1.5.0_06 on Solaris 9. To test, launch "java Server" first and run "java Client". While Client is running, Server feeds it with a very long XML stream. SAX parser in Client will reserved more and more memory. It will eventually consume all swap space on disk. The exception was thrown by the line "saxParser.parse(in, xmlHandler);" in Client.java. Please help...
==== Server.java ====
import java.net.*;
import java.io.*;
public class Server {
public static final int SRV_PORT= 24680;
final
String XML_VERSION = "<?xml version=\"1.0\"?>\n";
final String XML_DTD =
"<!DOCTYPE msg_box [\n" +
" ><!ELEMENT msg_box (message*)>\n" +
" <!ELEMENT message (to,from,subject,text)>\n" +
" <!ELEMENT to (#PCDATA)>\n" +
" <!ELEMENT from (#PCDATA)>\n" +
" <!ELEMENT subject (#PCDATA)>\n" +
" <!ELEMENT text (line)>\n" +
" <!ELEMENT line (#PCDATA)>\n" +
"]>\n";
public Server() {
DataOutputStream out = null;
try {
ServerSocket serverSocket = new ServerSocket(SRV_PORT);
System.out.print("Listening to port " + SRV_PORT + "....");
Socket socket = serverSocket.accept();
System.out.println("Connected");
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
System.err.println("Socket open failure.");
e.printStackTrace();
System.exit(1);
}
try {
out.writeBytes(XML_VERSION);
out.writeBytes(XML_DTD);
String
str = "<message>\n" +
" <to>Dave</to>\n" +
" <from>Susan</from>\n" +
" <subject>Reminder</subject>\n" +
" <text>Don't forget to buy milk on the way home.</text>\n" +
"</message>\n";
out.writeBytes("<msg_box>\n");
for (long i=0; i<100000000; i++) {
out.writeBytes(str);
out.flush();
try { Thread.sleep(5); } catch (Exception e) {}
}
out.writeBytes("</msg_box>\n");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String argv[]) {
new Server();
}
}
==== Client.java ====
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.net.*;
import java.io.*;
import javax.xml.parsers.*;
public class Client {
public static final int SRV_PORT= Server.SRV_PORT;
public static final String SRV_NAME= "localhost";
public Client() {
InputStream in = null;
SAXParser saxParser = null;
try {
Socket socket = new Socket(SRV_NAME, SRV_PORT);
socket.setTcpNoDelay(true);
in = socket.getInputStream();
} catch (IOException e) {
System.err.println("Socket open failure.");
System.exit(1);
}
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
try {
saxParser = factory.newSAXParser();
System.out.println("saxParser = " + saxParser);
} catch (SAXException e) {
e.printStackTrace();
System.exit(1);
} catch (ParserConfigurationException e) {
e.printStackTrace();
System.exit(1);
}
DefaultHandler xmlHandler = new XmlHandler();
try {
saxParser.parse(in, xmlHandler);
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public static void main(String argv[]) {
new Client();
}
}
class XmlHandler extends DefaultHandler {
public void startDocument() throws SAXException {
System.out.println("startDocument");
}
public void endDocument() throws SAXException {
System.out.println("endDocument");
}
public void startElement(String namespaceURI,
String localName,
String qualifiedName,
Attributes attributes)
throws SAXException {
}
static int count = 0;
public void endElement(String namespaceUri,
String localName,
String qualifiedName)
throws SAXException {
if (qualifiedName!=null && qualifiedName.equals("message"))
System.out.println("message count = " + (++count));
}
public void characters(char buf[], int offset, int len)
throws SAXException {
}
}