[
https://issues.apache.org/jira/browse/ODE-979?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13549674#comment-13549674
]
Hadrian Zbarcea commented on ODE-979:
-------------------------------------
I didn't close this issue because I was looking into a better way of doing it.
The Channels and ChannelListeners are basic concepts and any changes have
significant impacts all over the rest of the code. However they are not really
necessary in this form.
Firstly the generated Channel is not really needed, because they are always
used via Proxies. However, Proxies could implement multiple interfaces so there
is no real need for a (generated) class that implements both T (the generic
channel interface) and Channel. Things are a bit more complicated with
ChannelListeners and the challenge is to come up with a solution that allows to
change things incrementally.
There are 2 things that go against each other. The listener is invoked on to
pass the message, so they need to implement the generic channel interface T,
but the implementation has to interact with the runtime, so it needs to extend
JacobObject as well. Since java does not allow a generic class to implement (or
extend) a generic type, the solution was code generation. The best solution I
could come up with that would allow an incremental transition is introducing a
new abstract class RecieveProcess that does not implement T, but uses a T:
{code}
public abstract class ReceiveProcess<C extends Channel, R> extends
ChannelListener<C> {
final R receiver;
[...]
public Object receiver() {
return receiver;
}
public Set<Method> getImplementedMethods() {
if (_implementedMethods == null) {
Set<Method> implementedMethods = new HashSet<Method>();
ClassUtil.getImplementedMethods(implementedMethods,
receiver.getClass());
_implementedMethods =
Collections.unmodifiableSet(implementedMethods);
}
return _implementedMethods;
}
}
{code}
(NOTE: getImplementedMethods returns the list of methods supported by the
channel. It's kinda like the messages passed along the pi calculus channels are
instances of java.lang.reflect.Method, which are actuall, well, Continuations).
Then I modified JacobVpu.JacobThreadImpl.run() like this:
{code}
_method.invoke(_methodBody instanceof ReceiveProcess ?
((ReceiveProcess<?, ?>)_methodBody).receiver() : _methodBody, args);
{code}
Now given the fact that most of the listeners are implemented as anonymous
classes within the context of a JacobObject (Runnable), the JacobVPU (pi
calculus) methods (object/instance/message/newChannel) will be accessible. In
the rare cases where not, the access will be provided by getting the
JacobThread from the TLS.
So the new code will look like:
{code}
object(new ReceiveProcess<ValChannel, Val>(retChannel, new Val() {
public void val(Object retVal) {
_val = retVal;
}
}) {});
{code}
Once the whole code transitions to using ReceiveProcesses instead of generated
ChannelListeners, the code can be further simplified by eliminating the
ChannelListener completely and changing the ReceiveProcess to use only one
generic argument.
Since this change will have ripple effect across the whole code, I would
appreciate your thoughts before committing.
> Upgrade jacob-ap to jsr-269
> ---------------------------
>
> Key: ODE-979
> URL: https://issues.apache.org/jira/browse/ODE-979
> Project: ODE
> Issue Type: Improvement
> Reporter: Hadrian Zbarcea
> Assignee: Hadrian Zbarcea
> Fix For: 1.4
>
> Attachments: examples-jacob.zip
>
>
> Upgrade the apt support in jacob-ap to jsr-269. The old mirror api is
> deprecated anyway.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira