Java Exception java.io.OptionalDataException - java

I getting the following exception when deserializing an Object:
java.io.OptionalDataException
java.io.ObjectInputStream.readObject0(Unknown Source)
java.io.ObjectInputStream.readObject(Unknown Source)
java.util.HashSet.readObject(Unknown Source)
sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
The code I use to serialize and deserialize the object is as follows:
public class ObjectToFile
{
public static void save(Object obj, String name)
{
FileOutputStream fos;
try
{
ODebug.Write(Level.INFO, "SER-0049: Saving objects from file...");
fos = new FileOutputStream(".//data//" + name);
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos));
oos.writeObject(obj);
oos.close();
fos.close();
}
catch (Exception e)
{
ODebug.Write(Level.SEVERE, "SER-0000: Caught exception in save()", e);
}
}
public static Object read(String name)
{
FileInputStream fis;
Object obj;
try
{
ODebug.Write(Level.INFO, "SER-0049: Reading objects from file...");
fis = new FileInputStream(".//data//" + name);
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis));
obj = ois.readObject();
ois.close();
fis.close();
return obj;
}
catch (Exception e)
{
ODebug.Write(Level.SEVERE, "SER-0001: Caught exception in read()", e);
}
return null;
}
}
The object I am trying to serialize/deserialize is a hashmap that looks like this:
public static HashMap<Integer, Document> ProductList = new HashMap<>();
The Document class has the following definition plus a few methods.
public class Document implements Serializable
{
private static final long serialVersionUID = 1L;
public Integer documentID;
public DocumentZone titleZone = new DocumentZone();
public DocumentZone bodyZone = new DocumentZone();
}
Please help!

Related

Java Socket ClassCast Exception

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).

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 ; )

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() {
...
}
}

ObjectInputStream[Java]

i'm new to file i/o so i'm sorry if this is a pretty bad question.
Currently I have an add method/main method and a person class my outputstream is working fine in the add method: This is at the top of the method
FileOutputStream myFile = null;
try {
myFile = new FileOutputStream("txt123.txt");
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(myFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
And I then have this twice because there are two types of people that can be added
oos.writeObject(person);
oos.close();
System.out.println("Done");
So my question, how do i get the input working and finally where do i put it, in the add method or the main method, I read how to do what i done here: http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/
He also has a guide on reading in the objects but I cant seem to get it working
Thanks!
You would be reading the file you just created like this:
ObjectInputStream in =
new ObjectInputStream(new FileInputStream("txt123.txt"));
// terrible file name, because this is binary data, not text
try{
Person person = (Person) in.readObject();
finally{
in.close();
}
You can combine the ObjectOutputStream with the FileOutputStream as follows. I'm also guessing you need to place the read/write code in one place to allow re-use. Here's a simple example with the read/write in a DAO.
public static class Person implements Serializable {
private String name;
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
public static class PersonDao {
public void write(Person person, File file) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
oos.writeObject(person);
oos.close();
}
public Person read(File file) throws IOException,
ClassNotFoundException {
ObjectInputStream oos = new ObjectInputStream(new FileInputStream(
file));
Person returnValue = (Person) oos.readObject();
oos.close();
return returnValue;
}
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
PersonDao personDao = new PersonDao();
Person alice = new Person("alice");
personDao.write(alice, new File("alice.bin"));
Person bob = new Person("bob");
personDao.write(bob, new File("bob.bin"));
System.out.println(personDao.read(new File("alice.bin")));
System.out.println(personDao.read(new File("bob.bin")));
}

Save/Load HashMap with .bin

public Map<String, BarrackData> barrack = new HashMap<String, BarrackData>();
SavingData.save(barrack, "barrack.bin"); // save
barrack = (Map<String, BarrackData>)SavingData.load("barrack.bin"); // load
// BarrackData contains 3 int's and 1 String.
public static void save(Object obj, String path) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
oos.writeObject(obj);
oos.flush();
oos.close();
}
public static Object load(String path) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
Object result = ois.readObject();
ois.close();
return result;
}
How can I Save/Load HashMap's.
I use this methode, but it seem's to have problems.
The barrack.bin contains some error's that I can't figure out.
(java.io.NotSerializableException java.io.ObjectStreamException IOException suppressedExceptionst)
Your class BarrackData does not appear to implement java.io.Serializable. It should look like this:
public class BarrackData implements Serializable {
...

Categories

Resources