Java

The Next Great Language

Tagged:  

Actually, the title should be "The Next Great Mid-Level Language", but doesn't sound quite as snappy...

There has been a lot of talk in the last year or two about Java losing ground to newer languages and about which language is going to replace Java as the dominant language going into the next decade. Various factions from the Ruby and Scala camps have weighed in on the debate in earnest, leaving even some die-hard Java programmers wondering if they should be learning a new language (and soon). After all the smoke clears, what should the reasonable person conclude? Is it time to move on?

Ext GWT 1.0 Released

The Ext JS team has released version 1.0 of its SDK for developing GWT applications with the Ext JS library. Despite some controversy around Ext's licensing strategy (namely the switch from LGPL to GPL), Ext GWT is currently one of the better integrations between a Java web application framework and a JavaScript framework.

Ext GWT 1.0 has been compiled and tested against GWT 1.5 RC1. Downloads are located here.

Not a Fan of Scala? An Evolutionary Approach

Tagged:  

The Scala programming language, heralded by many of the Java cognoscenti as the language to replace Java, has garnered well-deserved praise as a sophisticated and capable language. But to many who have grown up in the tradition of C-C++-Java, Scala's hybrid imperative-functional design may be just too alien to their sensibilities. Given the history of popular programming languages, this is not a surprise. It was, after all, not Smalltalk but C++ that introduced OOP to the masses; and Java in no small way gained popularity by fixing many of the pains involved with programming in C++ while still retaining the same general style of syntax.

Now along comes a language called Fan, which takes a more evolutionary (as opposed to revolutionary) approach to language design, incorporating concepts from Java, C#, Ruby, and other languages (e.g. Erlang) into a fluid style that would be very comfortable for a programmer well-versed in any of these languages.

