hey I'm trying to transmit objects encoded by XMLEncoder over a network, using sockets. Usually, all I have to do to decode such objects is open an inputStream with them and tell XMLDecoder to decode them. But decoder refuses to interpret the data until the inputStream closes - that is, until the connection is broken, which is terrible for my application. To circumvent this, I subclassed XMLEncoder so I can print the "</java>" without closing the outputStream (as XMLEncoder.close() would do). This works absolutely fine, and I have double checked that it operates correctly by saving and loading files with it without any problems. But the decoder still waited for inputStream to close, so instead I decided to have a BufferReader read the stream in until it hit </java> (instead of waiting for the inputStream to close) and then feed the resulting text to the XMLDecoder. This way, the program can interpret data without closing the socket. The issue is, the XMLDecoder can only decode from inputStreams or subclasses of them. When I try to decode from my custom input stream InputStreamFromText, I get...

rg.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
Continuing ...
Exception in thread "main" java.util.NoSuchElementException
at java.util.Vector.lastElement(Unknown Source)
at com.sun.beans.ObjectHandler.lastExp(Unknown Source)
at com.sun.beans.ObjectHandler.dequeueResult(Unknown Source)
at java.beans.XMLDecoder.readObject(Unknown Source)
at SimpleSocketServer.main(SimpleSocketServer.java:45)

In short, the readObject call from the XMLDecoder fails - the NoSuchElementException is a result of the lack of output from the decoder. I've read in many places that SAXParseException is usually the result of whitespace at the beginning of the xml file, but there is no offending whitespace here.

here are the relevant parts of my code. I think that the issue is that InputStreamFromText does not override enough methods from InputStream:

Code:
import java.io.*;

public class InputStreamFromText extends InputStream
{
	StringBuffer the_text;
	int index;
	int marking;
	
	public InputStreamFromText(StringBuffer str)
	{
		the_text=str;
		index=0;
		marking =-1;
	}
	
	public int read()
	{

		index++;
		if(index <= the_text.length())
		{
			System.out.println("read "+ Integer.toString(index) +": "+ the_text.charAt(index-1));
			return the_text.codePointAt(index-1);
		}
		else
			return -1;
	}
	
	public void mark(int limit)
	{
		marking=index;
	}
	
	public boolean markSupported()
	{
		return true;
	}
	
	public void reset() throws IOException
	{
		if(marking != -1)
			index=marking;
		else
			throw new IOException();
	}
	
	public int available() throws IOException
	{
		return the_text.length()-index;
	}
}
The server side of the networking code - where the decoding is done. Pay attention to the XMLDecoder. "Checkpoint" is always output before any exceptions, but "Checkpoint 2" is never reached.

Code:
import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleSocketServer {

  public static void main(String args[]) throws Exception {
    ServerSocket serverSocket;
    int portNumber = 1777;
    Socket socket;    
    
    serverSocket = new ServerSocket(portNumber);

    System.out.println("Waiting for a connection on " + portNumber);

    socket = serverSocket.accept();
	InputStream IS = socket.getInputStream();
 	OutputStream OS = socket.getOutputStream(); 
	
	BufferedReader reader = new BufferedReader(new InputStreamReader(IS));

	String line=reader.readLine();
	StringBuffer str = new StringBuffer(line);
	Boolean kill=false;
	while(line != null && !kill)
	{
		str.append(line);
		System.out.println(line);
		if(line.indexOf("</java>") == -1)
			line = reader.readLine();
		else
			kill=true;
	}
	
	InputStreamFromText IS2 = new InputStreamFromText(str);
	XMLDecoder decoder = new XMLDecoder(IS2);
	System.out.println("Checkpoint");
	Galaxy result =(Galaxy) decoder.readObject();
	System.out.println("Checkpoint 2");
	decoder.close();

    reader.close();
    socket.close();

  }

}