Search code examples
javaandroidserializationdeserializationweka

Serialise and Deserialise an object in Java/Android [WEKA]


I am serialising an already trained classifier on my Computer and I am trying to deserialize it on Android. However, when I try to deserialize it on my Android Device I see this log in the console:

W/System.err: java.io.InvalidClassException: weka.classifiers.meta.LogitBoost;
Incompatible class (SUID): weka.classifiers.meta.LogitBoost: static final long serialVersionUID =-1105660358715833753L;
but expected weka.classifiers.meta.LogitBoost: static final long 
serialVersionUID =-3905660358715833753L;
W/System.err:     at java.io.ObjectInputStream.verifyAndInit(ObjectInputStream.java:2336)

Not sure what to do. I have to mention that I am using a stripped version of WEKA available here.

This is my classifier class used to train and serialize the classifier on my computer:

public class ClassifierSerializer {
//variables//
public ClassifierSerializer(String classifierName,
                            String classifierParameters,
                            String dataSourceFile,
                            String outputFileName) {

    this.classifierName = classifierName;
    this.classifierParameters = classifierParameters;
    this.dataSourceFile = dataSourceFile;
    this.outputFileName = outputFileName;
}

/**
 * Output the trained classifier to the specified file
 */
public void serialize() {
    readFile();
    train();
    writeToFile();
}
private void train() {
        classifier = AbstractClassifier.forName(classifierName, Utils.splitOptions(classifierParameters));
        classifier.buildClassifier(dataset);
 }
private void writeToFile() {
    // Serialize classifier
    FileOutputStream fileStream;

    fileStream = new FileOutputStream(outputFileName);
    ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
    objectStream.writeObject(classifier);
    objectStream.close();
    fileStream.close(); 
}
}

This is how I am using it in my main method:

public static void main(String[] args) throws Exception {
    String datasource = "C:\\Users\\Georgi\\Desktop\\HAR_training.arff";
    ClassifierSerializer classifierSerializer = new ClassifierSerializer(
            "weka.classifiers.meta.LogitBoost",
            "-P 100  -L -1.7976931348623157E308 -H 1.0 -S 1 -I 10 -W weka.classifiers.trees.DecisionStump",
            datasource,
            "logit.data");
    classifierSerializer.serialize();
 }

And this is how I am deserializing it on Android (I have the fine in my assets folder):

private Classifier getClassifier() {
    // Add logic to make a network call to download the trained offline model/classifier
    String filename = "logit.data";
    ObjectInputStream objectStream = new ObjectInputStream(getAssets().open(filename));
    Object obj =objectStream.readObject();

    if (obj instanceof Classifier) {
        return (Classifier) obj;
    } else {
        return null;
    }

}

Solution

  • I found out what was going on (kind of). I decided to replace the full weka.jar library in my InteliJ project on my PC with the same stripped version of the weka library that I am using on my Android Project. For some reason that solved the problem. I assume, the versions were a bit different and some change differences were causing the problem.