Here is a short list of interesting features in the Fan language:

  • Compiles to either JVM or .NET bytecode.
  • A Ruby-like syntax for using closures (with the method signature expression enclosed between two "|"). Like C#, functions are first-class citizens in Fan (represented by the Func class).
  • Fan has no concept of interface classes, but rather uses mixins for multiple inheritance. Mixins are like abstract classes in Java (i.e., they can declare concrete method implementations), but can contain no state (i.e., fields). This addresses one of the weaknesses of interfaces in Java (and C#), namely that it is very difficult to introduce new methods into the interface without breaking all of the existing implementations of this interface; this is a problem in widely-used public-facing APIs such as the Collections API in Java.
  • All threads in Fan have the ability to pass messages to other threads, i.e they use the Actor model for concurrency popularized by Erlang.
  • Fan is, generally speaking, a strongly and statically typed language. But Fan supports a special syntax for using dynamic typing with a "dynamic call operator", the "->". This operator allows you to call a method on a class without the compiler enforcing type checking. In other words, you don't have to cast a type just to call a method.
  • A unified namespace and deployment structure. The deployment unit in Fan is called the "pod". The first part of a namespace is always the deployment unit (pod), so identifying a missing class becomes much easier than the "jar hell" of Java (though arguably Maven makes this much easier).
  • Fan supports a "literal syntax" for programming with lists, maps, etc. that makes working with these common elements much easier.

More thorough documentation on the language is available here. In general, Fan does not introduce any world shaking concepts--certainly all of its elements are present in some form or another in other programming languages--but is distinguished by the fact that it makes very smart decisions about which features to use, combining them in a style that is both fluid and familiar to the average programmer.

Java The Next App Engine Language?

Tagged:  

Michael Podrazik has written an interesting post on what the next App Engine Language will be. If you don't know about App Engine it currently supports Python and you can read more about it here.

Below is an excerpt from the post.

So how reasonable would it be to offer a hosted Java environment? While almost any hosting provider currently gives you the option of running PHP, lots of 'em give you Perl, etc. virtually nobody except boutique hosting providers let you run Java. There's a good reason for this. First of all, Java is an enterprisey language and the apps that use Java on the server side are not especially well suited to run in a shared environment. Secondly, even if the market existed, there are technical limitations that make running Java in a shared resource pool problematic. While you can chroot PHP to prevent people from accessing the shared, underlying filesystem, with Java you can spawn threads and do lots of other things that make implementing resource consumption quotas problematic. The fact that you can't just run a Java program using an Apache module or through CGI, and the fact that there tends to be a mismatch in the skill sets that *nix ops people usually have and the skill set required to effectively manage a Java app just further muddies the waters.

What you would really need is a customizable JVM that let a hosting provider limit what hosted apps are allowed to do. You may be able to do this with a locked down SecurityManager, but doing the kinds of things that Google is doing with the App Engine Python implementation would be even better. Not very many people have the chops to write their own VM. Google is one of them, and oh yeah, they've already sorta done it. Twice.

GWT is interesting in that you write your applications in Java with certain elements of the API stripped out and the compiler translates your code to JavaScript. Android apps are written in Java with certain elements of the API stripped out and the compiler translate your code to run in Dalvik. Why not do something like this for App Engine and make it a trifecta?

Google is pouring a lot of resources into Java lately and in a public way. Guice is getting lots of attention lately as a Spring competitor.

You can read the full post here.

So, the post predicts that the next App Engine Language will be Java. However, it predicts that the API will be limited. I would love to hear your thoughts on this prediction, so leave your thoughts in the comments.

Live From JavaOne: Second Half

Tagged:  

After CommunityOne and the initial rush to JavaOne on Tuesday, Wednesday for me was a bit less eventful. The highlights of the day included Neal Gafter's talk on Closures and Gavin King's introduction to Web Beans. For those who have already been following the Closures proposals (and debates) for the Java language, Neal's talk didn't really contain much that was new other than concrete examples for how closures would be used in the real world (hence the title "Closures Cookbook"). Gavin's presentation was a little more interesting for me, primarily because I had not really spent that much time looking at Web Beans. Web Beans, for those who don't know, is a component model for objects in the web tier. It borrows ideas from Seam and Guice and, well, standardizes them. This has been an increasing trend in Java, and a good one: take the best of the ideas from Open Source, and move them into the standards space. But with all the new specifications being aimed at developers in this space (EJB 3.0, JSF 2.0, Servlet 3.0, etc.), I wondered a bit if there wasn't just a little specification overload happening here.

By Thursday, most attendees are starting to feel what is commonly referred to (in professional circles) as "PowerPoint fatigue". I was no exception. One session that really alleviated some of the fatigue was Martin Odersky's "Programming with Functional Objects in Scala". For those who don't know, Scala is a new programming language created by Odersky himself. Though it targets the JVM, it is a very different language than Java: functions/methods are objects which can be sub-classed (!); the language uses mixins ("traits") instead of interfaces; it is statically type-inferred; and the list goes on. The slide where Odersky showed Erlang-like actors in Scala really floored me; clearly, this was a sophisticated language.

The other fatigue reliever, "The Future of Guice", contained almost no information but was the perfect counterpoint to the rest of the conference. Bob Lee and fellow cohorts from Google (including Joshua Bloch himself, who showed up for the presentation) provided free beer, free books, off-the-cuff jokes, and generally a good time. I still have very little idea of what Guice 2.0 will be like but--what the heck--I'll read the documentation when it comes out.

As in past years, Friday is the winding-down period of the conference. The show floor is already empty, and a lot of people are thinking about other things. Nevertheless, the intrepid contention-goer can still squeeze some last nuggets of wisdom before the end, and this year I was able to do exactly that. My most practical session of the entire conference was on this day, "Automated Heap Dump Analysis" by Andreas Buchen and Krum Tsvetkov from SAP. I've spent some time doing profiling with one of the best (JProbe), but I must admit this was a pretty slick tool. For those who are interested, the SAP Memory Analyzer is open source and freely downloadable.

I ended the conference with Rod Johnson's "Spring Framework 2.5: New and Notable". Rod spent a fair amount of time on both the new @AutoWire dependency injection annotation as well as the OSGi-enablement of Spring itself. For those who have been following Guice, the first was nice but no big deal. The second (the integration of OSGi into Spring) was much more interesting given the move of many big application server vendors--WebLogic, WebSphere, Glassfish, etc.--to OSGi as the modularization and versioning platform of choice.

And, just like that, JavaOne was over. I rode up the escalator in the Moscone Center with a slight tear in my eye and a fistful of receipts for my expense report. Well, here's to next year...

Live From JavaOne

Tagged:  

I'm here at JavaOne this week in San Francisco sitting through the usual spiel of vendor pitches and technology presentations. As always, the conference is a bit of a zoo...long lines for popular presentations, lots of things going on.

YouTube Data API Changes and Player API

If you haven't heard the big news yet, the YouTube Data API has been updated and the YouTube Player APIs have been released. The APIs look very interesting with some much wanted features.

The below is the big news from the YouTube Blog.

Here's the sound byte: We now support upload, other write operations, and internationalized standard feeds. (And there was much rejoicing!) We're also introducing player APIs and a chromeless player -- a barebones player SWF that's fully customizable and controllable using the player APIs.

The Data API now allows for reading (nothing new), writing and uploading of data (the latter two are the big news). The API allows for you to do many things that can be done in YouTube, such as add comments about a video or upload videos to YouTube. Libraries for the API are available for Java and PHP (sorry Ruby developers at least for now).

You can read more about the Data API here.

The Player APIs now offer a Flash (Actionscript 2.0) API and a JavaScript API to allow more control over the player. The JavaScript API and Flash API are very similar (which makes since as they are both based on ECMA Script). The APIs have some very powerful hooks into the videos. My personal favorite hook is player.getPlayerState() which returns the state of the player. Possible values are unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).

You can read about the JavaScript API here and the Flash API here (note that the Flash API is almost exactly the same as the JavaScript API, so you will need to read both references if you are going to use the Flash API).

Perhaps Even bigger news is the release of the chromeless player. Below is an excerpt about the chromeless player from reference.

Getting Started

First off, you need a developer key. To register for one, visit the registration page.

The chromeless player consists of two SWF files. apiplayer.SWF contains the actual video playing functionality. cl.SWF is a loader SWF that loads apiplayer.SWF and exposes the player's API functions. It also provides security sandbox restrictions for the apiplayer.SWF, so loading SWFs cannot access elements inside the player directly.

The player can be controlled via two methods — by loading the SWF into another SWF (or Flash website, etc.), or by embedding it directly in an HTML page and using JavaScript to control the player. The JavaScript controls are identical to the embedded player's JavaScript API.

The URL to load the chromeless player SWF is:

http://gdata.youtube.com/apiplayer?key=DEV_KEY

Functions

The following operations are available in addition to the ones listed in the JavaScript API documentation.

loadVideoById(videoId:String, startSeconds:Number):Void
Load the specified video and starts playing the video. If startSeconds (number can be a float) is specified, the video will start from the closest keyframe to the specified time.
cueVideoById(videoId:String, startSeconds:Number):Void
Loads the specified video's thumbnail and prepares the player to play the video. The player does not request the FLV until playVideo() or seekTo() is called. startSeconds accepts a float/integer and specifies the time that the video should start playing from when playVideo() is called. If you specify startSeconds and then call seekTo(), the startSeconds is forgotten and the player plays from the time specified in the seekTo() call. When the video is cued and ready to play, the player will broadcast a video cued event (5).
setSize(width:Number, height:Number):Void
Sets the size of the chromeless player. This method should be used in favor of setting the width + height of the MovieClip directly. Note that this method does not constrain the proportions of the video player, so you will need to maintain a 4:3 aspect ratio. When embedding the player directly in HTML, the size is updated automatically to the Stage.width and Stage.height values, so there is no need to call setSize() when embedding the chromeless player directly into an HTML page. The default size of the SWF when loaded into another SWF is 320px by 240px.

You can read more about the new features at the YouTube API Blog.

