Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I created the default "hello world" GWT application and noticed that it has the following default code:

/**
 * Create a remote service proxy to talk to the server-side Greeting service.
 */
private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);

I was wondering how this is possible since the declaration of GreetingService is:

@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
    String greetServer(String name) throws IllegalArgumentException;

}

I thought you weren't able to instantiate Interfaces?

Thanks!

share|improve this question
    
possible duplicate of Instantiate interface in JAVA? –  Bozho Oct 24 '10 at 21:18
2  
@Kirk Bozho's link is about GWT –  Cristian Oct 24 '10 at 21:20
add comment

3 Answers

up vote 3 down vote accepted

Well, for one thing, it's not calling a constructor on an interface. This is perfectly valid Java, and in many Service Locator frameworks it would be fine. It's just calling a method, which returns something implementing GreetingServiceAsync as far as the Java compiler is aware.

The next thing to remember is that it's not going to be executing as Java anyway. GWT is going to be translating all of the client code into JavaScript magically. All it's got to know is what the remote path is (so it can know where to make the relevant service calls) and what the signatures are (so the Java actually has something to work with, and so it can validate you're passing appropriate arguments to the remote service).

At execution time this isn't going to be building a Java object at all... it'll be doing something in JavaScript so that it can make the RPC... and then on the server side, you can have a real implementation of the interface listening for that request.

share|improve this answer
    
How does it determine the relevant implementation? I thought the "Create" call would try to instantiate whatever class you pass in? –  Hortitude Oct 24 '10 at 21:09
    
@Hortitude: See my rewritten answer. –  Jon Skeet Oct 24 '10 at 21:19
    
This is true, when the application executes in compiled (JavaScript) form. But since GWT also supplies a Development Mode (which executes in Java), it must be able to create a Java object. To this end, deferred binding and Java code generators are used. You can see these generated classes, when you turn on the -gen compiler option. –  Chris Lercher Oct 25 '10 at 9:44
    
@chris_l: Interesting to know, thanks. I think the most important point is that it simply isn't invalid Java to start with - it's important to understand the difference between trying to call a constructor on an interface, and calling a static method which will return an implementation of an interface (where you shouldn't care what the implementation is like). –  Jon Skeet Oct 25 '10 at 9:55
add comment

It's using deferred binding, and in this case with a generator to dynamically create the implementation of the interface at compile-time (or runtime in the case of DevMode, but actually it generates Java code that's compiled on-the-fly)

share|improve this answer
add comment

The RPC Plumbing Diagram mentions:

Some of these classes, such as the service proxy, are automatically generated behind the scenes and you generally will never realize they exist.

Let's take a look behind those scenes:

We'll start at /com/google/gwt/rpc/RPC.gwt.xml in gwt-user.jar:

<generate-with class="com.google.gwt.rpc.rebind.RpcServiceGenerator">
  ...
  <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService" />
  ...
</generate-with>

This specifies a deferred binding, as mentioned by Thomas Broyer. So let's go to RpcServiceGenerator:

...
return new RpcProxyCreator(remoteService);
...

Now you can take a detailed look at the relatively complex code of RpcProxyCreator and its superclass ProxyCreator. I believe, the piece of code you're looking for is in ProxyCreator.getSourceWriter:

...
composerFactory.addImplementedInterface(
  serviceAsync.getErasedType().getQualifiedSourceName());
...
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.