Reflection-based roles - #356
Conversation
|
Hi @oberstet, Usage sample: declare the following classes import java.util.Arrays;
public class MyClass {
public int counter;
public int[] foo;
@Override
public String toString() {
return String.format("{counter: %d, foo:%s}", counter, Arrays.toString(foo));
}
}import io.crossbar.autobahn.wamp.reflectionRoles.WampTopic;
public class ComplexSubscriber {
@WampTopic("com.myapp.topic2")
public void OnTopic2(int number1, int number2, String c, MyClass d){
System.out.printf("Got event: number1:%d, number2:%d, c:%s, d: %s%n", number1, number2, c, d);
}
}Then call session.registerSubscriber: import io.crossbar.autobahn.wamp.Client;
import io.crossbar.autobahn.wamp.Session;
import io.crossbar.autobahn.wamp.interfaces.IInvocationHandler;
import io.crossbar.autobahn.wamp.reflectionRoles.ReflectionServices;
import io.crossbar.autobahn.wamp.reflectionRoles.WampProcedure;
import io.crossbar.autobahn.wamp.serializers.JSONSerializer;
import io.crossbar.autobahn.wamp.types.ExitInfo;
import io.crossbar.autobahn.wamp.types.InvocationDetails;
import io.crossbar.autobahn.wamp.types.InvocationResult;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
Session mySession = new Session();
mySession.addOnJoinListener((session, sessionDetails) -> {
System.out.println("Connected!");
ReflectionServices reflectionServices = mySession.getReflectionServices();
// Subscribe to "com.myapp.topic2"
reflectionServices.registerSubscriber(new ComplexSubscriber());
});
Client client = new Client(mySession, "ws://127.0.0.1:8080/ws", "realm1", executor);
CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}
}This sample works with this code. In order to have the parameters c and d filled (and not null), make sure to compile with the "-parameters" flag, otherwise Java won't emit the names of the parameters, and the code will fail to attach them to the corresponding parameters. Elad. |
|
@darkl Hi Elad! Awesome. Really cool. This allows for a style that is definitely even more expressive for app code, which is good. Also, thanks a lot for outlining rationale, usage examples, todos and all. @om26er maybe you also have a look over the code as it is quite extensive and see if you have comments from you side (you are much more familiar with the details I guess by now). also you could also check over all what Elad wrote (in particular the todos) and file issues as you see fit. I think this is really worth following up on, and of course then also putting it on the frontpage etc |
|
I have been looking into this, the change is mostly isolated, so doesn't really change the existing code (which is a good thing). One big problem however is that the new code won't work on Android, except for Android 8.0+ aka API level 26[1]. We currently support API level 24 as minimum. I have spent quite some time trying to figure out if there is a way to get that working on older versions through a third party library, so far no luck. I came across these libraries that could help though. https://github.com/maxxedev/javapan @oberstet For now what we can do is to only land that feature for Netty (need to make some changes in gradle config for that). Your call. [1] https://developer.android.com/reference/java/lang/reflect/Parameter.html |
|
|
||
| for (int i = 0; i < parameters.length; i++) { | ||
| Parameter parameter = parameters[i]; | ||
| String parameterName = parameter.getName(); |
There was a problem hiding this comment.
For Android, the main issue is this API(level 26 only) and of course its use is central to what we are trying to achieve here.
|
Is there any option for conditional compilation? (#ifdef in C#)
If this option exists, you can support parameter name mapping only for
netty. Also note my remark that parameter name mapping works only if the
user adds the "-parameters" flag, so you guys might just decide to ditch it
(IMO this feature is pretty neat, unfortunately Java makes life harder
about using it).
|
@om26er Ok, making it work on Netty only first is cool! We can figure out Android later. So I am going to merge this now - could you pls create a follow up PR with the gradle changes you mentioned? ah, and pls file follow up issues for the remaining todos mentioned by Elad |
|
@darkl awesome! thanks for coming around here and contributing=) |
Hi @oberstet,
This pull request contains a sketch for reflection based caller/callee roles. This is pretty cool.
Usage:
Callee proxy:
Declare an interface:
Use ReflectionServices property of session in order to obtain a proxy, and then call the desired method:
Callee
Declare a class
Use ReflectionServices property of service to register all procedures of an instance of this class:
TODOs
I really hope that this kind of feature will be integrated in AutobahnJava.
Feel free to ask me any question about this.
Elad