序列化和 Android ClassNotFoundException

Serialization and Android ClassNotFoundException

您好,我正在尝试将自定义对象列表从客户端发送到服务器。我收到 ClassNotFoundException。我正在为我的客户端使用 Android studio 模拟器,并在 Eclipse 上使用 运行 我的服务器。我什至写了一个测试代码来检查它是否在 Eclipse 中工作并且确实如此。但由于某种原因不适用于 android。我是 Android 的新手。

import java.io.Serializable;
import java.util.Arrays;    

public class Document implements Serializable {
private static final long serialVersionUID = 1L;
String id;
String name;
String address;
String[] category;
float lattitude;
float longitude;
String city;
double stars;
double overallRating;
// String attributes[];
Review[] reviews;

public Document(String id, String name, String address, String[] category, float longitude, float lattitude,
        String city, double stars, double overallRating, Review[] review) {
    super();
    this.id = id;
    this.name = name;
    this.address = address;
    this.category = category;
    this.longitude = longitude;
    this.lattitude = lattitude;
    this.city = city;
    this.stars = stars;
    this.overallRating = overallRating;
    this.reviews = review;
}

@Override
public String toString() {
    return "Document [id=" + id + ", name=" + name + ", address=" + address + ", category="
            + Arrays.toString(category) + ", lattitude=" + lattitude + ", longitude=" + longitude + ", city=" + city
            + ", stars=" + stars + "]";
}

}

import java.io.Serializable;

public class Review implements Serializable {

    private static final long serialVersionUID = -1595783420656910821L;
    double stars;
    String review;

    public Review(double stars, String review) {
        this.stars = stars;
        this.review = review;
    }

}

//部分服务器

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.List;

public class CommunicatewithMobileDevice implements Runnable {
Socket conn;
private InvertedIndexA invertedIndex;
private BufferedReader br;
private ObjectOutputStream oos;
private PrintWriter pw;

public CommunicatewithMobileDevice(Socket sock, InvertedIndexA invertedIndex) {
    conn = sock;
    this.invertedIndex = invertedIndex;
    try {
        br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()), true);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void run() {

    try {

        String ip = br.readLine();

        String input[] = br.readLine().split(" ");
        System.out.println(ip + " " + input[0] + " " + input[1]);
        List<Document> docs = invertedIndex.search(ip, Float.valueOf(input[0]), Float.valueOf(input[1]));
        System.out.println(docs.size());
        oos = new ObjectOutputStream(this.conn.getOutputStream());
        oos.writeObject(docs);


        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

//单例或服务器

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class Singleton implements Runnable {
    private ServerSocket conn;
    private static InvertedIndexA invertedIndex = new InvertedIndexA(Helper.loadCategories());
    private boolean isStopped = false;

    private Singleton() {
    }

    public static InvertedIndexA getInstance() {
        return invertedIndex;
    }

    public static void main(String args[]) {
        new Thread(new Singleton()).start();
    }

    public void acceptsClients() {
        try {
            synchronized (this) {
                conn = new ServerSocket(1503);
            }
            while (!isStopped()) {
                Socket sock = conn.accept();
                //System.out.println("Conn accepted");
                new Thread(new CommunicatewithMobileDevice(sock, invertedIndex)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private synchronized boolean isStopped() {
        return this.isStopped;
    }

    public synchronized void stop() {
        this.isStopped = true;
        try {
            this.conn.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }

    @Override
    public void run() {
        acceptsClients();
    }
}


    //The android client or a part of it



import android.Manifest;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import android.widget.ListView;
import android.widget.TextView;
import android.content.Context;

public class ListOfResults extends AppCompatActivity {

    CommunicateWithServer comm;
    GPSTracker gps;
    String message = "";
    List<Document> docs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_of_results);
        comm = new CommunicateWithServer();
        Bundle bundle = getIntent().getExtras();
        message = bundle.getString("message");
        //new Communicate().execute();
        new Thread(runnable).start();
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                Socket sock = new Socket("localhost", 1503);
                PrintWriter pw = new PrintWriter(sock.getOutputStream(), true);
                pw.println(message);
                double latitude = 0;
                double longitude = 0;
                pw.println(new String(Double.valueOf(latitude) + " " + Double.valueOf(longitude)));
                ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
                docs = (List<Document>) ois.readObject();
                BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                //Log.e("print the val",br.readLine());
                //System.out.println(docs.size());
                Log.e("size", Integer.toString(docs.size()));


            } catch (IOException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                System.out.println("yeassass");
            }
        }
    };

    public void populate(String result) {
        Log.e("here", "here");
        DocumentAdapter documentAdapter = new DocumentAdapter(this, docs);
        ListView listView = (ListView) findViewById(R.id.listView1);
        listView.setAdapter(documentAdapter);
    }
}

//这是我写的测试服务器代码的测试程序。在这里工作正常

 import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.List;

    public class Test implements Runnable {

        public Test() {
            // TODO Auto-generated constructor stub
        }

        public static void main(String args[]) {
            Test test = new Test();
            new Thread(test).start();
        }

        public void run() {
            testOp();
        }

        private void testOp() {
            try {
                Socket sock = new Socket("localhost", 1503);
                PrintWriter pw = new PrintWriter(sock.getOutputStream(), true);
                String location = Helper.getLocation();
                location = location.substring(location.lastIndexOf(") ") + 2);
                String split[] = location.split(",");
                pw.println("Chinese");
                pw.println(new String(split[0] + " " + split[1]));
                ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
                List<Document> docs = (List<Document>) ois.readObject();
                System.out.println(docs);
            } catch (IOException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

异常:

04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err: java.lang.ClassNotFoundException: Document
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.Class.classForName(Native Method)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.Class.forName(Class.java:309)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2263)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1641)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:657)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1782)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.util.ArrayList.readObject(ArrayList.java:661)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1330)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1242)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1835)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at com.kpt.krishgodiawala.myapplication.ListOfResults.run(ListOfResults.java:57)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.Thread.run(Thread.java:818)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err: Caused by: java.lang.ClassNotFoundException: Didn't find class "Document" on path: DexPathList[[zip file "/data/app/com.kpt.krishgodiawala.myapplication-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     ... 20 more
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     Suppressed: java.lang.ClassNotFoundException: Document
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.Class.classForName(Native Method)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
04-26 21:10:04.470 6009-6116/com.kpt.krishgodiawala.myapplication W/System.err:         ... 21 more

根据异常 java.lang.ClassNotFoundException: Document,这一定是因为 class 名称在编译时更改了。检查 document 以排除 DocumentReview class

更新: 还有 this 文档

java.lang.ClassNotFoundException: Document

所以您没有在客户端部署名为 Document 的 class。从客户端代码行编译的事实来看,你必须在其他包中有一个 Document class。那是不一样的 class,不管它的名字是什么。它必须相同 class、相同的包、相同的 serialVersionUID