Java: Serialization doesn't work for the second time - java

I have a server on which I keep track of some data. When I connect to the server with the administrator application to check out the current state of the data. I use a refresh rate of 5 seconds. The first time the server sends the data, it works. But the second time, when the data changed, the admin-side does not receive the up-to-date data. I'm sending the data, wrapped in a class, through an ObjectOutputStream and ObjectInputStream:
This is the wrapper class for the data:
public class Leerling implements Serializable {
public int llnID;
public String naam;
public String voornaam;
public String klas;
public int klasNummer;
public Date geboorteDatum;
public String getFullName()
{
return voornaam + " " + naam;
}
#Override
public String toString() {
return "Leerling{" + "llnID=" + llnID + ", naam=" + naam + ", voornaam=" + voornaam + ", klas=" + klas + ", klasNummer=" + klasNummer + ", geboorteDatum=" + geboorteDatum + '}';
}
}
public class SLeerling extends Leerling implements Serializable{
public boolean voted;
public int vote = -2;
}
What I tried is before reading the Object from the stream to call System.gc(); to make sure the object old object is not longer in memory. But without success.
Does someone know what the exact problem is? And how to make it possible to get the real up-to-date data?
Thanks in advance.
A second example of the problem:
I have again a wrapper class for some other data (It is an inner class):
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public List<Integer> votes;
}
When I send the data the first time, it works. But the second time I send it (to update it), everything EXCEPT the List<Integer> votes is updated. So votes isn't refreshed.
Then I solved it a bit tricky by replacing the List by an array:
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public Integer[] votes;
}
And this works perfect. Strange if you ask me. The the other part of the code I changed almost nothing... (except to implement the array instead of the List)

It's probably the ObjectOutputStream causing the trouble.
If you use a single ObjectOutputStream object on the server then you need to make sure you call reset on it, otherwise it will write shared references to previously-written objects. This sounds like what you are seeing.
To illustrate the problem:
class BrokenServer {
void sendBrokenVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.writeObject(votes); // Writes a shared reference to "votes" WITHOUT updating any data.
}
}
class FixedServer {
void sendFixedVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.reset(); // Clears all shared references.
out.writeObject(votes); // Writes a new copy of "votes" with the new data.
}
}

Related

I am trying to implement OOP concepts with java

When i try to compile an aggregation program , i receive an error saying "class,interface,enum expected". Here is my code. please help me solve this issue.
class employee
{
private String name;
private String address;
private float salary;
public employee(String na, String add,float sal)
{
name = na;
address = add;
salary = sal;
}
public void showEmpDetails()
{
System.out.println("Name " + name);
System.out.println("Address " + address);
System.out.println("Salary " + salary );
System.out.println();
}
}
import java.util.vector;
class company
{
private String comname;
private vector vt;
public company(String na)
{
comname = na;
vt = new vector();
}
public void addEmployee(employee e)
{
vt.addElement(e);
}
public void showComDetails()
{
System.out.println("Company Name " + comname);
int x = vt.size();
int y = 0;
while(y<x)
{
object e = vt.elementAt(y);
e.showEmpDetails();
y++;
}
}
}
public class demo
{
public static void main(String[] args)
{
employee e1 = new employee("Ashan","Kandy",2000.0f);
employee e2 = new employee("Steve","California",2500.0f);
employee e3 = new employee("Elon","South Africa",2500.0f);
company c1 = new company("Apple");
c1.addEmployee(e1);
c1.addEmployee(e2);
c1.addEmployee(e3);
c1.showComDetails();
}
}
Note:- i receive only one error. and also can anybody tell me why can't i have more than one public class in java.
Well, your code has more than one error actually. The reason for your specific error is that import should be at beginning of the file, not in the middle.
And my understanding of why only one public class is allowed for each file is:
It makes things clearer.
By reading the class name and document to this class, you could quickly know what the whole file is used for. If we allow multiple public classes in one file, like C++, then we have to jump inside of the file to understand it.
Notice Java is a strong object-oriented language, i.e. everything in Java is Object. So when importing, you are importing a file. It would be more complicated if one file contains multiple public classes.
It simplify testing.
Each public class could have a main function. And you could run any main function of a file Demo.java simply by java Demo. This is really nice, so that you could write test code, or example of usage in main function to show other contributor how this class should be used.
There have to be other more in-depth reason for single public class in Java. But these are my perspective.

Calling class methods from another class

