How to generate a serializable java class in Clojure by gen-class?

624 Views Asked by At

We need to serialize a bunch of Java objects generated by Clojure into a file by Java Serialization mechanism.

(gen-class
 :name lancelot.Instance
 :extends cc.mallet.types.Instance)

(gen-class
 :name lancelot.FilterPipe
 :extends cc.mallet.pipe.Pipe
 :prefix "-filter-"
 :methods [[pipe [cc.mallet.types.Instance] lancelot.Instance]])

(defn -filter-pipe [this ^cc.mallet.types.Instance inst]
  (.setData inst (clojure.string/join " "
    (filter normal-word? (clojure.string/split (.getData inst) #"\s+"))))
  inst)

(gen-class
 :name lancelot.SegmentorPipe
 :extends cc.mallet.pipe.Pipe
 :prefix "-segmentor-"
 :methods [[pipe [cc.mallet.types.Instance] lancelot.Instance]])

(defn -segmentor-pipe [this ^cc.mallet.types.Instance inst]
  (.setData inst (seg/seg (.getData inst)))
  inst)

As above, instances of lancelot.FilterPipe and lancelot.SegmentorPipe need to be serialized. We found that writing object stream is OK, but reading object stream are not work after we re-compile the code.

Exception in thread "Thread-8" java.io.InvalidClassException: lancelot.SegmentorPipe; local class incompatible: stream classdesc serialVersionUID = 2583852145887230781, local class serialVersionUID = -2255006751011717591 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)

Since serialVersionUID is static and final, but it seems that gen-class can only generate instance level final field. So the problem is that I can not set a specific serialVersionUID for the generated class.

Any advice for the problem? Thanks in advance.

1

There are 1 best solutions below

0
On

Please try to add Serializable

(gen-class :name lancelot.Instance :implements [java.io.Serializable] :extends cc.mallet.types.Instance)