2

I'm using protostuff to convert object of my own class to JSON and vice versa. There is java 8 and lambdas. Convert to JSON file like:

LinkedBuffer buffer = LinkedBuffer.allocate(2048);
Schema schema = RuntimeSchema.getSchema(obj.getClass());
boolean numeric = false;
byte[] json = JsonIOUtil.toByteArray(obj, schema, numeric, buffer);
Files.write(file, json);

Convert from JSON to obj:

Schema<MyClass> schema = RuntimeSchema.getSchema(MyClass.class);
Path path = Paths.get("path");
byte[] as = Files.readAllBytes(path);
MyClass mc = schema.newMessage();
JsonIOUtil.mergeFrom(as, mc, schema, false);

And when I'm trying to convert JSON to obj a have an exception:

Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: com.test.Blabla$$Lambda$4/1699679644

I think lambda is a problem. Can I convert classes with it?

Object has a filed:

private final Function<,> name;
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
I.G.
  • 35
  • 5
  • make sure all classes are in class path and are in correct packages (eg: com.test.Blabla).. – Jos May 16 '16 at 08:28
  • yes, I sure. for test I created simple class Person with field Function<>, create instance like `Person p = new Person("Name", "Surname", s -> new String());` convert, same exception. – I.G. May 16 '16 at 08:53

1 Answers1

4

Your lambda is a runtime expression and cannot be serialized. It is in fact a method pointer, which is valid in your running code which serializes. What would the receiving code (which de-serializes) do with such a method pointer, pointing to a method in your sending code?

If your sending code is the same as the receiving code, and the possible values of the lambda expression is a well defined set of different methods you should consider to implement an enum and only serializing the enum value:

public enum Lambdas
{
    FIRST( s -> new String()),
    SECOND( s -> s + " ");

    private Function<String, String> myLambda;

    private Lambdas( Function<String, String> aLambda )
    {
        myLambda = aLambda;
    }

    public Function<String, String> getLambda()
    {
        return myLambda;
    }
}

If your Person now has a member

private Lambdas myLambda;

(which is serializable) your receiving code can use it like this:

String result = myLambda.getLambda().apply();
Heri
  • 4,368
  • 1
  • 31
  • 51