-
applet to servlet EOFException
Hi,
I'm trying to send an object to a servlet for processing. However, I keep getting an EOFException or NullPointerException (depending on the order I arrange my code in the applet) on the readObject() method on the servlet. I've checked my code against numerous examples on the NET and don't see an obvious difference. Can someone please help.
Please advise,
Alan Shiers
*******************************************
TOMCAT LOG FILE:
Attempting to read Object...
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at TableDataServlet.doPost(TableDataServlet.java:31)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFil terChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain .java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java: 214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java: 178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:10 7)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnecti on(Http11Protocol.java:731)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:5 26)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorke rThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:6 84)
at java.lang.Thread.run(Unknown Source)
TABLEDATASERVLET:
Code:
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TableDataServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
doPost(request,response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
ObjectInputStream inputFromApplet = null;
TableData td = null;
PrintWriter out = null;
String[][] data = null;
try
{
// get an input stream from the applet
inputFromApplet = new ObjectInputStream(new BufferedInputStream(request.getInputStream()));
System.out.println("Attempting to read Object...");
// read the serialized data from applet
Object o = inputFromApplet.readObject(); //<<This is the culprit!!
if(o != null && (o instanceof TableData))
{
td = (TableData) o;
System.out.println("Got Object");
inputFromApplet.close();
data = td.getData();
String firstname = data[0][1];
// send back a confirmation message to the applet
out = new PrintWriter(response.getOutputStream());
response.setContentType("text/plain");
out.println("confirmed " + firstname);
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
class TableData implements Serializable
{
String[][] data = null;
public TableData(String[][] newData)
{
if(newData != null)
data = newData;
}
public String[][] getData()
{
return data;
}
public void setData(String[][] newData)
{
if(newData != null)
data = newData;
}
}
}
TABLEFORM APPLET:
Code:
package forms;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.util.*;
import java.applet.*;
import java.io.*;
import java.net.*;
public class TableForm extends JApplet implements ActionListener
{
...
public void actionPerformed(ActionEvent e)
{
...
if(e.getSource() == submit)
{
...
//Load up a 2D array
String[][] data = new String[RowCount][headers.length];
for(int i = 0; i < RowCount; i++)//rows
{
for(int j = 1; j < headers.length; j++)//columns
{
data[i][j - 1] = (String)dm.getValueAt(i,j);
}
}
TableData td = new TableData(data);
try
{
// connect to the servlet
String location = processingServlet;
URL testServlet = new URL( location );
URLConnection servletConnection = testServlet.openConnection();
if (servletConnection instanceof HttpURLConnection)
{
((HttpURLConnection)servletConnection).setRequestMethod("POST");
}
else
{
System.out.println("this connection is NOT an HttpUrlConnection connection");
return;
}
//inform the connection that we will send output and accept input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);
//Don't use a cached version of URL connection.
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches (false);
//Specify the content type that we will send binary data
servletConnection.setRequestProperty ("Content-Type", "application/octet-stream");
//send your data to the servlet
statusTextArea.append("Sending data to servlet..." + "\n");
ObjectOutputStream outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(servletConnection.getInputStream()));
outputToServlet.writeObject(td);
outputToServlet.flush();
outputToServlet.close();
statusTextArea.append("Data has been sent." + "\n");
//now wait for a response from the servlet
statusTextArea.append("Waiting for response..." + "\n");
String line = "";
while((line = in.readLine()) != null)
{
statusTextArea.append(line + "\n");
}
in.close();
statusTextArea.append("Communication ended." + "\n");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
private boolean isNumeric(String str)
{
for(int i = 0; i < str.length(); i++)
{
if(!Character.isDigit(str.charAt(i)))
return false;
}
return true;
}
class TableData implements Serializable
{
String[][] data = null;
public TableData(String[][] newData)
{
if(newData != null)
data = newData;
}
public String[][] getData()
{
return data;
}
public void setData(String[][] newData)
{
if(newData != null)
data = newData;
}
}
}
-
Shouldn't your TableData class have a couple of
methods more, in order to be serializable.
from the sun doc:
The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
I think you should implement these two in your
TableData class.
Code:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
The serializable interface can be specified for a class that
lack these two methods, without you getting a
compile error, since its just a "tagging" interface
eschew obfuscation
-
applet to servlet EOFException
My understanding is that it isn't necessary to implement the two methods you mentioned except in special cases. The class is just a wrapper for a String array. That's not very complicated. If you think those two methods are really necessary, how would you implement them?
Alan
-
When you try to serialize e.g a Vector then the vector
will write its signature and then call each of its elements
serialization method (writeObject). If you haven't made
one for the elements in the Vector the defaults are used
and that is not what you want, inless the vector is filled
w. primitives.
Your class, even though it only contains a string is not a
primitive.
This is an excerpt from a previous thread in this forum.
The Calendar entry only has two (interesting) class
variables: date and appointment, both strings:
Code:
/**
* the following two methods are required by a serializable object
*
* Serialize out this CalendarEntry object
*/
private void writeObject(ObjectOutputStream out)
throws IOException {
writeString(date, out);
writeString(appointment, out);
}
/**
* Serialize in this CalendarEntry object
*/
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
this.date=readString(in);
this.appointment=readString(in);
}
/**
* the following two are utility functions for writing & reading
* String objects in ObjectIOStreams.
*/
private void writeString(String s, ObjectOutputStream out) throws IOException {
int n=s.length();
out.writeInt(n);
out.writeBytes(s);
}
private String readString(ObjectInputStream in) throws IOException {
int n=in.readInt();
byte [] b=new byte[n];
in.read(b);
return new String(b);
}
Note: if you change your serialized class in a
way that affects its serialization, then you wont be able
to serialize in data that was serialized out w. the old
version; the serialization "stamps" its output w. a
version indicator.
PS: in your table case I would start the output w. a
Dimension object (guess what dimension ?)
and then a row-column traversal output of each
table element. The trick is to do it all in the same
sequencs when you read it in again.
eschew obfuscation
-
You know...you might be onto something here. I'd like to give this a try. Based on your recommendations I've rewritten the TableData class as follows. If you think it needs refinement, please show me what you'd change.
Note that I added the "transient" keyword to the array declaration.
Alan
****************************
Code:
class TableData implements Serializable
{
transient String[][] data = null;
public TableData(String[][] newData)
{
if(newData != null)
data = newData;
}
public String[][] getData()
{
return data;
}
public void setData(String[][] newData)
{
if(newData != null)
data = newData;
}
private void writeObject(ObjectOutputStream out)throws IOException
{
Dimension d = new Dimension(data.length, data[0].length);
out.writeObject(d);
for(int i = 0; i < d.getWidth(); i++)
{
for(int j = 0; j < d.getHeight(); j++)
{
writeString(data[i][j], out);
}
}
}
private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException
{
Dimension d = in.readObject();
data = new String[d.getWidth()][d.getHeight()];
for(int i = 0; i < d.getWidth(); i++)
{
for(int j = 0; j < d.getHeight(); j++)
{
data[i][j] = readString(data[i][j], out);
}
}
}
private void writeString(String s, ObjectOutputStream out)throws IOException
{
int n = s.length();
out.writeInt(n);
out.writeBytes(s);
}
private String readString(ObjectInputStream in)throws IOException
{
int n = in.readInt();
byte[] b = new byte[n];
in.read(b);
return new String(b);
}
}
-
There was a few buggies, I think I have killed them,
I also left the idea of the Dimension object, since its
width & height appeared a bit confusing to me...
Code:
import java.io.*;
public class TableData implements Serializable{
transient String[][] data = null;
public TableData(String[][] newData) {
if (newData != null)
data = newData;
}
public String[][] getData() {
return data;
}
public void setData(String[][] newData) {
if (newData != null)
data = newData;
}
private void writeObject(ObjectOutputStream out) throws IOException {
int rows=data.length;
int cols=data[0].length;
out.writeInt(rows);
out.writeInt(cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
writeString(data[i][j], out);
}
}
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
int rows=in.readInt();
int cols=in.readInt();
data = new String[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = readString(in);
}
}
}
private void writeString(String s, ObjectOutputStream out) throws IOException {
int n = s.length();
out.writeInt(n);
out.writeBytes(s);
}
private String readString(ObjectInputStream in) throws IOException {
int n = in.readInt();
byte[] b = new byte[n];
in.read(b);
return new String(b);
}
}
eschew obfuscation
-
Hi,
Yeah, I found the Dimension object clunky too. Its getWidth() and getHeight() methods returned doubles instead of ints. That would have meant I would have had to cast to ints.
I refined the class as suggested and ran the application. Unfortunateley, refining the serialization of the class has not fixed the issue. I am getting a NullPointerException on the readObject() method on the servlet still. Following is the Tomcat log.
Now, what could be the problem?
Alan
...
Attempting to read Object...
java.lang.NullPointerException
at java.awt.Container.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.access$300(Unknown Source)
at java.io.ObjectInputStream$GetFieldImpl.readFields(Unknown Source)
at java.io.ObjectInputStream.readFields(Unknown Source)
at java.awt.Container.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.access$300(Unknown Source)
at java.io.ObjectInputStream$GetFieldImpl.readFields(Unknown Source)
at java.io.ObjectInputStream.readFields(Unknown Source)
at java.awt.Container.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.access$300(Unknown Source)
at java.io.ObjectInputStream$GetFieldImpl.readFields(Unknown Source)
at java.io.ObjectInputStream.readFields(Unknown Source)
at java.awt.Container.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.access$300(Unknown Source)
at java.io.ObjectInputStream$GetFieldImpl.readFields(Unknown Source)
at java.io.ObjectInputStream.readFields(Unknown Source)
at java.awt.Container.readObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at TableDataServlet.doPost(TableDataServlet.java:32)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.ja va:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Pr otocol.java:731)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.jav a:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)
-
You know, I wonder if I've discovered a bug. Maybe with all the changes to JDK1.5 and Tomcat 5.5, someone has inadvertantly done something to screw up the ability to move objects from applets to servlets?
Just a thought...
Alan
-
I would have tried to run this locally first; making an
output and reading the table in again, but I suspect
the serialization to be ok. If it is, then it is the transfer
that bugs out. If the serialization is ok then I would
have tried sending a simple string using your setup,
just to see if it arrived.
That tomcat really knows how to make stackTraces
eschew obfuscation
-
Just a thought, the
javax.swing.table.AbstractTableModel (basically the
same thing you are working with) already implements
serialization. Maybe if you stuffed your matrix into
one of those and tried it...
eschew obfuscation
-
Originally posted by ashiers
You know, I wonder if I've discovered a bug. Maybe with all the changes to JDK1.5 and Tomcat 5.5, someone has inadvertantly done something to screw up the ability to move objects from applets to servlets?
Just a thought...
Alan
I thought only Microsoft had a habit of killing bugs
w. one hand and planting new ones w. the other, and
then offering service (haha) packs to to move
the bugs around...
eschew obfuscation
-
OK, I have some good news. For the **** of it, I decided to create a new applet and servlet whereby I am simply passing a plain String object. Code below. So I know the system is working well enough to do this. Now, the question is, "Why won't it accept my TableData object?" That is still unresolved.
Alan
APPLET:
Code:
package forms;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.applet.*;
import java.io.*;
import java.net.*;
public class StringForm extends JApplet implements ActionListener
{
boolean isStandalone = false;
BorderLayout borderLayout1 = new BorderLayout();
String processingServlet = "";
JButton submit = new JButton("Submit");
final static String data = new String("Alan Shiers");
//Get a parameter value
public String getParameter(String key, String def) {
return isStandalone ? System.getProperty(key, def) :
(getParameter(key) != null ? getParameter(key) : def);
}
//Construct the applet
public StringForm() {
}
//Initialize the applet
public void init()
{
try {
processingServlet = this.getParameter("action","");
}
catch (Exception e) {
e.printStackTrace();
}
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
}
}
//Component initialization
private void jbInit() throws Exception
{
this.setSize(new Dimension(100,100));
Container container = getContentPane();
container.setLayout(new FlowLayout());
submit.addActionListener(this);
container.add(submit);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == submit)
{
try
{
// connect to the servlet
String location = processingServlet;
URL testServlet = new URL( location );
URLConnection servletConnection = testServlet.openConnection();
if (servletConnection instanceof HttpURLConnection)
{
((HttpURLConnection)servletConnection).setRequestMethod("POST");
}
else
{
System.out.println("this connection is NOT an HttpUrlConnection connection");
return;
}
//inform the connection that we will send output and accept input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);
//Don't use a cached version of URL connection.
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches (false);
//Specify the content type that we will send binary data
servletConnection.setRequestProperty ("Content-Type", "application/octet-stream");
//send your data to the servlet
System.out.println("Sending data to servlet..." + "\n");
ObjectOutputStream outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream());
outputToServlet.writeObject(data);
outputToServlet.flush();
System.out.println("Data has been sent." + "\n");
//now wait for a response from the servlet
BufferedReader in = new BufferedReader(new InputStreamReader(servletConnection.getInputStream()));
System.out.println("Waiting for response..." + "\n");
String line = "";
while((line = in.readLine()) != null)
{
System.out.print(line + "\n");
}
System.out.println("Communication ended.");
//Lastly, close the streams
outputToServlet.close();
in.close();
//Once we have confirmation, we can simply request
//the next page in a Step by Step process using:
//this.getAppletContext().showDocument(URL u, "_self");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
SERVLET:
Code:
import java.awt.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class StringObjectServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
doPost(request,response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
ObjectInputStream inputFromApplet = null;
PrintWriter out = null;
String data = null;
try
{
// get an input stream from the applet
inputFromApplet = new ObjectInputStream(new BufferedInputStream(request.getInputStream()));
System.out.println("Attempting to read Object...");
// read the serialized data from applet
Object o = inputFromApplet.readObject();
if(o != null && (o instanceof String))
{
data = (String) o;
System.out.println("Got Object");
inputFromApplet.close();
// send back a confirmation message to the applet
out = new PrintWriter(response.getOutputStream());
response.setContentType("text/plain");
out.println("confirmed " + data);
out.flush();
out.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
-
Hmm, then how about bundling the whole table into a byte stream and 'unpack' it on receival ? I'll
have to get back on that tomorrow cause my little gang is here and they are in the firday mood
eschew obfuscation
-
Yeah! Woopie! I'm dancing in the streets! Come on everybody, Let's boogie down! Do people still say that?
I found the answer! Here's a lesson for you all to learn so listen up closely. You'll want to keep this in mind when dealing with others trying to perform object serialization from an applet to a servlet.
The reason I kept getting EOFException and NullPointerException messages is because in both the applet and servlet I defined the class TableData as an inner class in each. When I compiled both the applet and servlet, each had its own serialized rendition of the TableData class. After compiling, they must have been incompatible. But I fixed that by making TableData.java in its own file.
Now everything works perfectly!
Thanks for all your help,
Alan
-
Damm !!
I've heard about security issues w. applets and inner
classes (that I never use) but this was a new one.
And I like to learn new stuff
eschew obfuscation
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|