I think that these new feature really make it possible to make some great mash-ups with YouTube. If you create a cool mash-up using some of the new features of the API or use the the Player APIs or use the chromeless player then I would love to hear about it (you can leave it in the comments or you can write a blog post about it using your free Ajaxonomy account.

A Teris Game in JavaFX

Tagged:  

Like many developers I got into software development because I wanted to make games. While I don't work on game development anymore I still have an interest in the development, especially as it has to do with the web. Well over at DZone's JavaLoby Jim Weaver has posted an interesting article about making a Tetris game using JavaFX. This is the first post in a series of posts that will take you through the development of the game.

Below is an excerpt from the post.

In Tetris, there are several types of tetrominoes, each having a letter that it resembles. The four buttons on the left represent four of these shapes. When you press one of these buttons, the corresponding tetromino appears at the top and begins moving down the screen. When you click the Rotate button, the tetromino rotates to the right, and the Left/Right buttons move the tetromino left and right, respectively.

The code is contained in four FX program files, and needs some refactoring already. :-) Before showing you the code in its current state, I'd like to point out a couple of helpful things:

  • As explained in the Spinning Wheel post, the Key Frame animation syntax that you see here will become much less verbose as the JavaFX Script compiler team continues to address animation.
  • JavaFX Script programs should always be designed with the UI binding to a model. In this program, the model is represented in one class named TetrisModel, located in the FX file of the same name. You may find it helpful to take a look the Creating a Compiled JavaFX Script Program with Multiple FX Source Files post to see a Hello World style program that has more than one FX file. Please notice the package statments in this Tetris program, as that influences where you need to put the source files and how you build them.
  • You can obtain the JavaFX Compiler by following the instructions in the Obtaining the OpenJFX Script Compiler post.

The Source Code (so far)

Here's the main program, named TetrisMain.fx, that declaratively expresses the UI, and starts things up:

/*
* TetrisMain.fx - The main program for a compiled JavaFX Script Tetris game
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a compiled JavaFX Script example.
*/
package tetris_ui;

import javafx.ui.*;
import javafx.ui.canvas.*;
import java.lang.System;
import tetris_model.*;

Frame {
var model =
TetrisModel {

}
var canvas:Canvas
width: 480
height: 500
title: "TetrisJFX"
background: Color.WHITE
content:
BorderPanel {
center:
canvas = Canvas {}
bottom:
FlowPanel {
content: [
Button {
text: "I"
action:
function() {
canvas.content = [];
insert
TetrisShape {
model: model
shapeType: TetrisShapeType.I
}
into canvas.content;
model.t.start();
}
},
Button {
text: "T"
action:
function() {
canvas.content = [];
insert
TetrisShape {
model: model
shapeType: TetrisShapeType.T
}
into canvas.content;
model.t.start();
}
},
Button {
text: "L"
action:
function() {
canvas.content = [];
insert
TetrisShape {
model: model
shapeType: TetrisShapeType.L
}
into canvas.content;
model.t.start();
}
},
Button {
text: "S"
action:
function() {
canvas.content = [];
insert
TetrisShape {
model: model
shapeType: TetrisShapeType.S
}
into canvas.content;
model.t.start();
}
},
Button {
text: "Rotate"
action:
function() {
model.rotate90();
}
},
Button {
text: "Left"
action:
function() {
model.moveLeft();
}
},
Button {
text: "Right"
action:
function() {
model.moveRight();
}
}
]
}
}
visible: true
onClose:
function():Void {
System.exit(0);
}
}

 

I made the TetrisShape class a custom graphical component. Therefore, it is a subclass of the CompositeNode class, and overrides the composeNode function:

/*
* TetrisShape.fx - A Tetris piece, configurable to the
* different shape types. They are:
* I, J, L, O, S, T, and Z
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a compiled JavaFX Script example.
*
*/
package tetris_ui;

import javafx.ui.*;
import javafx.ui.canvas.*;
import java.awt.Point;
import java.lang.System;
import tetris_model.*;

class TetrisShape extends CompositeNode {
private static attribute squareOutlineColor = Color.BLACK;
private static attribute squareOutlineWidth = 2;
private attribute squareColor;

public attribute model:TetrisModel;
public attribute shapeType:TetrisShapeType on replace {
if (shapeType == TetrisShapeType.I) {
squareLocs = [];
insert new Point(0, model.SQUARE_SIZE * 1) into squareLocs;
insert new Point(0, 0) into squareLocs;
insert new Point(0, model.SQUARE_SIZE * 2) into squareLocs;
insert new Point(0, model.SQUARE_SIZE * 3) into squareLocs;
squareColor = Color.RED;
}
else if (shapeType == TetrisShapeType.T) {
squareLocs = [];
insert new Point(model.SQUARE_SIZE * 1, 0) into squareLocs;
insert new Point(0, 0) into squareLocs;
insert new Point(model.SQUARE_SIZE * 2, 0) into squareLocs;
insert new Point(model.SQUARE_SIZE * 1, model.SQUARE_SIZE * 1) into squareLocs;
squareColor = Color.GREEN;
}
else if (shapeType == TetrisShapeType.L) {
squareLocs = [];
insert new Point(0, model.SQUARE_SIZE * 1) into squareLocs;
insert new Point(0, 0) into squareLocs;
insert new Point(0, model.SQUARE_SIZE * 2) into squareLocs;
insert new Point(model.SQUARE_SIZE * 1, model.SQUARE_SIZE * 2) into squareLocs;
squareColor = Color.MAGENTA;
}
else if (shapeType == TetrisShapeType.S) {
squareLocs = [];
insert new Point(model.SQUARE_SIZE * 1, 0) into squareLocs;
insert new Point(model.SQUARE_SIZE * 2, 0) into squareLocs;
insert new Point(0, model.SQUARE_SIZE * 1) into squareLocs;
insert new Point(model.SQUARE_SIZE * 1, model.SQUARE_SIZE * 1) into squareLocs;
squareColor = Color.CYAN;
}
}

private attribute squareLocs:Point[];

public function composeNode():Node {
return
Group {
transform: bind [
Translate.translate(model.SQUARE_SIZE * model.tetrominoHorzPos,
(model.a / model.SQUARE_SIZE).intValue() * model.SQUARE_SIZE),
Rotate.rotate(model.tetrominoAngle,
squareLocs[0].x + model.SQUARE_SIZE / 2,
squareLocs[0].y + model.SQUARE_SIZE / 2)
]
content: [
for (squareLoc in squareLocs) {
Rect {
x: bind squareLoc.x
y: bind squareLoc.y
width: bind model.SQUARE_SIZE
height: bind model.SQUARE_SIZE
fill: bind squareColor
stroke: squareOutlineColor
strokeWidth: squareOutlineWidth
}
}
]
};
}
}

 

The TetrisShapeType class defines the tetromino types:

/*
* TetrisShapeType.fx - A Tetris shape type, which are
* I, J, L, O, S, T, and Z
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a compiled JavaFX Script example.
*
*/
package tetris_ui;

import javafx.ui.*;

class TetrisShapeType {
public attribute id: Integer;
public attribute name: String;

public static attribute O =
TetrisShapeType {id: 0, name: "O"};
public static attribute I =
TetrisShapeType {id: 1, name: "I"};
public static attribute T =
TetrisShapeType {id: 2, name: "T"};
public static attribute L =
TetrisShapeType {id: 3, name: "L"};
public static attribute S =
TetrisShapeType {id: 4, name: "S"};
}

 

And finally, here's a model class, named TetrisModel:

/*
* TetrisModel.fx - The model behind the Tetris UI
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
* to serve as a compiled JavaFX Script example.
*
*/
package tetris_model;

import javafx.ui.animation.*;
import java.lang.System;
import com.sun.javafx.runtime.PointerFactory;

public class TetrisModel {
public static attribute SQUARE_SIZE = 20;

public attribute a:Integer;
private attribute pf = PointerFactory {};
private attribute bpa = bind pf.make(a);
private attribute pa = bpa.unwrap();
private attribute interpolate = NumberValue.LINEAR;
public attribute t =
Timeline {
keyFrames: [
KeyFrame {
keyTime: 0s;
keyValues:
NumberValue {
target: pa;
value: 0;
interpolate: bind interpolate
}
},
KeyFrame {
keyTime: 20s;
keyValues:
NumberValue {
target: pa;
value: 370
interpolate: bind interpolate
}
}
]
};
public attribute tetrominoAngle:Number;
public attribute tetrominoHorzPos:Number = 10;

public function rotate90():Void {
(tetrominoAngle += 90) % 360;
}

public function moveLeft():Void {
if (tetrominoHorzPos > 0) {
tetrominoHorzPos--;
}
}

public function moveRight():Void {
if (tetrominoHorzPos < 20) { //TODO:Replace 10 with a calculated number
tetrominoHorzPos++;
}
}
}

 

You can read the full post here.

This use of JavaFX is very interesting, I'm looking forward to reading Jim's next post.

Java Wish List

Tagged:  

After reading Alex Miller's predictions for what features will make it into Java 7, I couldn't help but think of my own wish list of improvements to Java (version 7 and beyond). These range from weigh-ins on the major topics of the day to minor improvements in Java's usability. Drum roll please...

1. Reification of generics. Yes, I am beating a dead horse here (it's easier when they don't talk back), but erasure sucks. Unfortunately, I think Alex is probably right when he states that reification of generics won't make it into Java 7, which means it probably won't go into any future version of Java either. Neal Gafter's explanation probably best sums it up as to why reification cannot happen while preserving compatibility. What to do? C# took the better approach to introducing generics: introduce new reified generic classes while deprecating the older non-generic ones. It is probably too late for Java to take the same approach. Quite frankly, I think that the compatibility requirement for generics in Java is far too stringent. Yes, compatibility is important, but not at the cost of the integrity of the language. Can't we admit we made a mistake and change this?

2. Improve generics verbosity. The introduction of generic type parameters, especially bounded types, makes type definitions horribly verbose. Take a look at the following example:

Map<? extends Node, ? extends Collection> map = ...;

Ouch. It would be nicer if the programmer could express bounded types in a more concise way. This might be, to borrow from C# or Scala, the use of a colon (:) to replace the extends keyword (super could use a double-colon, ::). We can now write,

Map<?:Node, ?:Collection> map = ...;

which is much better (or at least as good as it can get).

3. A more intuitive (and explicit) syntax for returns in BGGA closures. Yes, BGGA hasn't made it into the Java language (yet), but the political momentum seems to be in its favor. I dislike the use of return to mean "return from the enclosing method", as well as the use of no-semicolon expressions as kind of implicit returns. While the introduction of pure expressions may be more consistent at the compiler level (language grammar), at the syntax level it's awkward, potentially confusing, and inconsistent with Java's existing control contructs. Use of a statement form for non-local and local returns (e.g. return super and return) would be much more intuitive, though explicit non-local return syntax would be unusable outside of a closure (which complicates the life of the compiler programmer, but better him than the hordes of junior Java programmers). I'm not sure I grok Neal Gafter's explanation of why use of an expression (sans semicolon)--which is already illegal in normal Java syntax and has no meaning outside of a closure--is better than an explicit return statement. Java already has rules as to where certain keywords can be used, and the creation of closure constructs will mandate special syntax anyway.

IMHO, the simplicity of reading and writing a language trumps other concerns by a wide margin; in this view, syntactical consistency is paramount. BGGA in its current form doesn't meet this criteria. Perhaps it would just be easier if non-local returns were disallowed entirely...? I'd like to see a compelling use case for including them, at the very least.

4. Single, unified deployment mechanism for Java programs/libraries. Java has EARs, WARs, JARs, and so on. Some projects/products even include their own (e.g., SARs and MARs in Axis 2.0). It would be really nice to have a single packaging mechanism for deploying all Java programs, with appropriate variations for web applications, services, etc. Though Java modules are only intended to replace JARs, what I'd like to see is some final (and more comprehensive) form of JSR-277 (or JSR-277 integrated with OSGi) eventually replace all existing packaging formats.

5. Convention over configuration. In addition to a unified deployment mechanism, it would be nice if Java stole a few good ideas from Ruby on Rails (RoR). One of these ideas is "convention over configuration", a term coined to express the idea that one should only have to configure something if it deviates from a simple, well-defined convention. Java already has a nice example of this called the JavaBeans API. This approach could be extended to other areas of Java, especially in the way that deployment archives locate and handle various metadata files: XML Schema, WSDL, properties files, etc. There are some existing conventions regarding metadata files in Java, but they are scattered across different specifications and (in some cases) not consistently adhered to; centralization of these conventions in a specification like JSR-277 would be a good thing, as would some automatic mechanism for discovering these files without the need for system properties or other configuration.

Well, that concludes the Java Wish List, for now at least. Feel free to add your own ideas to the mix in the comments or even dispute (!) mine. Remember, not all good ideas in the Java world need to be in the form of a JSR with the attendant expert group. Let your voice be heard.

Accessing JSON Web Services with the Google Web Toolkit

Over at GWT Site they have written a good post about using the Google Web Toolkit with JSON Web Services. Since JSON is fast becoming a standard for web services that are cross domain and GWT is a heavily used development tool this is a useful post.

below is an excerpt from the post.

The main difficulty when trying to talk to some web service on another server is getting past your web browser’s Same-Origin Policy. This basically says that you may only make calls to the same domain as the page you are on. This is good for security reasons, but inconvenient for you as a developer as it eliminates the use of GWT’s HTTP library functions to achieve what we want to do. One way to get around this is to call a web service through a javascript <script> tag which bypasses this problem. In his book, Google Web Toolkit Applications, Ryan Dewsbury actually explains this technique in more detail and provides a class called JSONRequest which handles all the hard work for us. JSON is one of the more popular data formats, so most web services support it. Lets leverage Ryan’s code and take a quick look at how it works.

public class JSONRequest {
  public static void get(String url, JSONRequestHandler handler) {
    String callbackName = "JSONCallback"+handler.hashCode();
    get( url+callbackName, callbackName, handler );
  }	
  public static void get(String url, String callbackName, JSONRequestHandler handler ) {
    createCallbackFunction( handler, callbackName );
    addScript(url);
  }
  public static native void addScript(String url) /*-{
    var scr = document.createElement("script");
    scr.setAttribute("language", "JavaScript");
    scr.setAttribute("src", url);
    document.getElementsByTagName("body")[0].appendChild(scr);
  }-*/;
  private native static void createCallbackFunction( JSONRequestHandler obj, String callbackName)/*-{
    tmpcallback = function(j) {
      obj.@com.gwtsite.client.util.JSONRequestHandler::onRequestComplete(Lcom/google/gwt/core/client/JavaScriptObject;)(j);
    };
    eval( "window." + callbackName + "=tmpcallback" );
  }-*/;
}

To make our request we call the get method with the web service url, and an implementation of the JSONRequestHandler interface. This interface has one method called onRequestComplete(String json). This is where you’ll handle the JSON formatted data once it comes back from the server. When calling a service from within a script tag, we need to specify the name of a callback function in the request. Most services let you specify the name yourself, so the first get method generates a callback name for you. The createCallback method is a JSNI method that simply calls your JSONRequestHandler implementation when the call returns via the callback name. Note, if you use this class, to make sure and change the package name for the JSONRequestHandler call to the correct location. Finally, the get method will call the addScript function which is responsible for embedding the <script> tag on your page and setting its src attribute to the web service url.

You can read the full post here.

Since I am a fan of both JSON and GWT I enjoy seeing good posts about using these two technologies. I recommend this post for any Java developer that wants to make Ajax applications using Web Services.

Syndicate content