Follow on from an earlier question here. Trying to send this object Employee via HTTP. I'm not getting any errors but am hoping for a printout of the employee details at the other end but something isn't happening. I'm opening my log files to see the printout on my tomcat server but other than the indication that the method has started showing the START printout I'm not getting the END one. So something isn't working right in that section.
Here is the test class Employee:
public class Employee implements java.io.Serializable {
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck() {
System.out.println("Mailing a check to " + name + " " + address);
}
}
Client Side:
public class SerializeAndSend {
public static void main(String args[]){
one.Employee e = new one.Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
sendObject(e);
}
public static Object sendObject(Object obj) {
URLConnection conn = null;
Object reply = null;
try {
// open URL connection
URL url = new URL("///myURL///");
conn = url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
// send object
ObjectOutputStream objOut = new ObjectOutputStream(conn.getOutputStream());
objOut.writeObject(obj);
objOut.flush();
objOut.close();
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
// recieve reply
try {
ObjectInputStream objIn = new ObjectInputStream(conn.getInputStream());
reply = objIn.readObject();
objIn.close();
} catch (Exception ex) {
// it is ok if we get an exception here
// that means that there is no object being returned
System.out.println("No Object Returned");
if (!(ex instanceof EOFException))
ex.printStackTrace();
System.err.println("*");
}
return reply;
}
}
I think thats correct. But I'm stuck on the server end, I have the employee class on the server side too:
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
System.out.println("START");
Object obj;
Employee emp = null;
ObjectInputStream objIn = new ObjectInputStream(req.getInputStream());
try {
obj = objIn.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
emp = (Employee)objIn.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("END");
System.out.println(emp.name);
}
Any ideas whats going wrong on the receiving end?
try {
obj = objIn.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
emp = (Employee)objIn.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
You are sending one object and trying to receive two. You either need this:
obj = objIn.readObject();
if (obj instanceof Employee)
{
Employee emp = (Employee)obj;
}
or this:
Employee emp = (Employee)objIn.readObject();
Not a mixture of both. Two readObject() calls implies reading the stream for two distinct objects, and you aren't sending them.
Secondly, you shouldn't catch Exception and then use instanceof on the exception object. In this case you should have a separate catch (EOFException exc), which is OK if you expect to receive zero objects, but not otherwise, and then catch the other possible exceptions separately: they are not OK.
Related
something is really messed up. I've got a ".ser" document in the assets folder, which stores an ArrayList of Objetcs. In an android application, I want to read this objects. There are a lot of posts related to this issue, however none of them could solve my problem. The strange part is, when I am using similar code in non - android context / "normal" java, it works properly. Here, the last line throws a NullPointerException - What is going wrong?
public void getData() {
ArrayList<MyClass> output= null;
InputStream is = null;
ObjectInputStream ois = null;
try{
is = this.getAssets().open("data.ser");
ois = new ObjectInputStream(is);
output = (ArrayList<MyClass>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("TAG", output.get(0).getId());
}
I would create a class and place the array within a single object:
public class ListObjects implements Serializable {
List<MyClass> listMyClass = new ArrayList<>();
public ListObjects(){
}
public List<MyClass> getListMyClass() {
return listMyClass;
}
public void setListMyClass(List<MyClass> listMyClass) {
this.listMyClass = listMyClass;
}
}
I had a similar problem. And it was because the name of the package in the java app was not called the same as the package name in android. And therefore I did not recognize them as equal objects. This is how I do it:
public static Object fromData(byte[] data) {
ObjectInputStream ois = null;
Object object = null;
try {
ois = new ObjectInputStream(
new ByteArrayInputStream(data));
object = ois.readObject();
} catch (Exception ex) {
Logger.getLogger(ModeloApp.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
ois.close();
} catch (Exception ex) {
Logger.getLogger(ModeloApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
return object;
}
I have one client file clientRPC.java and server file serverRPC.java. Both communicate using TCP protocol and use objectinput and output stream to transfer data.
my client file:
public class clientRPC {
public static void main(String args[]) {
Socket s = null;
try {
int serverPort = 8888;
s = new Socket("localhost", serverPort);// server name is local host
//initializing input and output streams object and referencing them to get input and output
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(s.getOutputStream());
in = new ObjectInputStream(s.getInputStream());
MathsTutor mt = new MathsTutor();
out.writeObject(mt);
out.flush();
System.out.println("Welcome to Maths Tutor Service. The available maths exercises are:\n"
+ "Addition: Enter 'A' or 'a'\n"
+ "Subtraction: Enter 'S' or 's'\n"
+ "Multiplication: Enter 'M' or 'm'\n"
+ "Division: Enter 'D' or 'd'\n"
+ "Enter 'Q' or 'q' to quit");
//System.out.println();
MathsTutor mt1 = (MathsTutor) in.readObject();
String response = in.readUTF();
System.out.println(response);
} catch (UnknownHostException e) {
System.out.println("Socket:" + e.getMessage());
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
System.out.println("close:" + e.getMessage());
}
}
}
}
}
and my server file :
public class serverRPC extends Thread {
String request;
String response;
public static void main(String args[]) {
try {
int serverPort = 8888;
ServerSocket listen_socket = new ServerSocket(serverPort);
while (true) {
Socket clientSocket = listen_socket.accept();
Connection c = new Connection(clientSocket);
}
} catch (IOException e) {
System.out.println("Listen socket:" + e.getMessage());
}
public serverRPC(String s) {
request = s;
}
}
class Connection extends Thread {
ObjectInputStream in;
ObjectOutputStream out;
Socket clientSocket;
public Connection(Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
this.start();
} catch (IOException e) {
System.out.println("Connection:" + e.getMessage());
}
}
public void run() {
try {
MathsTutor mt = (MathsTutor) in.readObject();
InetAddress ip = clientSocket.getInetAddress();
System.out.println("The Received Message from Client at address:/" + ip.getHostAddress());
System.out.println("====================================");
MathsTutor mt1 = new MathsTutor();
out.writeObject(mt1);
while(true) {
// Read from input
String command = in.readUTF();
System.out.println(command);
}
//System.out.println();
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {/*close failed*/
}
}
}
}
The problem is when I run server and then client on cmd, the client side displays the welcome msg and puts cursor on another line for user input but, I can't type anything, the cursor just blinks... I know this might be simple but it has taken already 3 hours for me and I'm stuck in the same thing.
The cursor marked with red keeps blinking but doesn't let me type anything.
You're writing an object with writeObject() and trying to read it with readUTF(). Illogical.
objects written with writeObject() must be read with readObject().
strings written with writeUTF() must be read with readUTF().
primitives written with writeXXX() must be read with readXXX(), for most values of X.
Today I started using serialized object in java, I'm new at it and I have some problems when I try to deserialize.
I have this file where I write all my Account objects, it writes fine I guess. The problem is I don't know how to refer to a specific object from that file, or how could I get all of them into a list? and then refer to it.
This is how i'm trying to read them:
public void readAccount(Account e) {
/* List<Account> results = new ArrayList<Account>();
try {
FileInputStream fileIn = new FileInputStream("test.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
for (int i = 0; i < accBank.size(); i++) {
results.add((Account) in.readObject());
}
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
for (Account acc : results) {
System.out.println(toString(acc));
if(e.getAcc_no() == acc.getAcc_no())
{System.out.println("Deserialized Account...");
System.out.println(toString(e));
}
}
*/
List<Account> results = new ArrayList<Account>();
Account acc = null;
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
while (true) {
ObjectInputStream ois = new ObjectInputStream(fis);
results.add((Account) ois.readObject());
acc = (Account) ois.readObject();
}
} catch (Exception ignored) {
// as expected
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
System.out.println("results = " + results);
for (Account ac : results) {
System.out.println(toString(ac));
if(e.getAcc_no() == ac.getAcc_no())
{System.out.println("Deserialized Account...");
System.out.println(toString(e));
}
}
}
And this is how I write them:
public void writeAccount(Account e) {
try {
ObjectOutputStream os1 = new ObjectOutputStream(
new FileOutputStream("test.txt", true));
os1.writeObject(e);
os1.close();
} catch (Exception exc) {
exc.printStackTrace();
}
}
Edit:
public void writeFile() {
for (int i = 0; i < accBank.size(); i++) {
writeAccount(retAcc(i));
}
}
Can any of you tell me what im doing wrong? I also tried other examples from other questions and didn't work.
What you're doing wrong is that you use several ObjectOutputStreams to write to the same file (which is not a txt file, BTW, since it contains binary data), and use a single ObjectInputStream to read all the accounts. As a consequence, a new serialization header is written each time you write an account, and the ObjectInputStream doesn't expect that.
The best way to write a list of accounts is to do just that: you store the accounts into a List<Account>, and write the list. To read the list of accounts, you do just that: you read a single object from the file, and cast it to List<Account>.
Trying to send an arrayList over a socket, get a null pointer exception at object input stream initialization (client).
Client:
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
Server:
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush(); // added later, not helping
}
I've been trying to comunicate over sockets for two days now with almost no success. I have no idea what's going on. Ofc I plan to document myself better when I'll have more time but for now I'd really like to understand what is happening.
EDIT
public class Client {
private static int port = 6666;
private static Socket socket = null;
public Client (int port) {
Client.port = port;
}
public Client () {
}
public void establishConnection() {
try {
Client.socket = new Socket(InetAddress.getByName(null), Client.port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Server:
public void start () {
(new Thread() {
public void run() {
try {
Server.socket = new ServerSocket(Server.portNumber);
while (!Server.stop) {
Socket client = Server.socket.accept();
(new HandleRequest (client)).start();
}
...............
public class HandleRequest extends Thread {
private Socket client = null;
private SQL sql_db = new SQL ();
public HandleRequest (Socket client) {
this.client = client;
}
#Override
public void run () {
try {
if (!this.sql_db.isConnected())
this.sql_db.connect();
if (this.client == null) {
System.out.println("Error: client does not exist, NO idea what's going on");
return;
}
ArrayList<Book> library = this.sql_db.getAllBooks();
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush();
} catch (Exception e) {
System.out.println("Server error in handling request for whole library!");
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because the NPE is on this line:
Client.socket.getInputStream());
there is only one thing that can cause it. It can't be Client, because that is static. It can't be getInputStream(), because that is a method, so it has to be socket that is causing the NPE.
On this line:
private static Socket socket = null;
you set socket to be null. The only place I see where you set it to be not null is in your .establishConnection() method, but I don't see where you call that method.
Therefore, your problem is most likely that you aren't calling the .establishConnection() method.
Is you establishConnection method called before
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
If not, your Client.socket is null and you need to initialize it. I.e. your code should look like this:
try {
Client c = new Client(1337);
c.establishConnection();
ObjectInputStream objIn = new ObjectInputStream(
c.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
I've been trying to debug this for 2 hours and i just can't explain it.
I have a server and a client. (server manages some Auctions).
What happens:
The client request something , server sends data back and client receives it just fine.
The client sends something to the server, and the server updates some data.
The client makes the same request as first time (1.), the server send back the updated
data, but the client does not receive the new update data, instead it receives the old data (as it got it in the first request (1.).
The data that is being sent is just a Java Bean with two List-s.
And the code:
// CLIENT CLASS
// creates socket, sends and listens on the socket
// listening is done on a separate thread
public class ServerConnector {
private Socket socket = null;
private ObjectOutputStream out = null;
private Display display;
private ServerListener listener;
public ServerConnector(Display display) {
this.display = display;
try {
socket = new Socket("localhost",33333);
out = new ObjectOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listener = new ServerListener(socket, display);
new Thread(listener).start();
}
public void sendRequest(Request request) {
try {
out.writeObject(request);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerListener implements Runnable {
private Socket socket;
private ObjectInputStream in = null;
private Display display;
public ServerListener(Socket socket,Display display) {
this.socket = socket;
this.display = display;
try {
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
Response response =null;
try {
while ((response = (Response)in.readObject()) != null) {
if (response.getCars().size() > 0) {
display.showAvailableCars(response.getCars());
}
if(response.getAucs().size() > 0) {
List<Auction> auctionz = response.getAucs();//HERE 1st time it gets the GOOD data, 2nd time should get UPDATED DATA but instead receives the OLD DATA (same as 1st time).
display.showOpenAuctions(auctionz);
}
response = null;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//CLIENT CLASS
// controls when something should be sent, and print out responses
public class Display {
Scanner console = new Scanner(System.in);
ServerConnector server = new ServerConnector(this);
List<Car> cars;
List<Auction> aucs;
public void show() {
int opt = 0;
System.out.println("1. Show available cars for auction.");
System.out.println("2. Show open auctions.");
opt = console.nextInt();
Request request = new Request();
if (opt == 1)
request.setRequest(Request.GET_CARS);
if (opt == 2) {
request.setRequest(Request.GET_OPEN_AUCTIONS);
}
server.sendRequest(request);
}
public void showAvailableCars(List<Car> cars) {
int i = 0;
for (Car c : cars ){
i++;
System.out.println(i +". " + c.getMaker() + " " + c.getModel() + " price: " + c.getPrice());
}
System.out.println("Select car to open Auction for:");
int selectedCar = console.nextInt();
if (selectedCar != 0) {
if (selectedCar <= cars.size()) {
Request request= new Request();
request.setRequest(Request.OPEN_AUCTION);
Car c = cars.get(selectedCar-1);
request.setCar(c);
server.sendRequest(request);
}
}
show();
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public void showOpenAuctions(List<Auction> aucs2) {
int i = 0;
for (Auction auc : aucs2) {
i++;
System.out.println(i+ ". " + auc.getCar().getModel() + " " + auc.getCar().getMaker() + " last price: " + auc.getPrice());
}
System.out.println("You can now make offers");
System.out.println("Input auction number:");
int selectedAuction = 0;
selectedAuction = console.nextInt();
if (selectedAuction > 0 && selectedAuction <= aucs2.size()) {
System.out.println("Offer new price:");
int price = console.nextInt();
Request request= new Request();
request.setRequest(Request.MAKE_OFFER);
request.setAuctionId(aucs2.get(selectedAuction-1).getId());
request.setPrice(price);
server.sendRequest(request);
}
show();
}
public void setOpenAuctions(List<Auction> aucs2) {
this.aucs = aucs2;
}
}
// SERVER CLASS : send and receives
public class ClientManager implements Runnable {
private AuctionManager manager = new AuctionManagerImpl();
private Socket client;
private ObjectInputStream in = null;
private ObjectOutputStream out = null;
public ClientManager(Socket socket) {
this.client = socket;
try {
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
} catch(Exception e1) {
try {
e1.printStackTrace();
client.close();
}catch(Exception e) {
System.out.println(e.getMessage());
}
return;
}
}
#Override
public void run() {
Request req = null;
try {
while ((req = (Request)in.readObject()) != null) {
if (req.getRequest() != null) {
if (req.getRequest().equals(Request.GET_CARS)) {
Response response = new Response();
response.setCars(manager.getAvailableCars());
out.writeObject(response);
continue;
}
if (req.getRequest().equals(Request.OPEN_AUCTION)) {
manager.openAuction(req.getCar());
continue;
}
if (req.getRequest().equals(Request.GET_OPEN_AUCTIONS)) {
Response response = new Response();
response.setAucs(manager.getHoldedAuctions()); //this line ALWAYS sends to the client GOOD, UPDATED DATA
out.writeObject(response);
out.flush();
continue;
}
if (req.getRequest().equals(Request.MAKE_OFFER)) {
Auction auction = manager.getOpenAuction(req.getAuctionId());
manager.updateAuction(auction, req.getPrice(),client.getRemoteSocketAddress().toString());
continue;
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It could be because you are using ObjectOutputStreams. Remember that ObjectOutputStreams will cache all objects written to them so that if the same object is written again in the future it can write a back-reference instead of re-writing the whole object. This is necessary when writing an Object graph.
Your code fragment:
if (req.getRequest().equals(Request.GET_CARS)) {
Response response = new Response();
response.setCars(manager.getAvailableCars());
out.writeObject(response);
continue;
}
is writing the object returned by manager.getAvailableCars(). The next time a request is received the same object (but now with different contents) is written - but the ObjectOutputStream doesn't know about the new contents so it just writes a back-reference. The ObjectInputStream at the other end sees the back-reference and returns the same object it read last time, i.e. the original data.
You can fix this by calling ObjectOutputStream.reset() after each response. This will clear the stream's cache.
See ObjectOutputStream.writeUnshared() and .reset().
Ok. I just found out the solution.
from here http://java.sun.com/developer/technicalArticles/ALT/sockets/ :
Object Serialization Pitfall
When working with object serialization it is important to keep in mind that the ObjectOutputStream maintains a hashtable mapping the objects written into the stream to a handle. When an object is written to the stream for the first time, its contents will be copied to the stream. Subsequent writes, however, result in a handle to the object being written to the stream. This may lead to a couple of problems:
If an object is written to the stream then modified and written a second time, the modifications will not be noticed when the stream is deserialized. Again, the reason is that subsequent writes results in the handle being written but the modified object is not copied into the stream. To solve this problem, call the ObjectOutputStream.reset method that discards the memory of having sent an object so subsequent writes copy the object into the stream.
An OutOfMemoryError may be thrown after writing a large number of objects into the ObjectOutputStream. The reason for this is that the hashtable maintains references to objects that might otherwise be unreachable by an application. This problem can be solved simply by calling the ObjectOutputStream.reset method to reset the object/handle table to its initial state. After this call, all previously written objects will be eligible for garbage collection.
The reset method resets the stream state to be the same as if it had just been constructed. This method may not be called while objects are being serialized. Inappropriate invocations of this method result in an IOException.