Java Socket ClassCast Exception - java

I've been developing a software to send files through TCP/IP connection using Java Sockets. The program compiles, however, the 'Server Application' throws a Class Cast Exception and the files aren't sent to the server. Anyone who could help me, I would be very thankful. Above is the following code:
Server class:
package filesender;
import java.io.*;
import java.net.*;
public class ServidorTCP {
public static void main(String[] args)
throws IOException, UnknownHostException {
try (ServerSocket socketServer = new ServerSocket(6789)) {
Socket socket = socketServer.accept();
System.out.println("Conexão realizada com o cliente na porta 6789");
byte[] objectAsByte = new byte[socket.getReceiveBufferSize()];
BufferedInputStream bf =
new BufferedInputStream(socket.getInputStream());
bf.read(objectAsByte);
Arquivo arquivo = (Arquivo) getObjectFromByte(objectAsByte);
String dir = arquivo.getDiretorio() + "\\" + arquivo.getNome();
System.out.println("Criando o arquivo: " + dir);
try (FileOutputStream fos = new FileOutputStream(dir)) {
fos.write(arquivo.getConteudo());
}
}
}
private static Object getObjectFromByte(byte[] objectAsByte) {
Object obj = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bis = new ByteArrayInputStream(objectAsByte);
ois = new ObjectInputStream(bis);
obj = ois.read();
bis.close();
ois.close();
} catch (IOException e) {
}
return obj;
}
}
Client class
package filesender;
import java.io.*;
import java.net.*;
public class ClienteTCP {
public static Arquivo arquivo;
private static final long serialVersionUID = 1L;
public static void main(String[] args)
throws IOException, UnknownHostException {
selectFile();
try (Socket clientSocket = new Socket("127.0.0.1", 6789)) {
try (BufferedOutputStream bf =
new BufferedOutputStream(clientSocket.getOutputStream())) {
byte[] bytea = serializeFile();
bf.write(bytea);
bf.flush();
}
}
}
private static void selectFile() {
try {
File file = new File("C:\\Users\\DeveloperEng\\Documents\\"
+ "teste\\arquivo.txt");
byte[] bFile = new byte[(int) file.length()];
try (FileInputStream fis = new FileInputStream(file)) {
fis.read(bFile);
}
arquivo = new Arquivo();
arquivo.setConteudo(bFile);
arquivo.setNome("teste.txt");
arquivo.setDiretorio("C:\\Users\\DeveloperEng\\Documents");
} catch (IOException e) {
}
}
private static byte[] serializeFile() {
ByteArrayOutputStream bao = null;
ObjectOutputStream ous = null;
try {
bao = new ByteArrayOutputStream();
ous = new ObjectOutputStream(bao);
ous.writeObject(arquivo);
//return bao.toByteArray();
} catch (IOException e) {
}
return bao.toByteArray();
}
}
File class
package filesender;
import java.io.*;
public class Arquivo implements Serializable {
private String nome;
private byte[] conteudo;
private String diretorio;
private static final long serialVersionUID = 1L;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public byte[] getConteudo() {
return conteudo;
}
public void setConteudo(byte[] conteudo) {
this.conteudo = conteudo;
}
public String getDiretorio() {
return diretorio;
}
public void setDiretorio(String diretorio) {
this.diretorio = diretorio;
}
}
Exception thrown by the IDE:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to filesender.Arquivo
at filesender.ServidorTCP.main(ServidorTCP.java:20)
C:\Users\DeveloperEng\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
FALHA NA CONSTRUÇÃO (tempo total: 5 segundos)

Please, see the row 20 of the ServidorTCP class.
You can't cast the value that is returned by "getObjectFromByte" method to an "Archivio", because it is not of a compatible type. In particular, it is an Integer.
It happens because the read method of the ObjectInputStream returns an int (See Javadoc).

Related

Appending to a Serialization file (Java)