I have created a class for a book with various field. I have then created a an array class for the library to store the book details. However I am not sure how to link them. I am looking to ultimately be able to search my array for all books with the same author surname for example. Should I somehow be calling methods from the book code to the library code?
This is my object class
public class Bookrecord
{
private int idnumber;
private String author;
private String title;
private String fiction;
public Bookrecord( int newidnumber, String newauthorname, String newtitlename, String newfictionname)
{
idnumber = newidnumber;
author = newauthorname;
title = newtitlename;
fiction = newfictionname;
}
public int getidnumber()
{
return idnumber;
}
public String getauthorname()
{
return author;
}
public String getfictianname()
{
return fiction;
}
public String gettitlename()
{
return title;
}
public void setidnumber(int insertidnumber)
{
idnumber = insertidnumber;
}
public void setauthor(String insertauthorname)
{
author = insertauthorname;
}
public void setfictian(String insertfictionname)
{
fiction = insertfictionname;
}
public void settitle(String inserttitlename)
{
title = inserttitlename;
}
public void printBookrecord()
{
System.out.println("The idNumber is " + idnumber + " The authorname is " + author + " The fictionname is " + fiction + " The titlename is " + title);
}
}
This is my array class
import java.util.ArrayList;
public class Libraryclass
{
// instance variables - replace the example below with your own
private ArrayList<String> member;
private ArrayList<String> bookrecord;
private ArrayList<String> libraryloan;
/**
* Constructor for objects of class Loan
*/
public Libraryclass()
{
// initialise instance variables
member = new ArrayList<String>();
bookrecord = new ArrayList<String>();
libraryloan = new ArrayList<String>();
}
public void addMember(String newMember)
{
member.add(newMember);
}
public void bookrecord(String newrecord)
{
bookrecord.add(newrecord);
}
public void libraryloan(String newloan)
{
libraryloan.add(newloan);
}
}
This reminds of an assignment for my first object oriented course. I get the feeling you also just started development and need some tips to get started.
Keep in mind we won't spoonfeed the answer to you since it is frowned upon to use stackoverflow to get complete answers to college assignments.
Your library or (arrayclass) should store an Array of BookRecord objects. Currently your arraylists hold String Objects. You should re-read what objects and classes are, to better understand the underlying concepts. You want your Library to hold an arraylist of bookrecords.
FYI: An Arraylists is a class available in java that allows the addition and removal of elements. It has some advantage related to arrays but also has some cons.
Your library object will use 'for loops' or 'iterators' to go through your arraylist of records. In order to implement features such as search for book you need to learn how to iterate over elements in an arraylist to search for strings. Google is your friend here. Here is an example what someone in your position should search for:
-searching through an arraylist, java
-iterating over arraylist, java
-how to use indexof java stack overflow
Finally, it makes more sense to call methods of the BookRecords from the Libraryclass. A bookRecord has one and only one Library. A library has many books. Hence, the library will hold references (contain) the books and will call getters and setters on the books.

Viewing variables within a java object in the logs

