Tuesday, May 3, 2011

gwt-dispatch and Custom Header or Basic Authentification

gwt-dispatch is an open source implementation of the command pattern, which is very well suited for use with GWT RPC.

In order to set Custom Headers in GWT you need to get the RequestBuilder instance which will perform the request under the covers for you.

There are two ways to do this:
  1. Let your Async Interface return RequestBuilder instead of void
  2. You can provide an instance of RPCRequestBuilder to your service, which will construct the RequestBuilderInstance

Using option one has the disadvantages that you have to send your request manually, thus changing the DispachAsync interface would break a lot of current applications (and introduce a lot of redundant code). So I was looking for another options.


You can downcast your service to ServiceDefTarget and set an instance of RPCRequestBuilder like this:

service = GWT.create(Dispatch.class);
((ServiceDefTarget) service).setRpcRequestBuilder(this.authenticatingRequestBuilder);


With and RPCRequestBuilder looking like this:

public class ACustomRequestBuilder extends RpcRequestBuilder {

@Override
protected RequestBuilder doCreate(String serviceEntryPoint) {
RequestBuilder requestBuilder = super.doCreate(serviceEntryPoint);
requestBuilder.setHeader("your header", "your value");
return requestBuilder;
}
}




Now you can easily control all aspects of your request.

Thanks to Robert Muntenau this is now also in the gwt-dispatch docs: http://code.google.com/docreader/#p=gwt-dispatch&s=gwt-dispatch&t=RequestBuilder

Saturday, April 16, 2011

Testcoverage in general and with GWT MVP

I have always been criticized about my view on minimal test coverage of code.

I always advocated that any test coverage below 100% may lead to the following:
Only the easy to cover parts of the software get tested. The hard parts will be left out. (I already have a sufficient part tested, why spend more time?). The really tricky edge cases will be left out sometimes entirely.

To make myself clear: I am not taking about 100% input coverage. Every line of code that will run in production should behave as expected (or intended by the developer). To make sure you should run through this code at least one time to state your intention. This will not in any way prove that your product doesn't have any bugs. It will just reduce the number of bugs.

Sometimes I heard the argument that this is fine for backend code where it's easy to mock out dependencies, but does not translate to UI programming. That's just not true: if you take a look at GWT MVP you get a very good idea how to isolate your presentation logic from the UI fields and you can test most of your code in a simple JUnit Test Case.

Me personally I like EMMA a lot. It's an open-source toolkit for measuring and reporting Java code coverage, which has a nice integration in eclipse and maven as well. Basically in eclipse it marks a line in your code green, yellow or red. Red meaning that this part of the code was never executed during your tests. Green meaning this part of the code was executed. Yellow meaning that only part of your code was executed. It also sums up test coverage for packages.

Using EMMA you can quickly discover the dirty spots in your project and improve their test coverage. I even trigger built failures if the test coverage drops from a previous built, so that you can only check in tested code.

But if you think about a normal GWT MVP project you will end up with a few untested places like your Entrypoint with all the initialization, and those view implementations. It's not possible to test them in simple JUnit Test and so it's not possible to test them very quickly at all. Quick feedback to your commits is very important, so what can we do about those. First we exclude them from EMMA so that we only measure the testable code. Second thing is that most of the code is simple UI plumbing stuff. So we can get a decent coverage (which is sufficient) in our UI Test with selenium for instance.

Monday, March 21, 2011

gwt-phonegap 0.8

The next release of gwt-phonegap 0.8 is ready to be downloaed.

The Contacts API is now part of the project and two plugins Childbrowser and Badge.

The main improvement is that gwt-phonegap now runs inside your desktop browser (with an emulated implementation). By using GWT.create to create the instance of the new phonegap interface we can easily detect the environment and load the appropriate gwt-phonegap implemenation. This makes it much easier to develop your phonegap app in the browser.

The new version is now the featured download on the project page.

Monday, March 14, 2011

gwt phonegap 0.7 realeased

Today I found the time to update gwt-phonegap to the latest phonegap version 0.9.4 and gwt 2.2.

The new version can be downloaded here