I'm trying to append objects to a serialized file but when I read it, it only contains the most recent object instead of all of the objects:
import java.io.*;
public class Main implements Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
TestClass test = new TestClass();
test.username = "this one is second";
test.age = 23;
test.phone = "+1 (010) 000 0000";
test.address = "2 Main St.";
TestClass test2 = new TestClass();
test2.username = "this one is second 22222";
test2.age = 23;
test2.phone = "+1 (010) 000 0000";
test2.address = "2 Main St.";
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser"));
out.writeObject(test);
out.writeObject(test2);
out.close();
ObjectOutputStream out2 = new ObjectOutputStream(new FileOutputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser", true)) {
#Override
protected void writeStreamHeader() throws IOException {
reset();
}
};
out2.writeObject(test);
out2.writeObject(test2);
out2.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\Java Projects\\ObjectOutputStreamTests\\files\\test.ser"));
try {
while ((in.readObject()) != null) {
TestClass testRead = (TestClass) in.readObject();
System.out.println(testRead.username);
System.out.println(testRead.age);
System.out.println(testRead.address);
System.out.println(testRead.phone);
}
} catch (EOFException e) {
System.out.println("end");
}
}
}
TestClass:
import java.io.Serializable;
public class TestClass implements Serializable {
public String username;
public int age;
public String phone;
public String address;
}
When I run this code, I get the second object (test2) printed twice, instead of the first and second object consecutively. This issue persists with more or less objects. How do I fix this?
You are reading the same Object twice for each iteration
while ((in.readObject()) != null) { // once
TestClass testRead = (TestClass) in.readObject(); // twice
You can change your code to
Object obj;
while ((obj = in.readObject()) != null) {
TestClass testRead = (TestClass) obj;
System.out.println(testRead.username);
System.out.println(testRead.age);
System.out.println(testRead.address);
System.out.println(testRead.phone);
}
Note
To get it to work I changed to
FileOutputStream f = new FileOutputStream("C:\\temp\\test.ser", true);
ObjectOutputStream out2 = new ObjectOutputStream(f)
{
#Override
protected void writeStreamHeader() throws IOException {
System.out.println("I am called");
reset();
}
}
;
out2.writeObject(test);
out2.writeObject(test2);
out2.close();

Java read a file into an arraylist of objects and return that arraylist

I need to write a class that has two static methods: writeFile and readFile. However, after I do my readFile(), it returns nothing.
class writereadFile {
public static void writeFile(ArrayList<Object> list, File file){
try {
try (FileOutputStream fos = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(list);
oos.close();
}
}catch(IOException e){e.getMessage();}
}
public static ArrayList<Object> readFile(ArrayList<Object>list, File file){
try {
try (FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis)) {
Object o = ois.readObject();
list = (ArrayList<Object>) o;
ois.close();
}
}catch(IOException | ClassNotFoundException e){e.getMessage();}
System.out.println(list);
return list;
}
}
EDIT:
This my class for testing. My object is an arraylist of custom objects if you need the custom object just comment.
class main {
public static void main(String[] args) {
Date date = new Date();
Book b1 = new Book("abc", "Phi", true, date, null);
Book b2 = new Book("cba", "Someone", true, date, null);
Books booklist = new Books();
booklist.add(b1);
booklist.add(b2);
File filetoDo = new File("book.txt");
//write arraylist into file
writereadFile.writeFile(booklist, filetoDo);
//clear the arraylist
booklist.clear();
//read book from file
writereadFile.readFile(booklist, filetoDo);
System.out.println(booklist);
}
}
Your test should read:
bookList = writereadFile.readFile(booklist, filetoDo);
and, by the way, you should really refactor your readFile method to simply:
public static ArrayList<Object> readFile(File file)
You can't modify the argument reference like that, since Java is always pass-by-value call semantics. (You could modify the list argument contents inside the function, but that's not what you are doing.)
If you are using Java 8 try using Streams:
public static readFile(String filePath) {
List<Object> list = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
stream.forEach(list::add);
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
I'm playing around this topic a bit on my own, so below you can find some code snippets that might help you.
Examples are very short and simple, so I hope you will not just use e.printStackTrace() in your code :)
public class ExternalIO {
private ExternalIO() {
}
public static ObjectOutputStream objectOutputStream(String basePath, String pathToFile) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(createFileIfDoesNotExist(absolutePath(basePath, pathToFile)));
return new ObjectOutputStream(fileOutputStream);
}
public static ObjectInputStream objectInputStream(String basePath, String pathToFile) throws IOException {
FileInputStream fileInputStream = new FileInputStream(absolutePath(basePath, pathToFile));
return new ObjectInputStream(fileInputStream);
}
private static File createFileIfDoesNotExist(String absolutePath) throws IOException {
File file = new File(absolutePath);
if (file.exists()) {
return file;
}
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
private static String absolutePath(String basePath, String pathToFile) {
return Paths.get(basePath, pathToFile).toAbsolutePath().toString();
}
}
output usage:
List<ItemType> input = null; //create your input list here
try (ObjectOutputStream objectOutputStream = ExternalIO.objectOutputStream(CONFIG, FILENAME)) {
objectOutputStream.writeObject(input);
} catch (Exception e) {
e.printStackTrace();
}
input usage:
try (ObjectInputStream objectInputStream = ExternalIO.objectInputStream(CONFIG, FILENAME)) {
return (List<ItemType>) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
hope that helps ; )

