Update - You can find a sample project to recreate the issue here: https://github.com/benf1977/j2objc-serialization-example/releases/tag/1.0
I'm trying to serialize an object in Java and pass the bytes over to my Objective-C layer to write to the filesystem. My relevant Java code is this:
/**
* Created by benjamin.flynn on 10/7/15.
*/
public class TestData implements Serializable {
private String mName;
private int mAge;
public TestData(String pName, int pAge) {
mName = pName;
mAge = pAge;
}
public String getName() {
return mName;
}
public int getAge() {
return mAge;
}
public byte[] bytes() {
byte[] bytes = null;
try (ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);) { // Application will break on this line when run on Xcode
objectOutputStream.writeObject(this);
bytes = byteOutputStream.toByteArray();
} catch (IOException ioe) {
System.err.println("Aww snap: " + ioe);
}
return bytes;
}
}
I've unit tested this class in Java (which I also have a deserializer for) and it passes. In Objective-C, I'm doing this:
ComMycompanyTestData *testData = [[ComMycompanyTestData alloc] initWithNSString:@"Daryl" withInt:47];
IOSByteArray *bytes = testData.bytes; // Exception here
The exception is:
(lldb) po $arg1
java.lang.NoSuchMethodException: writeReplace
The relevant trace is:
frame #0: 0x000000019a2cbf48 libobjc.A.dylib`objc_exception_throw
frame #1: 0x0000000100214bb0 MyApp `-[IOSClass getDeclaredMethod:parameterTypes:] + 124
frame #2: 0x00000001000c9188 MyApp`JavaIoObjectStreamClass_findMethodWithIOSClass_withNSString_ + 144
frame #3: 0x00000001000c71dc MyApp`JavaIoObjectStreamClass_createClassDescWithIOSClass_ + 984
frame #4: 0x00000001000c909c MyApp`JavaIoObjectStreamClass_lookupStreamClassWithIOSClass_ + 88
frame #5: 0x00000001000c8f88 MyApp`JavaIoObjectStreamClass_lookupWithIOSClass_ + 44
frame #6: 0x00000001000c6f30 MyApp`JavaIoObjectStreamClass_createClassDescWithIOSClass_ + 300
frame #7: 0x00000001000c909c MyApp`JavaIoObjectStreamClass_lookupStreamClassWithIOSClass_ + 88
frame #8: 0x00000001000c8f88 MyApp`JavaIoObjectStreamClass_lookupWithIOSClass_ + 44
frame #9: 0x00000001000c284c MyApp`JavaIoObjectOutputStream_initWithJavaIoOutputStream_ + 56
frame #10: 0x00000001000c6a20 MyApp`new_JavaIoObjectOutputStream_initWithJavaIoOutputStream_ + 48
* frame #11: 0x00000001000a666c MyApp`-[ComMycompanyTestData bytes](self=0x000000013fd51a50, _cmd="bytes") + 76 at TestData.java:49
Thoughts on what might be happening?
What version of j2objc are you using? We've made recent improvements in serialization, and running your example works after adding this test added:
public static void main(String[] args) {
TestData td = new TestData("Jane Doe", 30);
byte[] serialized = td.bytes();
System.out.println("serialized: " + Arrays.toString(serialized));
}
I ran this with a translator/runtime built using "make dist" on the current j2objc source:
$ javac TestData.java
$ java TestData
serialized: [-84, -19, 0, ...
$ j2objc TestData.java
translating TestData.java
Translated 1 file: 0 errors, 0 warnings
$ j2objcc TestData.m
$ ./a.out TestData
serialized: [-84, -19, 0, ...