Note:
If you start using phonegap 0.9.4 on iOS there is an issue with the Phonegap Network interface (isReachable). I`m going to update the issue. A valid workaround is described here.

Tuesday, February 22, 2011

mgwt 0.5a

About one and a half years ago I started developing applications for the iPhone using GWT and phonegap. At the moment GWT is not quite a fit for mobile development so I had to adjust the tool and do some ground work.

After using mgwt for my personal mobile developement I had some great responses from colleagues telling me to open source my work. It took me quite a while to start sharing because I am one of those persons who like to show of with perfect code, but at some point I realized that I should be sharing as soon as possible to get some feedback.

So the first wave of open sourcing consists of:
  1. the GWT Events (touchstart, touchmove, touchend, touchcancel, animationend, transistionend) integrated with the GWT event System
  2. Anitmations integrated with GWT MVP
  3. Styling for iPhone
  4. Lots and lots of widgets

I also have a theme for iPads and Android which I would like to share at some later point (they are just not ready yet). I am very excited about mgwt and hope to find some people that are exited as well about developing mobile apps with gwt.

Any feedback is very much welcome!

So if you like to see what mgwt is like check out www.m-gwt.com

Saturday, January 1, 2011

GWT RPC with Phonegap

Update: This is no longer necessary. Take a look at a newer post!


I have been asked a couple of times now how to use gwt rpc with phonegap applications. Right now this does not work out of the box for a simple reason:

For security reasons phonegap starts your application locally (not http:// but file://pathToYourApp/www/index.html). GWT on the other hand assumes that it will find the services by appending your annotated servlet path to the base url. So GWT phonegap applications out of the box try to find their services locally.

In order to fix this you have to do a couple of things (which will be included in the next version of gwt-phonegap)

You have to set the url of your servlet in the proxy service interface like so:

DispatchServiceAsync realService = GWT.create(DispatchService.class);
ServiceDefTarget service = (ServiceDefTarget) realService;
service.setServiceEntryPoint("http://www.daniel-kurka.de/yourservice");

Normally I include a switch for production and dev time.


The other thing that is not working out of the box is the RemoteServiceServlet. I looks for the gwt.rpc files at the url that the client tells it (which would be file:// something). So serialization of some object may fail because its working in gwt 1.3 mode.

To fix this you can just look locally for those files by overriding doGetSerializationPolicy like this:


@Singleton
public class PhoneGapDispatchServiceServlet extends RemoteServiceServlet implements DispatchService {

 private static final long serialVersionUID = 9114953736786309471L;
 private final Dispatch dispatch;

 private Logger logger = Logger.getLogger(getClass().getName());

 @Inject
 public PhoneGapDispatchServiceServlet(Dispatch dispatch) {
  this.dispatch = dispatch;
 }

 public Result execute(Action action) throws ActionException {
  try {
   return dispatch.execute(action);
  } catch (RuntimeException e) {
   logger.log(Level.SEVERE, "Exception while executing " + action.getClass().getName(), e);
   throw new ActionException("runtime exception occured while dispatching action");
  }
 }

 private String getBaseUrl(HttpServletRequest request) {
  if (request.getServerPort() == 80 || request.getServerPort() == 443)
   return request.getScheme() + "://" + "127.0.0.1" + request.getContextPath() + "/iphone/";
  else
   return request.getScheme() + "://" + "127.0.0.1" + ":" + request.getServerPort() + request.getContextPath() + "/iphone/";

 }

 @Override
 protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL, String strongName) {

  String baseUrl = getBaseUrl(request);
  logger.info("localUrl: " + baseUrl);

  return super.doGetSerializationPolicy(request, baseUrl, strongName);
 }

}


This is all you have to do to get GWT RPC working with phonegap apps.

Sunday, November 21, 2010

GWT PhoneGap Version 0.6

I finally found some time this weekend to update the gwt-phonegap project.

I made a new realease (Version 0.6) to fix some open issues and move to the latest version of PhoneGap (0.9.2) and GWT (2.1.0). (Changes)

As always, if you encounter any problems using gwt-phonegap feel free to contact me or use the issue tracker.

Note: If you are running on Android make sure to take a look at the getting started section, you will need to include a small Javascript into your html host page to make gwt-phonegap work.

If you are unaware what gwt-phonegap is feel free to read this blogpost.