Search code examples
javaandroidsocketsclassnotfoundexceptionobjectinputstream

Android C/S using ObjectInputStream and ObjectOutputStream with a Serializable class


On the desktop I have a perfectly working multithreaded client/server project using using ObjectInputStream/ ObjectOutputStream and a class that implements Serializable called Protocolo. This class is used on the server and on the client. As a learning experience I decided to implement the client on Android Studio. I created the following AsyncTasks:

OpenSocket – OpenSocket extends AsyncTask<String, Integer, Socket>

OpenObjectInputStream – OpenObjectInputStream extends AsyncTask<Socket, Integer, ObjectInputStream>

OpenObjectOutputStream – OpenObjectOutputStream extends AsyncTask<Socket, Integer, ObjectOutputStream>

ReadFromServer - ReadFromServer extends AsyncTask<ObjectInputStream, Integer, Object>

WriteToServer - WriteToServer extends AsyncTask<ObjectOutputStream, Integer, Boolean>

On my MainActivity I have a method for the Connect button:

    public void ligarBtClick(View v) {
    String[] params = new String[]{
            server.getText().toString(),
            port.getText().toString()
    };
    AsyncTask<String, Integer, Socket> openSocket = new OpenSocket().execute(params);
    try {
        socket = openSocket.get();
        if (socket != null) {
            AsyncTask<Socket, Integer, ObjectOutputStream> openObjectOutputStream = new OpenObjectOutputStream(xChange).execute(socket);
            output = openObjectOutputStream.get();
            AsyncTask<Socket, Integer, ObjectInputStream> openObjectInputStream = new OpenObjectInputStream(xChange).execute(socket);
            input = openObjectInputStream.get();
            AsyncTask<ObjectInputStream, Integer, Object> readFromServer = new ReadFromServer(xChange).execute(input);
            msgFromServer = (Protocolo) readFromServer.get();
            fromServer.append("SERVER:\t" + msgFromServer.getType() + ": " + msgFromServer.getMessage() + "\n");
            toServer.requestFocus();
            desligarBt.setEnabled(true);
            ligarBt.setEnabled(false);
            enviarBt.setEnabled(true);
        } else {
            fromServer.append("LOG:\tCould not connect to " + params[0] + ":" + params[1] + "\n");
        }
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
}

I am connecting successfully, I am getting an input and an output stream and, using Wireshark, I can see that the server is sending a greeting to the client which the clients ACKs. The relevant part from the ReadFromServer AsyncTask is:

    @Override
protected Object doInBackground(ObjectInputStream... params) {
    Object msgFromServer = null;
    Message msg = Message.obtain();
    try {
        msgFromServer = params[0].readObject();
        msg.what = 5;
    } catch (IOException e) {
        e.printStackTrace();
        msg.what = 6;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    xchange.sendMessage(msg);
    return msgFromServer;
}

My app is crashing when I run ReadFromServer, more specifically when it hits this line msgFromServer = params[0].readObject(); it will crash with the following messages:

06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err: java.lang.ClassNotFoundException: Protocolo
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.lang.Class.classForName(Native Method)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.lang.Class.forName(Class.java:251)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2265)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1641)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:657)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1784)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1985)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1942)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at pt.enta.jdm.tcpclientobject.ReadFromServer.doInBackground(ReadFromServer.java:30)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at pt.enta.jdm.tcpclientobject.ReadFromServer.doInBackground(ReadFromServer.java:14)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:288)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
06-20 12:34:08.745 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.lang.Thread.run(Thread.java:841)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err: Caused by: java.lang.NoClassDefFoundError: Protocolo
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:    ... 17 more
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err: Caused by: java.lang.ClassNotFoundException: Didn't find class "Protocolo" on path: DexPathList[[zip file "/data/app/pt.enta.jdm.tcpclientobject-6.apk"],nativeLibraryDirectories=[/data/app-lib/pt.enta.jdm.tcpclientobject-6, /vendor/lib, /system/lib]]
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
06-20 12:34:08.755 12591-13006/pt.enta.jdm.tcpclientobject W/System.err:    ... 17 more
06-20 12:34:08.755 12591-12591/pt.enta.jdm.tcpclientobject D/AndroidRuntime: Shutting down VM
06-20 12:34:08.755 12591-12591/pt.enta.jdm.tcpclientobject W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41f79bc0)
06-20 12:34:08.755 12591-12591/pt.enta.jdm.tcpclientobject E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: pt.enta.jdm.tcpclientobject, PID: 12591
                                                                             java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                                 at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                                                                                 at android.view.View.performClick(View.java:4508)
                                                                                 at android.view.View$PerformClick.run(View.java:18675)
                                                                                 at android.os.Handler.handleCallback(Handler.java:733)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:136)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5584)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
                                                                                 at dalvik.system.NativeStart.main(Native Method)
                                                                              Caused by: java.lang.reflect.InvocationTargetException
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                 at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                                                                                 at android.view.View.performClick(View.java:4508) 
                                                                                 at android.view.View$PerformClick.run(View.java:18675) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:733) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:136) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5584) 
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
                                                                                 at dalvik.system.NativeStart.main(Native Method) 
                                                                              Caused by: java.lang.NullPointerException
                                                                                 at pt.enta.jdm.tcpclientobject.MainActivity.ligarBtClick(MainActivity.java:66)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                                                                                 at android.view.View.performClick(View.java:4508) 
                                                                                 at android.view.View$PerformClick.run(View.java:18675) 
                                                                                 at android.os.Handler.handleCallback(Handler.java:733) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                                                 at android.os.Looper.loop(Looper.java:136) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5584) 
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
                                                                                 at dalvik.system.NativeStart.main(Native Method) 

The class it is complaining about is the class that exists in the server (not in the client); I changed the name of the class in the server and sure enough it complained it could not find the new name. Can't figure this one out.

Thanks!


Solution

  • Found the solution to my own problem. The class Protocolo is used by both the server and the client. The class has to be in the same package both in the client and in the server. I had the class in the client and in the server but (and as far as I am concerned this would be normal) in different packages.

    Thank you!