Reputation: 207
I'm trying to get an object from the server, but it does not work.
Relevant section from the server (By Debug I see that he is really sending the correct object):
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage) {
BorderPane mainPane = new BorderPane();
mainPane.setStyle("-fx-border-color: black;");
mainPane.setPadding(new Insets(5,5,5,5));
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(5,5,5,5));
gridPane.add(lblStatus,0,1);
gridPane.add(lblDate,0,2);
mainPane.setTop(gridPane);
createTableView();
mainPane.setCenter(tableView);
Scene scene = new Scene(mainPane, 700, 250);
primaryStage.setTitle("Server"); // Set the window title
primaryStage.setScene(scene); // Place the scene in the window
primaryStage.show(); // Display the window
primaryStage.setAlwaysOnTop(true);
primaryStage.setOnCloseRequest(
new EventHandler<WindowEvent>(){
public void handle(WindowEvent event) {
try {
Platform.exit();
System.exit(0);
serverSocket.close();
socket.close();
}
catch(SocketException ex){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (IOException e) {
// TODO Auto-generated catch block
Platform.exit();
System.exit(0);
}
}
});
connectToDB();
connectionDate=new Date();
Platform.runLater(() ->lblDate.setText(("Server started at \t"+connectionDate)));
Platform.runLater(() ->lblStatus.setText(connectionStatus));
new Thread( () ->
{
try{
// Create a server socket
serverSocket = new ServerSocket(8000);
while (true){
// Listen for a connection request
socket = serverSocket.accept();
this.clientNo++;
clientRequest clientDetails = new clientRequest(clientNo, new Date(), "New Clinet");
addRowToServerTable(clientDetails);
new Thread(new HandleAClient(socket)).start();
}
}
catch(SocketException ex){
}
catch(IOException ex){
}
}).start();
}
/** Connect to DB */
private void connectToDB(){
// Connection to the database
try{
Class.forName(driver); // Load the JDBC driver
System.out.println("Driver Loaded");
connection = DriverManager.getConnection(url, username, password); // Establish a connection
System.out.println("Connected to " + url);
connectionStatus = "Connected to \t" + url;
}
catch (java.lang.Exception ex){
ex.printStackTrace();
connectionStatus = ex.toString();
}
}
// Define the thread class for handling new connection
class HandleAClient implements Runnable{
private Socket socket; // A connected socket
/** Construct a thread */
public HandleAClient(Socket socket){
this.socket = socket;
}
/** Run a thread */
public void run(){
try{
// Create data input and output streams
ObjectOutputStream outputToClient = new ObjectOutputStream(
socket.getOutputStream());
DataInputStream inputFromClient = new DataInputStream(
socket.getInputStream());
// Continuously serve the client
while (true){
// Receive sql from the client
String sql = inputFromClient.readUTF();
clientRequest clientDetails = new clientRequest(clientNo, new Date(),"New Query");
addRowToServerTable(clientDetails);
// Execute SQL
Object[] rows = executeSQL(sql);
outputToClient.writeObject(rows);
}
}
catch(SocketException ex){
try{
serverSocket.close();
//socket.close();
}
catch (IOException e){
}
}
catch(IOException ex){
}
}
Relevant section from the client (Probably the mistake on the client, when it receives the object he jumps line ".start ();" Of the Thread.):
private void connectToServer(){
try{
// Create a socket to connect to the server
socket = new Socket(host, 8000);
// Create an input stream to receive Object from the server
fromServer = new ObjectInputStream(socket.getInputStream());
// Create an output stream to send data to the server
toServer = new DataOutputStream(socket.getOutputStream());
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void sendAndGetFromServer(String sqlQuery){
new Thread(() ->{
try{
System.out.println("a1");
// Send sql query to server
toServer.writeUTF(sqlQuery);
//toServer.flush();
// Get notification from the server
Student[] rows = (Student[])fromServer.readObject();
setRowsInTable(rows);
}
catch(SocketException ex){
try{
socket.close();
}
catch (IOException e){
}
}
catch (Exception ex){
}
}).start();
I tried to separate into two Thread (One Input and other Output in Server and client) according to the answers I read here --- but it didn't help. Also tried to change the order of Input and Output --- without success.
What's the problem here?
Edit. Student class:
public class Student implements Externalizable
{
private final SimpleIntegerProperty ID;
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty address;
private final SimpleObjectProperty<Date> birthDate;
private final SimpleStringProperty department;
private final SimpleIntegerProperty pointsAmount;
private final SimpleObjectProperty<Date> startStudyingDate;
private final SimpleIntegerProperty failedAmount;
private final SimpleDoubleProperty average;
private final SimpleIntegerProperty lavelByGrade;
private final SimpleStringProperty pic;
public Student(int ID, String firstName, String lastName, String address,
Date birthDate, String department,
int pointsAmount, Date startStudyingDate, int failedAmount,
double average, int lavelByGrade, String pic){
this.ID= new SimpleIntegerProperty(ID);
this.firstName= new SimpleStringProperty(firstName);
this.lastName= new SimpleStringProperty(lastName);
this.address= new SimpleStringProperty(address);
this.birthDate= new SimpleObjectProperty<Date>(birthDate);
this.department= new SimpleStringProperty(department);
this.pointsAmount= new SimpleIntegerProperty(pointsAmount);
this.startStudyingDate= new SimpleObjectProperty<Date>(startStudyingDate);
this.failedAmount= new SimpleIntegerProperty(failedAmount);
this.average= new SimpleDoubleProperty(average);
this.lavelByGrade= new SimpleIntegerProperty(lavelByGrade);
this.pic = new SimpleStringProperty(pic);
}
public int getID() {
return ID.get();
}
public void setID(int ID) {
this.ID.set(ID);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getAddress() {
return address.get();
}
public void setAddress(String address) {
this.address.set(address);
}
public Date getBirthDate() {
return birthDate.get();
}
public void setBirthDate(Date birthDate) {
this.birthDate.set(birthDate);
}
public String getDepartment() {
return department.get();
}
public void setDepartment(String department) {
this.department.set(department);
}
public int getPointsAmount() {
return pointsAmount.get();
}
public void setPointsAmount(int pointsAmount) {
this.pointsAmount.set(pointsAmount);
}
public Date getStartStudyingDate() {
return startStudyingDate.get();
}
public void setStartStudyingDate(Date startStudyingDate) {
this.startStudyingDate.set(startStudyingDate);
}
public int getFailedAmount() {
return failedAmount.get();
}
public void setFailedAmount(int failedAmount) {
this.failedAmount.set(failedAmount);
}
public double getAverage() {
return average.get();
}
public void setAverage(Double average) {
this.average.set(average);
}
public int getLavelByGrade() {
return lavelByGrade.get();
}
public void setLavelByGrade(int lavelByGrade) {
this.lavelByGrade.set(lavelByGrade);
}
public String getPic() {
return pic.get();
}
public void setPic(String pic) {
this.pic.set(pic);
}
@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
setID(in.readInt());
setFirstName((String)in.readObject());
setLastName((String)in.readObject());
setAddress((String)in.readObject());
setBirthDate((Date)in.readObject());
setDepartment((String)in.readObject());
setPointsAmount(in.readInt());
setStartStudyingDate((Date)in.readObject());
setFailedAmount(in.readInt());
setAverage(in.readDouble());
setLavelByGrade(in.readInt());
setPic((String)in.readObject());
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(getID());
out.writeObject(getFirstName());
out.writeObject(getLastName());
out.writeObject(getAddress());
out.writeObject(getBirthDate());
out.writeObject(getDepartment());
out.writeInt(getPointsAmount());
out.writeObject(getStartStudyingDate());
out.writeInt(getFailedAmount());
out.writeDouble(getAverage());
out.writeInt(getLavelByGrade());
out.writeObject(getPic());
}
}
Upvotes: 2
Views: 1009
Reputation: 209653
JavaFX properties are not Serializable. So if you try to serialize an object that uses JavaFX properties for its state, you will get an exception.
You have a couple of options here. One is simply to not use Java object serialization, but some other serialization technique, such as representing the object with JSON.
The other option is to implement Externalizable
instead of Serializable
. Externalizable
is a subinterface of Serializable
in which you define your own process for serializing and deserializing the data. In particular, instead of serializing the JavaFX properties themselves, just serialize their contents.
A simple example:
import java.io.Externalizable ;
import java.io.IOException ;
import java.io.ObjectInput ;
import java.io.ObjectOutput ;
import javafx.beans.property.IntegerProperty ;
import javafx.beans.property.SimpleIntegerProperty ;
import javafx.beans.property.SimpleStringProperty ;
import javafx.beans.property.StringProperty ;
public class Person implements Externalizable {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty id = new SimpleIntegerProperty();
public StringProperty nameProperty() {
return name ;
}
public final String getName() {
return nameProperty().get();
}
public final void setName(String name) {
nameProperty().set(name);
}
public IntegerProperty idProperty() {
return id ;
}
public final int getId() {
return idProperty().get();
}
public final void setId(int id) {
idProperty().set(id);
}
// important: must have a no-arg constructor:
public Person() { }
public Person(int id, String name) {
setId(id);
setName(name);
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
// write id then name
// note we write the contents of the properties, not the properties
// themselves, as the properties are not serializable:
out.writeInt(getId());
out.writeObject(getName());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// read data back in same order:
setId(in.readInt());
setName((String)in.readObject());
}
}
Note that this class has a pretty simple structure, so it's easy to implement these two methods. For more complex objects - particularly those which may potentially have circular references - you need to work a bit harder.
Since the class defined above implements Externalizable
, it also implements Serializable
, and can be serialized in the usual way:
ObjectOutputStream oos = ... ;
oos.writeObject(new Person(007, "James Bond"));
Read my blog post on JavaFX beans and JPA for more.
Upvotes: 1
Reputation: 562
Try with this post, search part with following text and Externalizable: For quite a long time, I thought the lack of support for Serialization from JavaFX properties really prevented them from being used in any server-side capacity.
http://www.marshall.edu/genomicjava/2014/05/09/one-bean-to-bind-them-all/
https://gist.github.com/james-d/e485ac525c71e20bb453
Upvotes: 0