I have a really simple wrapper class thats displayed below:
public class EmbedFoods {
private Collection<Food> foods;
public Collection<Food> getFoods() {
return foods;
}
public void setFoods(Collection<Foods> foods) {
this.foods = foods;
}
}
public class Food {
private String nutrition;
private String calories;
private String peanuts;
etc...
}
I get a list of "Food" for this EmbedFoods class by calling my API which returns a JSON string and I use Robospice for Spring Android to populate EmbedFoods automatically.
Now, I would like to view the object EmbedFoods in a human-readable format, preferably JSON.
If I go Log.e("embedFoods", EmbedFoods.toString());, it returns:
E/embedFoods [LModel.Food;#25ef9bbb
I can only see the model that is inside the embedFood class, but I cannot see variables that it comprises of. I was hoping to see a JSON string that shows all the variable of the java object printed in the logs.
How can I view all the variables that were set within the embedFood class other than debugging the line in which the embedFood is set in the app?
Well a way to do this can be done by overriding the toString method to display the correct values you want to see.
Something like
#Override
public String toString() {
Foods[] foods = collection.toArray();
String words = "[";
for (int i = 0; i < foods.length; i++) {
words = words + "{" + foods.nutrition + foods.etc + "}"
}
words = words + "]"
return words;
}
In your Embed foods.

Java Static constructor not working

Here is my code
class Bomb {
static String description = "bomb description";
static int id = 1;
private String name;
private int size;
public static void Bomb() {
id++;
System.out.println(" " + description + " " + id);
}
public void setName(String name) {
this.name = name;
}
public void setSize(int size) {
this.size = size;
}
public void printout() {
System.out.println(" " + name + size);
}
}
public class array {
public static void main(String args[]) {
Bomb.Bomb();
Bomb detenator = new Bomb();
Bomb destroyer = new Bomb();
destroyer.setName("hr4");
destroyer.setSize(43);
detenator.setName("m1s");
detenator.setSize(34);
detenator.printout();
destroyer.printout();
}
}
I want the description to print with each bomb object. but the description prints by itself.
any one got any idea how to fix that?
also please suggest any alternative ways I could've written this code, but don't make it to complicated. i just started learning java so i probably wont understand complex stuff.
I short, there are no "static constructors".
You may want something that references a static member, like this:
public Bomb() {
id++;
System.out.println(" " + Bomb.description + " " + id);
}
Please go over the Java tutorial of constructors:
Constructor declarations look like method declarations—except that they use the name of the class and have no return type.
Your definition of constructor is completely messed up.
As #Reut Sharabani mentioned there is no something like static constructor. You are using constructors to initiate object of a class. And static let you use method just by calling ClassName.staticMethod() without creating object of the class (one ruling out another). If static constructor would exist you would be able to write something like, for example, ClassName.ClassName() which make no sense.
Constructors are not returning any value, so declaring them as void is an error. Again constructor is used to initialize your object with some values (but unnecessary)

Why getStamp() return the same value?

I read this code in Thinking in Java and get puzzled:
package generics;
//: generics/Mixins.java
import java.util.*;
interface TimeStamped { long getStamp(); }
class TimeStampedImp implements TimeStamped {
private final long timeStamp;
public TimeStampedImp() {
timeStamp = new Date().getTime();
}
public long getStamp() { return timeStamp; }
}
interface SerialNumbered { long getSerialNumber(); }
class SerialNumberedImp implements SerialNumbered {
private static long counter = 1;
private final long serialNumber = counter++;
public long getSerialNumber() { return serialNumber; }
}
interface Basic {
public void set(String val);
public String get();
}
class BasicImp implements Basic {
private String value;
public void set(String val) { value = val; }
public String get() { return value; }
}
class Mixin extends BasicImp
implements TimeStamped, SerialNumbered {
private TimeStamped timeStamp = new TimeStampedImp();
private SerialNumbered serialNumber =
new SerialNumberedImp();
public long getStamp() { return timeStamp.getStamp(); }
public long getSerialNumber() {
return serialNumber.getSerialNumber();
}
}
public class Mixins {
public static void main(String[] args) {
Mixin mixin1 = new Mixin(), mixin2 = new Mixin();
mixin1.set("test string 1");
mixin2.set("test string 2");
System.out.println(mixin1.get() + " " +
mixin1.getStamp() + " " + mixin1.getSerialNumber());
System.out.println(mixin2.get() + " " +
mixin2.getStamp() + " " + mixin2.getSerialNumber());
while(true)System.out.println(new Date().getTime());
}
} /* Output: (Sample)
test string 1 1132437151359 1
test string 2 1132437151359 2
*///:~
Why are the values returned of getStamp() the same? (1132437151359 == 1132437151359)?
Two objects are created and they have different propoties created in different time, so Why?
The expression new Date().getTime() is a slow way of doing System.currentTimeMillis() which has a minimum resolution of one milli-seconds (but can be as much as 16 ms on some OSes)
This means if the method is called less than one milli-second apart it can give the same result.
A better option is to use AtomicLong.getAndIncrement() for ids.
Using time for serial numbers is not a good idea. The reason you're getting the same time is probably because the code runs rather quickly and enough time doesn't elapse between instantiation of the first object and the second. The time stamp is returned in milliseconds and so if the instantiation of both objects is within 1ms of each other, you won't see a difference.
If you increase load on the system, you might see a difference, or if you use Thread.sleep(5) to cause your program to pause. Both approaches aren't very good.
Instead of using the time for a unique id, use UUID.
Try something like this:
Mixin mixin1 = new Mixin();
Thread.sleep(10);
Mixin mixin2 = new Mixin();
Now you got 10 ms pause in the process of creating those 2 objects.
Your class is simple and you have fast computer so distance in time between two instantations is so small that Java can't see it.

Categories

Resources