I don't know about the implementation. I don't think a new connection is made. But what I know is the more objects you share remotely the more objects that depends on remote dereference to get garbage collected (so there will be more objects living longer, not good).
Alternative approach
I'll recommend a mixed approach. Use the nice approach for the client but implement it the not-so-nice-way internally:
interface Server {
public Handler getHandler(...);
}
interface Handler extends Serializable {
// it gets copied!
public X doThis(...);
public Y doThat(...);
}
class HandlerImpl implements Handler {
public X doThis(...) {
backDoor.doThis(this, ...);
}
public Y doThat(...) {
backDoor.doThat(this, ...);
}
private BackDoor backDoor;
}
interface BackDoor {
public X doThis(Handler h, ...);
public Y doThat(Handler h, ...);
}
class ServerImpl imlpements Server, BackDoor {
public Handler getHandler(...) {
return /*a handler with a self reference as backdoor, only ONE remote obj shared via TWO interfaces */
}
...
// it does everything
// it receives the handler
}
BackDoor and Handler are sync'ed interfaces. The first has the methods with Handler as argument, the later has the pure methods. I don't think it's a big deal. And the two different interfaces let you work cleanly without the client know nothing and allowing the thin serializable Handler's do the dirty work.
Hope you like it!