Showing posts with label gwt. Show all posts
Showing posts with label gwt. Show all posts
Friday, June 05, 2009
Tuesday, November 04, 2008
Wednesday, October 22, 2008
AjaxWorld 2008
1.) Comet. There were a lot of talks about some form of data push from the server to the browser. Kevin Nilson did a nice job of differentiating Ajax (infinite loop of XHR polls) vs. Comet (long poll.) The folks at ICEFaces have built some nice abstractions on top of Comet. There was also a lot of interest around WebSockets, especially the work by the folks at Kaazing. A duplexed socket connection to the server sounds great on paper. I think there will be some very interesting technologies that grow around that.
2.) Don't make me learn JavaScript! There seemed to be a lot of folks advocating the "only know one language" approach to the web. In most cases that language was NOT JavaScript (even though the Jaxer guys say it can be.) Vendors liked Oracle and ICEFaces preached abstractions that shielded the developer from JavaScript. Of course the GWT folks say do everything in Java. Microsoft says use Silverlight so you can do everything in C#. Of course one of the best sessions was by Doug Crockford who told everyone to man up and learn JavaScript. I tend to agree with Crockford, even though I prefer ActionScript...
Labels:
ajax,
ajaxworld,
comet,
flash,
flex,
gwt,
icefaces,
javascript,
kaazing,
silverlight,
websockets
Friday, August 08, 2008
New developerWorks Articles: DWR and Google App Engine
Speaking of Google (that is called a segue, if you are keeping score at home) the second article is the first of a three part series on the Google App Engine. I had mentioned some of the work on this here, and now you can read all about it on developerWorks. Of course you can also check out the application developed in the series, i.e. the aggroGator and you can get its source code here.
Labels:
ajax,
developerworks,
directwebremoting,
dwr,
gae,
google app engine,
gwt
Thursday, March 13, 2008
Silverlight Stocks
This look-and-feel is all defaults. It looks like a web page! It's usually easy to spot Flex apps, but that is not as true with Silverlight. Everything works the same as with the Flex or GWT versions, except the color-coding for stocks that are up or down. I figured out how to define styles with Silverlight (more on that) but could programmatically set the style. Let's take a look at the code. First the UI code.
<UserControl x:Class="SilverStocks.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Enter Symbol "/>
<TextBox x:Name="symbol" Width="100" KeyDown="symbol_KeyDown"/>
<Button Click="Button_Click" Content="Get Info" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Company Name: "/>
<TextBlock x:Name="company"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Price: "/>
<TextBlock x:Name="price" Text="$"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Change: "/>
<TextBlock x:Name="change" Text=""/>
</StackPanel>
</StackPanel>
</UserControl>
Pretty similar to MXML, but distinctive. As with ASP.NET pages, Silverlight puts all code in a code-behind file:
public partial class Page : UserControl
{
const string url = "http://localhost:8080/Stocks/Stocks?symbol=";
public Page()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
invokeStockService();
}
private void invokeStockService()
{
string symbol = this.symbol.Text;
WebClient service = new WebClient();
service.DownloadStringCompleted += new DownloadStringCompletedEventHandler(handler);
service.DownloadStringAsync(new Uri(url + symbol));
}
private void handler(object sender, DownloadStringCompletedEventArgs args)
{
if (args.Error == null)
{
this.showInfo(args.Result);
}
}
private void showInfo(string xmlContent)
{
XDocument root = XDocument.Parse(xmlContent);
var stocks = from xml in root.Descendants("stock")
select new Stock
{
Symbol = (string) xml.Element("symbol"),
Company = (string) xml.Element("companyName"),
Price = Decimal.Parse((string)xml.Element("price")),
Change = Decimal.Parse((string)xml.Element("change"))
};
foreach (Stock stock in stocks)
{
this.company.Text = stock.Company;
this.price.Text = stock.Price.ToString();
this.change.Text = stock.Change.ToString();
}
}
private void symbol_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
this.invokeStockService();
}
}
}
Notice that I used the LINQ-XML cleverness, as advocated by Scott Gu. Most dynamic language folks will probably favor ActionScript's E4X over using this lambda-ish query language and a statically defined class. Actually I'm sure I could refactor this to not use the class at all, and just set the text fields during the query.
Finally, the other major difference between the two is the Flex framework's mx:HttpService. This component encapsulates the call to the back-end and provides dynamic binding. There is no handler code in the Flex version because of the binding. Will data source bindings and components like mx:HttpService find their way in to Silverlight?
Labels:
actionscript,
c#,
flash,
flex,
gwt,
linq,
microsoft,
ria,
silverlight
Sunday, February 24, 2008
TDD Gone Wrong
The article starts by point out how GWT enables RIA development in pure Java. That's a good thing. He then talks about some of the difficulties he's experienced trying to write unit tests for GWT widgets and concludes:
views are usually very hard to test, therefore they should know and do as little as possible ... Most of the GWT code has pretty much all the logic in widgets, so most developers using GWT extend a widget and just add some more logic. My advice is simple: don't go there.
RIAs are all about putting lots of logic in your view. Now it's not just any logic, but view logic. You see there is logic involved in creating a rich user interface and the place for that logic is the user interface. So this guy's obsession with testing has led him to the conclusion that you should dumb down your view code so you can test it. This completely defeats the purpose of using GWT. Very sad.
I think the author does bring up some valid points on unit testing GWT. If you place a huge importance on unit test coverage, then the more logical conclusion is that you should not use GWT. Don't try to dumb down the technology so that you can sleep better at night. Just pick a different technology.
Labels:
ajax,
gwt,
programming,
spring,
TDD,
unit test,
webdevelopment
Tuesday, November 13, 2007
The Network Application Pattern
The list of technologies was all over the place: PowerBuilder, Swing, and Visual Basic. The reasons for the conversions were pretty similar though: make things more easily accessible. It was much easier to say “you need InternetExplorer 5.5 or higher” to run an application, than it was to require somebody to download and install, and stay upgraded to the latest version of an application. The hardest part about these conversions was trying to reproduce all the functionality. You just could not do it, and there were always compromises that you had to work out with the clients on this.
These days I am starting to think that such compromises are unacceptable. The days of the thin client are coming to an end. At the same time, the days of the thick client are not coming back. Instead a different pattern has emerged, and it is going to win. I call it the Network Application, though other folks have different names and different takes on it. Here is what it is.
Misuse of Big Iron
To make things as accessible as possible generally meant to require as little as possible on the end user’s machine. The browser wars necessitated this as well. Inconsistencies across browsers required a least common denominator approach. The browser become a rendering device, and nothing else really.
All the computation required to determine the interface shown to a user was performed on servers. For awhile these servers were Big Iron -- look at how well SUNW did in the late 90’s. Moore’s Law caught up and lots of cheap servers replaced Big Iron, but the usage pattern remained unchanged. Programming languages flourished around this. Look at all the UI frameworks in Java, the explosion of PHP, and the emergence of Ruby on Rails.
Another Shift
I am not one of those melodramatics who look for a single event and say “this epoch caused everything to change.” Things started changing. Browsers stabilized and Moore’s Law kept moving along. Microsoft’s attempt at subverting web browsers by creating IE-only extensions, ultimately backfired on them. They created XMLHttpRequest, which ultimately allowed for exactly what the Netscape think tank had always hoped for and Microsoft always feared: web applications that were on-par with desktop applications. Well sort of...
Web applications still have a lot to be desired. As I mentioned earlier, it can be really hard to reproduce a desktop experience in a browser. There are a lot of things going on to solve that, and some of them might even work. Orthogonal to the technologies at play is the pattern of how to program applications that are as feature rich as desktop applications, but can be run from a browser with no software to download or worry about updating.
The Pattern
The key to the pattern is to stop using servers for creating user interfaces. If you like to think of UIs using the popular Model-View-Controller paradigm, the server should only be a place for Models. Your View and your Controller should be running on a client computer, not a server. Your server will probably serialize a Model to send to the client so it can use it in a view, but otherwise the boundaries should be very clear.
Why does this help with the problem of creating desktop-like applications? Because when all the view logic is located on the client, there are no limitations to the interactivity. For an example, think about infinite scrolling like you see in Yahoo Mail (I usually rip on Yahoo, so I thought this would be a nice change of pace.) If the view of the list of your emails is formed on a Yahoo server, then to scroll past the bottom means recalculating that view on a Yahoo server, even if it is to show one more email that is just past the bottom of the list. If you had to do it that way, you would not allow scrolling. You would force pagination, like GMail does. However, if you already have the code for creating that view on the client, then all you need on the client is the data to display.
Servers Are for Services
The beauty of this pattern is that your servers become specialized in serving up data, not HTML. There is still some overhead in de-serializing the request and serializing the response and making it all work over HTTP, but it’s a lot less than the alternatives. Of course it’s not a read-only world, so you’re not just sending out data. You are also receiving changes to the data, either directly, or (hopefully) via a service interface. Just because we’re getting clever with our presentation design, doesn’t mean our middle-tier design can be garbage.
Notice I used the Service word. This is the same word used by those SOA guys, and it means the same thing. There’s no reason that the clients that you build for your service (in this case user interfaces) cannot leverage the same infrastructure that clients built by other folks use. Now you may want to expose more services to the user interfaces that you built, or maybe you don’t... The point is that if you decouple the so called business logic of your system, then it is easy to build Network Applications that provide rich user interfaces to the end users of your system.
Implementations of the Pattern
Like most patterns, this was one has emerged from implementations. It is not something I dreamed up in my ivory tower in San Jose. One of my favorites is the Google Web Toolkit. GWT let’s you build things kind of like you would for the old-school thick clients using Swing, but it turns around, turns everything into code that runs on the client. One of my friends was starting to learn GWT recently and I think he was surprised when I told him that everything in GWT becomes static assets that can be served up by any web server directly. They are very cache-able assets as well... There are GWT ways to hook up your server calls as well, and of course this does require a Java application server. But that part of your code can be done in JavaScript, using GWT’s JavaScript Native Interface (JSNI.) The nice thing about using the GWT server code is that you get to use the same object model on client and server.
GWT is tied to JavaScript, and thus it inherits the limitations of JavaScript. My other favorite implementation of the pattern is Adobe Flex. Flex Builder 3 even has code generators for creating Java or PHP data services for communicating to your Flex application. Flex applications run inside the Flash player, and don’t have nearly as many limitations as JavaScript applications. Flex applications are usually much bigger than JavaScript ones, but are also very cache-able. Bandwidth is becoming less of an issue in terms of user experience, though it is still a cost issue.
The Moral of the Story
If you are a UI engineer, you should not be writing HTML. You should only be writing code that executes on the client. There are many other options out there. In the JavaScript world, there’s Dojo’s Dijit, the Yahoo UI Library, even script.aculo.us. Ruby on Rails’ RJS has some similarities to GWT, but is not there yet. The Rails guys are still perfecting the last generation of web applications, and have not moved on yet :-) Straddling the JS and non-JS worlds is OpenLaszlo. I would be more enthusiastic about Laszlo if it was using new Flash technologies. On the non-JS side, the two chief non-Flash entities are Microsoft’s Silverlight and JavaFX.
Now again, these are all technologies that can be used with this pattern. They can also be used outside of the pattern, though I would say that is probably a mistake :-)
Labels:
design patterns,
flex,
gwt,
javascript,
laszlo,
microsoft,
mvc,
webdevelopment
Friday, October 19, 2007
GWT and XForms Series, Parts 3 and 4
Continuing down that tangent... I'd like to see an ActionScript implementation of that pattern. It would be cool to take a dozen images in Flex Builder, have it create a composite, and then use that for any references to those images in your Flex application. Of course maybe it's not needed. If you knew you needed those dozen images for your app, you could just embed them all in your SWF. That's going to be even more efficient since you won't have to make the HTTP request for the composite image. Obviously there are advantages to externalizing, since you could change the composite image without recompiling your SWF and without having to worry about referencing a new version of your SWF that's not being cached by users. It also allows for localization of the images. Enough rambling on that topic for now.
Labels:
actionscript,
ajax,
developerworks,
flash,
flex,
google web toolkit,
gwt,
ibm,
xforms
Tuesday, October 09, 2007
New GWT + XForms Series
Labels:
ajax,
developerworks,
google web toolkit,
gwt,
ibm,
java,
javascript,
xforms
Friday, September 07, 2007
GWT 1.4
- Cross Platform Problems -- Hard for me to say how much things progressed. I did almost everything on my MacBook, and things had always worked well on OSX. I did do a little on Windows. I had to do a little more configuration to get it to correctly run in hosted mode than I did on OSX.
- Obfuscation -- Still a problem. Of course you can turn it off, which is good. Still, I pity the fool trying to debug GWT JS in Firebug.
- No Java 5 -- Still a problem. GWT will choke on a List
, but String[] is ok. Also, any annotations will choke it as well. So no returning @Entity classes from your RPC services. Lots of boilerplate code to write -- Still a problem. You still have to write two interfaces and one class to create an RPC service. Inserting GWT into an existing page is easier, with just a single JS file to include. Better build support needed -- This has a improved a little. The ant script that is generated is slightly more useful than the previous version. Still frustrating that there's no build script generated for creating a WAR file. You don't have to use GWT with a Java application server, but obviously a lot of people are. The RPC services require it as well. RPC is bad -- Of course that can't change! RPC is still bad. I like how in the documentation, the GWT team mentions two different design philosophies for RPC services. One is to create RPC's specifically for the web application. The other is to have general purpose ones that can be re-used by many clients. Good luck on that last one. That would mean your general purpose services can only accept and return classes from the subset of Java 1.4 that GWT supports.
So that addresses my old pain points. Not much progress has been made. There are some new good points.
Performance improvements -- Ok, they've really done a good job here. Things are snappy even on a page where you use lots of generated JS to create your UI. More Widgets -- Steady progress has been made here. You can get pretty far just using their widgets. I haven't tried out any of the commercial WYSIWYGs built for GWT, but these seem more viable and useful with more widgets. Of course, their widgets are very limited. They definitely aren't components. Compare a GWT widget to a Flex component, for example, and it's not even funny. GWT's widgets are pretty lightweight, but are low in functionality compared to similar abstractions found in similar frameworks. Image Bundles -- Very cool new feature. I like how they use CSS to get nice layout of the images from the bundle. It seems like a great way to optimize the static assets in your app. Seems like it might play tricks with a user who wants to right-click on one of your images and do save-as, but oh well. - Localization -- This has always been there, but it seems better documented and exposed now. Plus there is a command line tool for it. It's pretty nice, though I question the logic behind doing your localization in code that is going to be converted to JavaScript and executed on the client.
So all in all, GWT has made some nice improvements and added some new features. They have not addressed the things that are their most blaring weaknesses (IMO), but then again those are probably the hardest things to address. I was surprised though. From my last big write up, I got a lot of feedback from people talking about how these exact issues were being addressed, i.e. that the work was already in progress. Was that really the case?
Labels:
ajax,
google,
google web toolkit,
gwt,
ibm,
web development
Thursday, May 24, 2007
Flex Stocks Updated
- Deployable WAR -- Drop it into to your web container and go to http://
localhost:8080/Stocks - WAR Source Code -- Unzip it and import into Eclipse
- Flex Source Code -- Unzip it and (hopefully) import into Flex Builder.
I'm thinking of refactoring the original GWT app to use the exact same code as the code used here. More on that later.
Labels:
adobe,
ajax,
flash,
flex,
google web toolkit,
gwt,
java,
web development,
web service
Tuesday, May 22, 2007
Flex Stocks
It was really pretty easy to do this. Of course this was a pretty simple application. I might try to re-implement the advanced version of the Stocks application from part of the GWT tutorial. First, I'll do the easy one in Silverlight.
Labels:
adobe,
ajax,
flex,
google web toolkit,
gwt,
java,
silverlight,
web service
GWT Tutorial Part 2
Friday, May 11, 2007
GWT Tutorial on IBM
Labels:
ajax,
developerworks,
google web toolkit,
gwt,
java
Monday, April 16, 2007
Thoughts on GWT
GWT is an interesting engineering solution to a hard problem: generating standardized, cross-browser AJAX applications. What makes it unique is that it doesn't require you to understand JavaScript at all. You barely need to understand HTML even. That is really cool. But is it worthwhile?
The answer is, I don't know. It seems like a toy at times, but a really powerful toy. It's hard for me to imagine creating a real website using it, and there is really no way to even use it just for prototyping. As I understood it more though, I realized that there was a real-world workflow possible with it, and maybe that's its biggest strength.
If I were using GWT to build a real site, I would have a web designer build a complete prototype that I would check in and deploy -- as is. Ok, maybe I'd make sure that various visual components had the proper IDs or classes, since that's what GWT uses to identify and replace components. It's the replace part that is really important. The GWT runtime would replace the components created by the designer. It would replace it with JavaScript generated HTML. However, all the CSS created by the designer would be applied. So as long as the CSS was tight, then the GWT-generated component should look how the designer wanted it.
That's nice, really nice. I think having a good workflow between designers and developers is huge. Just look at what Microsoft has tried to do with Web Forms and now with XAML. Web Forms arguably inspired Java Server Faces, which is now part of the JavaEE specification. So maybe that's the real strength of GWT. Everything else is icing on the cake. That being said, here's my favorite and least favorite things about GWT.
Good Stuff
- Debugging -- Being able to debug client side code inside Eclipse (or any IDE) is really nice. I don't know how much time FireBug has saved me in debugging JavaScript. Every JS developer I know uses it. I show those guys what it's like debugging GWT code inside Eclipse and they freak out. The Visual Studio debugger is also really nice, but it's still got nothing on a Java debugger. GWT just enables a Java debugger. Of course it's only valid for hosted mode, but that's another topic.
- Unit Testing -- Ditto for writing unit tests. I know that there are initiatives for creating JavaScript unit tests, such as JsUnit. I've looked at it a little bit, and it's really clever. It still requires all your code to be deployed (of course.) Being able to run a unit test either inside your IDE or with an Ant/Maven target is really nice. Easier unit testing == more unit tests == better software.
- Nice HTML Abstractions -- Really like the FlexTable for example. It's also interesting to port layout managers to HTML. I can definitely see possible conflicts with CSS though. I'm not sure what would happen if your CSS specified a position that really conflicted with the layout algorithm. I'm sure CSS would win, I'm just not sure how bad it's going to make things look.
- RAD Tools -- Nice tools for setting up your project, etc. A lot of GWT was clearly inspired by Ruby on Rails, and this is one of the notable inspirations.
- Architecture -- Encourages UI logic being pushed to the client. Make use of the user's computer, and offload from your server.
Bad Stuff
- Cross Platform Problems -- All those RAD tools are OS dependent. In my experience they work really well on OSX, but are haphazard on Windows. I love OSX, but that's not good.
- Obfuscation -- The generated JS is dense and heavily obfuscated. Maybe that is useful for Google projects, but how is it good for the average developer? It creates a dependency. If you can't debug your client code in hosted mode, you have no chance of debugging it at all.
- No Java 5 -- It's understandable that GWT only supports a subset of Java classes when it comes time to generate JavaScript. But it's really annoying that you can't use things like the improved for loop, generics, and annotations. The annotations present a real problem if you're using Java Persistence or EJB3. An annotated entity bean cannot be passed to the UI essentially. You're forced back into a data transfer object anti-pattern.
- Lots of boilerplate code to write -- To use a remote service, you have to write a client side interface for it (not too bad), an asynchronous version of the same interface, and the actual (server side) implementation of the interface. Then you have to write some obscure looking client side code for registering the service at runtime. Doesn't this all sound familiar? Doesn't this sound like creating remote and home interfaces for an EJB and then having to use JNDI to look it up at runtime? We all know how that turned out for EJBs.
- Better build support needed -- Hosted mode is great, but it's kind of a pain going from hosted mode to a real deployment. GWT can't solve this completely obviously, but they can do more. Hosted mode lets you switch to a "live" mode where GWT creates a Tomcat directory and installs the web application to Tomcat. So clearly they understand the deployment issues, like exposing the RPC servlet endpoint in web.xml.
- RPC is bad -- Ok, I'm not quite as convinced of this as I used to be, but I think it is mostly true. RPC encourages a lot of strong coupling between server and client. However, I think the distinctions between server and client are fading anyways, so this is becoming less of an issue. You're probably going to want the services called by the client to be facades to the "real" services anyways, just because you don't want your real services to be compiled into servlets (which is what happens because you have to extend the RemoteServlet class in GWT.)
I'd like to see GWT leverage Java 5 a lot more. It needs to support generics. It should not only ignore most annotations, it should use them to eliminate the boilerplate code that developers have to write and the redundant interfaces that have to be declared.
Labels:
developerworks,
google,
google web toolkit,
gwt,
java,
javascript,
web development
Sunday, March 25, 2007
GWT, Eclipse, and JUnit -- Rants
The junitCreator seems even worse. It needs a GWT module name, but none of the artifacts created by the applicationCreator or projectCreator contain this. The .gwt.xml file has the module of course, but not it's name. It took me some trial and error to get this right. Even when I did, I could only launch my unit tests using the generated command line tools. I could launch these files directly from Eclipse, but I couldn't launch the unit tests using Eclipse. Thus I could not attach Eclipse's debugger.
I'm sure there's a way to do this. I'm sure that either I 1.)didn't use the right junitCreator command option, 2.) need to configure my project differently, or 3.) need to configure my run/debug profiles differently. Whatever this case, this is all very un-Ruby on Rails like.
Oh, one last complaint. The projectCreator has an option for generating an Ant file. That is borderline useless. The build file only builds a JAR and does not include the gwt compiler as part of the build. Guess what, if you're using gwt, you're building web applications. You don't need a JAR you need a WAR, and you need it to include all the web files, i.e. all that gwt-generated JavaScript. You need a web.xml file, which gwt knows how to generate (it creates one when you launch web mode.) WAR files have a very standardized structure, so this should not be very hard. Just package up what gets deployed to the bundled Tomcat in web mode.
Update: Strangely I don't have a lot of these same problems when I run everything on a Mac. No idea why, since even though the command line tools are platform specific and some of the runtime is platform specific, one would think that the underlying Java code that creates the projects, artifacts, etc. is pretty much the same.
Labels:
ajax,
eclipse,
google web toolkit,
gwt,
java,
junit,
ruby on rails,
web development
Wednesday, March 21, 2007
Google Web Toolkit and Firebug
I like JavaScript, and I'm not worried that saying so will cause me to take a pay-cut. I have some tools I like to use to deal with it. One is a bookmarklet I found for viewing XMLHttpRequests and responses. It works really well in Internet Explorer 7.
I was playing with my little app on IE, and decided to open up my bookmarklet to see exactly what the GWT-generated JavaScript sent to the server. What did I see? Nothing at all...
Ok, time to get serious. I switched over to Firefox, where I have every web developer's best friend, Firebug, installed. I flipped the switch on Firebug and repeated the same process. What did I see here? Again nothing. Nada.
What the heck was going on? I see the request hitting the server and the response causing the data on the page to be changed. Yet somehow these common debugging tools were oblivious to what was going on. Was there an inviso-IFrame being used? That would be so Web 1.0-ish.
I probed around with Firebug, and indeed there was a massive hidden IFrame on my page. I opened it up and saw that there was a GWT-generated HTML page that was being dumped in here. That page contained tons of JavaScript. And not just any JavaScript, but amazingly obfuscated JavaScript. Here's a sample of it:
function gX(hX,iX){hX.aX = iX;}
function jX(kX){return kX.cX;}
function lX(mX,nX){mX.cX = nX;}
function oX(pX){return pX.bX;}
function qX(rX,sX){rX.bX = sX;}
function tX(uX,vX){uX.fo(eX(vX));uX.cq(jX(vX));uX.fo(oX(vX));}
function wX(xX,yX){gX(yX,xX.jo());lX(yX,xX.Ep());qX(yX,xX.jo());}
I don't know what to say about this stuff, but it's not the point. This wacky IFrame was where all the magic happened. It's the use of this IFrame and its Skynet-like JS that allows the GWT guys to claim:
Your GWT applications automatically support IE, Firefox, Mozilla, Safari, and Opera with no browser detection or special-casing within your code in most cases.
They're not using the sexiest flavor of AJAX, they're using the lowest-common-denominator version of it.
Labels:
ajax,
firebug,
firefox,
google,
google web toolkit,
gwt,
ie7,
java,
javascript,
xmlhttprequest
Subscribe to:
Posts (Atom)