Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sending lambdas #12

Open
Adam5Wu opened this issue Jan 26, 2016 · 5 comments
Open

Add support for sending lambdas #12

Adam5Wu opened this issue Jan 26, 2016 · 5 comments
Assignees

Comments

@Adam5Wu
Copy link

Adam5Wu commented Jan 26, 2016

public class TestClient {
    public static void main(String[] argv) {
        try {
            QuickTask.execute("LocalHost", (Runnable) () -> {
                throw new Error("Test");
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Triggers exception message on the server:

Jan 25, 2016 9:38:41 PM com.googlecode.mobilityrpc.session.impl.MobilitySessionImpl receiveIncomingExecutionRequest
SEVERE: Unexpected exception processing execution task, for connection id: 127.0.0.1:64933:0, execution request: ExecutionRequest{serializedExecutableObject=111 bytes, serializationFormat=KRYO, executionMode=RETURN_RESPONSE, requestIdentifier=RequestIdentifier{sessionId=4aa76093-2798-425f-9dbc-07131e49f1dc, requestId=c41303bd-08e2-4127-8ee5-38eac2ac9e70, requestLabel='<no label>'}}
java.lang.IllegalStateException: Failed to process execution request, for connection id: 127.0.0.1:64933:0, execution request: ExecutionRequest{serializedExecutableObject=111 bytes, serializationFormat=KRYO, executionMode=RETURN_RESPONSE, requestIdentifier=RequestIdentifier{sessionId=4aa76093-2798-425f-9dbc-07131e49f1dc, requestId=c41303bd-08e2-4127-8ee5-38eac2ac9e70, requestLabel='<no label>'}}
    at com.googlecode.mobilityrpc.session.impl.MobilitySessionImpl.receiveIncomingExecutionRequest(MobilitySessionImpl.java:371)
    at com.googlecode.mobilityrpc.protocol.processors.impl.ExecutionRequestMessageProcessor.process(ExecutionRequestMessageProcessor.java:39)
    at com.googlecode.mobilityrpc.protocol.processors.impl.ExecutionRequestMessageProcessor.process(ExecutionRequestMessageProcessor.java:31)
    at com.googlecode.mobilityrpc.controller.impl.MobilityControllerImpl$MessageProcessorTask.processMessage(MobilityControllerImpl.java:128)
    at com.googlecode.mobilityrpc.controller.impl.MobilityControllerImpl$MessageProcessorTask.run(MobilityControllerImpl.java:108)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Exception deserializing object from 111 bytes data in KRYO format
    at com.googlecode.mobilityrpc.session.impl.MobilitySessionImpl.deserialize(MobilitySessionImpl.java:514)
    at com.googlecode.mobilityrpc.session.impl.MobilitySessionImpl.receiveIncomingExecutionRequest(MobilitySessionImpl.java:295)
    ... 9 more
Caused by: com.esotericsoftware.kryo.KryoException: Unable to find class: TestClient$$Lambda$1/1599771323
Serialization trace:
wrapped (com.googlecode.mobilityrpc.quickstart.QuickTask$SessionReleasingRunnable)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:156)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:133)
    at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:670)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:118)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.read(FieldSerializer.java:551)
    at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:790)
    at com.googlecode.mobilityrpc.serialization.impl.KryoSerializer.deserialize(KryoSerializer.java:88)
    at com.googlecode.mobilityrpc.session.impl.MobilitySessionImpl.deserialize(MobilitySessionImpl.java:508)
    ... 10 more
Caused by: java.lang.ClassNotFoundException: TestClient$$Lambda$1/1599771323
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:154)
    ... 17 more

However, if a formal inheritance class is made like the test code in #11, then the error is gone.

@npgall
Copy link
Owner

npgall commented Jan 27, 2016

Sending Java 8 lambdas to remote machines is not officially supported yet. At the moment Mobility-RPC targets Java 6 and later, but some newer language features are not guaranteed to work.

I'm going to rename this issue to Add support for sending lambdas, as I want to add support for this.

@npgall npgall changed the title Lost track of class on remote server Add support for sending lambdas Jan 27, 2016
@npgall npgall self-assigned this Jan 27, 2016
@BrynCooke
Copy link

Hi, I have in the past investigated serialization of lambdas. It basically works out of the box if Java serialization is used and the interface that the lambda is implementing is serializable. So the probable solution to this is to allow the user of Java serialization instead of Kryo.

@BrynCooke
Copy link

The other solution is to enable lambda serialization in Kryo: https://github.com/magro/kryo/blob/bf803974ba6351d993093636aac00245f1ec28bc/test/com/esotericsoftware/kryo/serializers/Java8ClosureSerializerTest.java#L52
This could be done with reflection to prevent a dependency on Java8.

@npgall
Copy link
Owner

npgall commented May 13, 2016

I'm not too concerned about Java 6 compatibility anymore. And I think Java 8 lambdas are quite a natural way to send tasks to remote machines.

@BrynCooke I like the second option, to enable Java 8 closure support in Kryo. If you have time to try that out by modifying the KryoSerializer class in mobility-rpc and testing locally, it would help. I'm totally open to merging pull requests which would help with this!

The main challenge I can envisage is that currently the mobility-rpc protocol supports sending only Runnable or Callable objects. Any other type of object to be sent (including lambdas) need to be wrapped in one of these. So the easiest solution if we want to send a lambda, is to write a helper method which wraps the lambda in a Runnable or Callable object. If this is possible then it should not be a problem to send a lambda.

@BrynCooke
Copy link

Thanks, I'll create a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants