There is a client ( Login ) that sends an object ( objRequest ) through the connection class ( clentCon ) to the server. The server ( ServerWindow ) receives an object (an echoThread is created for each client), works with it, collects a response object ( objResponse ) and sends it to the client. In the objResponse class objResponse 3 variables ( ResultSet , int , String , all have default values, constructors simply assign new values ​​to two of them), the class implements Serializable .

At the moment, the client is accessing the server in two places. In one ("check connection") in the returned object, the int and String change and everything works fine. In the second (implies a query to the database) the ResultSet and String should change, but I get the following:

 java.io.NotSerializableException: com.mysql.jdbc.JDBC4ResultSet at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at logic.echoThread.run(echoThread.java:60) 

from the server side and

 java.lang.NullPointerException at keyringWindows.Login.checkPassword(Login.java:257) at keyringWindows.Login$3.actionPerformed(Login.java:151) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.mysql.jdbc.JDBC4ResultSet at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at logic.clientCon.run(clientCon.java:36) Caused by: java.io.NotSerializableException: com.mysql.jdbc.JDBC4ResultSet at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at logic.echoThread.run(echoThread.java:60) 

from the client.

As far as I can tell, the problem is somewhere in echoThread

 public class echoThread extends Thread { protected Socket soc = null; private ObjectInputStream objins = null; private ObjectOutputStream objouts = null; private Connection con = null; public JTextPane tp; public echoThread(Socket soc, Connection con, JTextPane tp) { this.soc = soc; this.con = con; this.tp = tp; } public void run() { try { objins = new ObjectInputStream(soc.getInputStream()); objouts = new ObjectOutputStream(soc.getOutputStream()); while(true) { try { objRequest request = (objRequest) objins.readObject(); sleep(250); String type = request.getType(); tp.setText(tp.getText() + String.format("Получен запрос типа: %s\n", type)); objResponse resp = null; if(type.equals("select")) { Statement st = con.createStatement(); resp = new objResponse(st.executeQuery(request.getQuery()), type); st.close(); } else if(type.equals("check")) { resp = new objResponse(123,"checked"); } else { PreparedStatement statement = con.prepareStatement(request.getQuery()); resp = new objResponse(statement.executeUpdate(), type); statement.close(); } objouts.writeObject(resp); objouts.flush(); } catch(Exception ex) { ex.printStackTrace(); return; } } } catch(Exception ex) { JOptionPane.showMessageDialog(null, "Ошибка подключения.\n" + ex.getMessage()); } finally { try { tp.setText(tp.getText() + "Клиент отключился\n"); soc.close(); objins.close(); objouts.close(); } catch(Exception ex) { JOptionPane.showMessageDialog(null, "Ошибка подключения. Серверное приложение будет выключено."); System.exit(0); } } } } 

Please help understand what's wrong.

  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

1 answer 1

The problem is that the ResultSet that you are trying to ObjectOutputStream into an objResponse not serializable within the objResponse object, so it cannot (sorry for tautology) be serialized, that is, written to an ObjectOutputStream . From here a problem on the client: as the server could not write data in the answer, on client side got out NullPointerException . Good article about serialization in Java .

You should reconsider the protocol of data exchange between the client and the server. Why does the server give an unprocessed ResultSet ? It would be better on the server to pull the necessary data out of it, put it into some kind of serializable object and only then transfer it to the client.

Also: you need to close the statement in the finally block. If there is an error in your code when executing the SQL query, the statement will remain unclosed and you will have a memory leak.

Update

Still, it is better to consider the option of providing the result as an object of a particular class. In general, if you are not writing an application whose purpose is to allow the user to execute any SQL queries on the server, it would be better if the client does not know how and where the data is received from. If you don’t want to write a separate class for each query, use List<Map<String, Object>> , but not the ResultSet .

  • Clear. Googled a bit and found a certain CachedRowSetImpl , which, judging by the description, is a serializable extension of ResultSet . Since I plan to have many different requests to the database, and I would not like to write each option into separate classes (or one particularly cumbersome), can I use it? - Mr Scapegrace