JAVA Send an object to all clients

I try to make a chat. When a client send a message to the server, it is working, the server receives the message. So I would like to send this message all the clients. I tried many things but they are not working... Just the client which sends the message, it receives this message
Can You help me please ?
Thanks in advance
PS : Sorry for my bad English
This is the result in the console :
http://i.stack.imgur.com/VS2wf.png
MainClient
public class MainClient {
/**
* #param args the command line arguments
* #throws java.io.IOException
* #throws java.lang.ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
boolean stop = false;
Socket socket;
Scanner nickScan;
String nick;
socket = new Socket(InetAddress.getLocalHost(), 2009);
System.out.println("Hi, what is your name ?");
nickScan = new Scanner(System.in);
nick = nickScan.nextLine();
User u = new User(nick, false, false, true);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(u);
EmissionThread e = new EmissionThread(u, socket);
e.start();
while(!stop){
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message m = (Message)ois.readObject();
System.out.println(m.getNick() + " : " + m.getMsg());
}
//socket.close();//On ferme les connexions
}
}
MainServer
public class MainServer extends Thread {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO code application logic here
ConnectionThread c = new ConnectionThread();
c.start();
}
}
ConnectionThread
public class ConnectionThread extends Thread {
private static final boolean stop = false;
Socket socketduserveur;
ServerSocket socketserver;
Session s = new Session("#upec");
public ConnectionThread() throws IOException {
this.socketserver = new ServerSocket(2009);
}
public ServerSocket getSocketserver() {
return socketserver;
}
#Override
public void run() {
while (!stop) {
try {
socketduserveur = socketserver.accept(); //On accepte les connexions
ObjectInputStream ois = new ObjectInputStream(socketduserveur.getInputStream());
User u = (User)ois.readObject();
System.out.println(u.getNick() + " c'est connecté");
s.addUserList(u);
if (s.listAlone()) {
System.out.println("Vous etes admin");
u.setAdmin(true);
}
ReceptionThread r = new ReceptionThread(socketduserveur);
r.start();
} catch (ClassNotFoundException ex) {
Logger.getLogger(MainServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ConnectionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
ReceptionThread
public class ReceptionThread extends Thread {
private static final boolean stop = false;
Socket socketduserveur;
ServerSocket socketserver;
public ReceptionThread(Socket socketduserveur) {
this.socketduserveur = socketduserveur;
}
#Override
public void run() {
while (!stop) {
try {
ObjectInputStream ois = new ObjectInputStream(socketduserveur.getInputStream());
Message m = (Message)ois.readObject();
System.out.println(m.getNick() + " : " + m.getMsg());
ObjectOutputStream oos = new ObjectOutputStream(socketduserveur.getOutputStream());
oos.writeObject(m);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(ReceptionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
EmissionThread
public class EmissionThread extends Thread {
private User u;
private Socket socketduserveur;
private static final boolean stop = false;
public EmissionThread(User u, Socket socketduserveur) {
this.u = u;
this.socketduserveur = socketduserveur;
}
#Override
public void run() {
while (!stop) {
try {
Scanner msgScan;
String msg;
msgScan = new Scanner(System.in);
msg = msgScan.nextLine();
Message m = new Message(u.getNick(), msg);
ObjectOutputStream oos = new ObjectOutputStream(socketduserveur.getOutputStream());
oos.writeObject(m);
} catch (IOException ex) {
Logger.getLogger(EmissionThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Message
public class Message implements Serializable {
private String nick;
private String msg;
public Message(String nick, String msg) {
this.nick = nick;
this.msg = msg;
}
}
Session
public class Session implements Serializable {
private String name;
private ArrayList<String> listSession = new ArrayList();
private ArrayList<User> listUser = new ArrayList();
public Session(String name) {
this.name = name;
}
public void addSession(String name){
listSession.add(name);
}
public void deleteSession(String name){
for(String s : listSession){
if(name.equals(s)){
listSession.remove(s);
}
}
}
public boolean existSession(String name){
for(String s : listSession){
if(name.equals(s)){
return true;
}
}
return false;
}
public void addUserList(User u){
listUser.add(u);
}
public boolean listAlone(){
int compteur = 0;
for(User u : listUser){
compteur++;
}
return compteur == 1;
}
}
User
public class User implements Serializable {
private String nick;
private final Session session;
private boolean admin, moderator, voice;
public User(String nick, boolean admin, boolean moderator, boolean voice) {
this.nick = nick;
this.admin = admin;
this.moderator = moderator;
this.voice = voice;
this.session = new Session("#upec");
}
}
You can use websockets on tomcat for this. If you download tomcat there is a chat app already built as an example

NotSerializableException even after implementing Serializable

Recieving the error:
java.io.NotSerializableException
even after implementing Serializable.
I'm simply trying to serialize a Survey object. Here is my code, does anyone have an idea why I am receiving this error?
public void loadData(Survey survey, Test test, Boolean isSurvey) throws FileNotFoundException {
...
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
Survey s = (Survey) ois.readObject();
ois.close();
System.out.println("list size = " + s.questions);
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveData(Survey survey, Test test, Boolean isSurvey, String fileName) {
...
if (isSurvey) {
try {
FileOutputStream fileOut = new FileOutputStream("surveys/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(survey);
out.close();
fileOut.close();
} catch (IOException ex) {
}
} else {
try {
FileOutputStream fileOut = new FileOutputStream("tests/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(test);
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
}
EDIT: Added survey class. My Question class, Main class, and Input class both implement Serializable
package Survey;
import java.io.Serializable;
import java.util.ArrayList;
import IO.Input;
import Question.Question;
public class Survey implements Serializable{
private static final long serialVersionUID = 1L;
protected Main main = new Main();
protected Input input = new Input();
protected String name;
public ArrayList<Question> questions = new ArrayList<Question>();
public void setName() {
...
}
public void displayName() {
...
}
public void displayQuestions() {
...
}
public void mainMenu() {
...
}
public void addQuestionMenu() {
...
}
}

How to handle StreamCorruptedException when using ObjectInputStream? [duplicate]

This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 5 years ago.
`I am new to java and getting StreamCorruptedException in the code below... In this code I am trying to read multiple objects from a file using ObjectInputStream... m not able to handle the StreamCorruptedException...the o/p I m getting is
File C098.txt already exists
Product ID:- P001
Description:- Book
Price:- Rs.200
Exception in thread "main" java.io.StreamCorruptedException: invalid type code:
AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Utility.getProducts(Utility.java:57)
at Utility.main(Utility.java:23)
CODE:
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
}
class Utility{
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C098.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
objProduct = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C098.txt",objProduct);
getProducts(cartId);
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}`
The problem is because of header issue, You are appending to same file and while returning second object it throws exception because of headers issue. try to write object in different files, you can rid out of the problem.
SCE Thrown when control information that was read from an object stream violates internal consistency checks.
try
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C0982.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
Product objProduct1 = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C0981.txt",objProduct1);
getProducts("C0981.txt");
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
</pre>
You can't 'handle' it. You have to prevent it. It results from a design error such as using two ObjectOutputStreams on a stream that is read by a single ObjectInputStream, as you are doing here by appending to the file, or writing data other than objects and not reading it symmetrically.

Categories

Resources