‏إظهار الرسائل ذات التسميات gwt. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات gwt. إظهار كافة الرسائل

الأحد، 11 يوليو 2010

Use a single version number for Ant and Java (bonus: GWT)

Problem: If your application has a version number, it should be accessible during run time from Java (e.g., to display it in an “About this application” dialog) and during build time from Ant (e.g. to include it in file names). The solution is as follows.

Access the version from Java

Create the following properties file src/de/hypergraphs/hyena/core/client/bundle/BuildConstants.properties and put it into the class path.

buildVersion=0.2.0

Access BuildConstants.properties as a Java resource. I usually construct the resource path relative to a Java class (a sibling of the file). That way the path to the properties file will always stay up-to-date, as long as I move the Java class with it.

Ant

Ant can read external property files as variable with the following statement.
    <property file="src/de/hypergraphs/hyena/core/client/bundle/BuildConstants.properties">

Additionally, you can insert the value of $buildVersion into a file while copying it, by using a filterset.
    <copy file="${data.dir}/index.html" todir="${version.dir}">
<filterset>
<!-- Replace @VERSION@ with the version -->
<filter token="VERSION" value="${buildVersion}">
</filterset>
</copy>

GWT

For client-side GWT, you can use constants. Then the version number is compiled directly into the JavaScript code. To do so, you add the following interface as a sibling of BuildConstants.properties.
package de.hypergraphs.hyena.core.client.bundle;

import com.google.gwt.i18n.client.Constants;

public interface BuildConstants extends Constants {
String buildVersion();
}

الأحد، 18 أبريل 2010

Speeding up GWT

I’ve recently come across a few great resources on how to speed up client-side GWT:
  • Effective GWT: Developing a complex, high-performance app with Google Web Toolkit
    Describes interesting tricks for making your application faster. One of the main challenges for them was to make everything work with IE 6. Interesting points were:
    • DeferredCommand can be used to execute code after the current invocation. Very handy in event handlers where performing complex user interface changes can lead to weird behavior, such as the “bleeding through” of return keys, etc. This may well have been the most important take-away of the talk for me (as I am currently not too concerned about performance in my projects).
    • Also cool: They describe how to go from GUI sketches on paper to a PhotoShop mock-up to a GWT implementation.
    • Generating HTML (on the client) and letting the browser parse it is fastest for generating DOM. I’m assuming that is as far as IE 6 is concerned where each created JavaScript object is very costly.
    • Foreach is slow, because an iterator (=JavaScript object) has to be created. With an integer index, this does not happen.
    • Programmatic manipulation of styles via widget.getElement().getStyle() is slow, using CSS is faster.
  • Simpler and Speedier GWT with Server Side RPC Serialization
    It is a common technique to make the first remote procedure call (RPC) directly after the page has loaded. To improve performance, one can simulate that RPC and embed the result inside the web page on the server. The previous talk mentioned this trick which lead me to investigate further and find this article.
  • Resource Bundles and Linkers in Google Web Toolkit
    This talk goes further into details how data can be served more compactly. It was linked from the previous article.

الجمعة، 2 أبريل 2010

GWT, an important Java technology: features, future and wishes

The Google Web Toolkit (GWT) has become one of the most important Java technologies, as it gives that language a credible web platform strategy. I used to be doubtful of the extra compilation step and developed with DWR and Dojo, but have since become a convert.

Cool features:
  • A single code base for client and server.
  • Great development tools, via Eclipse: refactoring, code navigation, etc. This was one of the reasons the creators of GWT chose Java as the source language. Server-side JavaScript certainly would have been a possibility, and compiling JavaScript to JavaScript is not unheard of, either.
  • Quick turn-around: after making changes, the server and client can be reloaded quickly to reflect those changes (only the first start of the client is a bit slow, subsequent reloads are fast).
  • Easy install of development tools: All you need are two Eclipse plugins and you are done.
  • IDE support: One of the Eclipse plugins helps with various coding tasks and errors (such as keeping Service and AsyncService consistent).
  • Easy deployment of applications: GWT produces a WAR file. Drop it into a servlet container such as Jetty or Tomcat. Done.
  • Fast and reliable GUI layout: Still limited compared to what Swing and SWT offer, but for the first time acceptable.
  • True client-side technology: GWT is tightly integrated into the browser environment and stays close to JavaScript. This makes it easy to keep pace with the rapid progress that browsers are making. GWT is also one of the few Java frameworks that can be used to write offline web applications, because it relies so little on the server.
Extending the basic features: For someone who has already programmed Swing or SWT, it is very easy to get started with GWT. After a while, you will probably be looking for advanced features. Luckily, a lively community has grown around GWT to fulfill this kind of need.
  • gwt-dnd: Implements Drag and Drop in pure GWT.
  • Smart GWT: GWT does currently not have too many widgets. Smart GWT is a GWT wrapper around the SmartClient JavaScript library which has lots of widgets. While GWT is really good at this kind of wrapping, there is some baggage involved: load times of web applications increase, and there is a new API to learn.
  • GWT Mosaic: Also extends GWT, but as pure GWT and with less widgets/features.
  • Other wrappers for JavaScript libraries exist. But beware, some of them have very restrictive licenses.
What the future will bring:
  • Currently, the GWT incubator hosts experimental features. Long-term, its parts will be migrated to either separate projects or the GWT core.
  • A post reveals interesting things about GWT’s future. For example, it will get data-backed widgets.
What I am missing:
  • More widgets: The current widgets are limited (menus don’t ensure that they are visible, no support for shortcuts, no resizable dialogs, no context menus, etc.) and there are not enough of them. I expect this area to improve quickly, though, now that all the important foundations have been laid (event handlers, modular CSS, layout panels).
  • Switching back-ends: Many computers are only intermittently online. Programming an offline mode for a GWT application is difficult, because the server usually hosts important functionality. A hypothetical way of solving this is by installing a back-end locally. The client could switch between this back-end and the server. Managing installed back-ends should work similar to Java Web Start. A local back-end could also provide a GWT application with desktop features, because it has access to desktop resources such as the file system.
  • Better client-side modularity: I love Eclipse’s modularity, especially when working in a team. You can have a core plugin that is extended via other plugins residing in separate projects. It would be nice if one could extend a GWT application in a similar fashion. On the server side that is possible via OSGi. On the client side, that is currently not possible.
  • Sending binary data from server to browser: For example, one cannot create images on the server and send them to the client via RPC. Data URIs are a work-around, but a poor one.
  • Annotations for hiding code from the client: If an object is transferred back and forth between client and server, there are often some server-only methods. An annotation would allow one to hide those methods. There is an issue for this feature. You can star it, if you would like to see it fixed.
  • Instantiating classes via class literals: There is no Class.newInstance() in client-side GWT. One has to resort to sending a factory to the client.
  • Two two useful methods: Class#getSimpleName(), String.format() are simple to implement, so I don’t see the reason for not doing so in client-side GWT.
  • Simpler unscrambling of GWT method names: If you want to invoke GWT code from JavaScript you need to prevent GWT from scrambling your method names. Doing this is a bit more complicated than it should be. A simpler solution would be to add an annotation to methods whose names one wants to preserve.

السبت، 20 مارس 2010

Google goodness: using GWT with Guice

The Google Web Toolkit and Guice are two very useful technologies. This post explains what they are, how they can be used together and what benefits this brings.



The Google Web Toolkit enables one of the most elegant ways of writing web applications. With version 2, it has reached a new level of ease of use: simple install, quick development turn-around, testing in an external browser, CSS-based layout that works even for complicated scenarios, etc. Guice is a lightweight dependency injection framework and helps with structuring an application. It also has one of the most elegant Java APIs around. Combining them means that Guice manages GWT’s services and server-side objects. These are the installation steps:



Step 1: Install GWT. Installing the GWT has become simple, because both the GWT SDK and the Google Plugin (with IDE support for GWT) can be installed as Eclipse plugins.



Step 2: Install Guice. Also simple. Download the JAR, drop it into the directory war/WEB-INF/lib inside the directory of your GWT project, add it to the Java build path.



Step 3: Let Guice manage all remote services, as explained in the article “Guice with GWT”. I needed aopalliance.jar in addition to the two JARs that were mentioned in the article. Unfortunately, the @RemoteServiceRelativePath is relative to the module path. The following is an example where this has been taken into consideration.

public class ServiceModule extends ServletModule {
@Override
protected void configureServlets() {
serve("/"+ServerConstants.SERVICE_PATH).with(MyServlet.class);

bind(MyService.class).to(MyServiceImpl.class);
}
}

@RemoteServiceRelativePath("../"+ServerConstants.SERVICE_PATH)
public interface MyService extends RemoteService {
//...
}
Benefits: As all services are managed by a single servlet, one just registers a new service with Guice and it becomes available to the client. No need to set up an additional servlet. To fully appreciate Guice, first learn about basic (constructor) dependency injection. Afterward, you are ready for an explanation of scopes: The Guice injector is a factory for objects. By default, it creates a new instance each time it is invoked. This can be changed by assigning scopes to classes. For example, the singleton scope means that a class is only instantiated once; if the injector is told to produce more than one instance, it will always return the same one. Each invocation of a service method is a separate HTTP request. Accordingly, classes in request scope are created freshly for each request. The injector has a binding for HttpServletRequest, and can thus inject it into an instance in request scope. A service method handles a request by asking the injector for a request-scoped instance and by invoking one of its methods. Scopes can also be used for session management, as there is a session scope. Instances are created once per session and can hold any kind of session data (who is currently logged in, etc.). No more direct fiddling with HttpSession! By requesting a Provider<MySessionScopedClass>, instances in singleton scope can access the current instance of MySessionScopedClass.



More Guice tips: If you want to extend a class Component with implementers of an interface Plugin, you can do so via multibindings. Interface Plugin is multibound to a set of classes and Component requests a Set<Plugin>. It is then free to iterate over all Plugin instances, in order to make them perform tasks or to inform them of important events. Guice also helps one with logging:

Guice has a built-in binding for java.util.logging.Logger, intended to save some boilerplate. The binding automatically sets the logger’s name to the name of the class into which the Logger is being injected. [source]


Thread safety: If you are in singleton or session scope, you need to be thread-safe. If you are in request scope or “no scope” (=created each time), you don’t. Interestingly, Crazy Bob Lee recommends:

If the object truly is stateless, it’s faster for Guice to create a new instance than it is to retrieve a singleton. If Guice creates a new instance every time, it can bypass the scoping layer entirely, not to mention the logic inside the singleton scope.
Moral: use the latter two scopes as often as possible.

الخميس، 2 يوليو 2009

What is the appeal of Ajax and GWT?

Ajax does have its detractors. Their argument goes as follows: Why reinvent everything that has already been done on the desktop on an inferior platform? I do agree that the attraction of Ajax is subjective (i.e., not based on technological arguments). This is obvious whenever I’m excited about something web-based, show it to non-developer friends and their only reaction is boredom. Then I realize that while I’m excited about what’s possible on the web, they have already seen it on the desktop. But—there are some good arguments in favor of Ajax. My reasoning goes as follows:
  • I love web applications (because I use 3 different computers having data travel with me is great).
  • I’ve always disliked Applets and Flash. With advanced browser use (tabs, drag&drop of links, etc.), anything that is not well integrated feels constricting.
  • Mobile applications: Web applications are currently the best solution if you need something that runs on the smartphone platforms Android, iPhone, Palm Pre, and Blackberry. The browsers of all of these platforms are WebKit-based, making testing less of a chore. Windows Mobile 6 is out there, too, but feels dated now, and I'm not sure how capable its browser is.
  • There is tremendous momentum behind the browser as a platform. New user interface ideas are constantly being tried out, JavaScript is getting really fast, gains lots of APIs (geolocation comes to mind), etc.
Using GWT to write Ajax applications has the following advantages:
  • Compared to desktop Java: GWT makes programming web applications almost as simple (in some cases simpler) as programming Swing. So why not use it?
  • Compared to other Ajax solutions: GWT has Java's superior tooling, one has a single code base for client and server, and GWT’s compiler produces highly optimized code (due to Java’s static nature).
[Further reading: “What should be the platform of your next application?”]

الجمعة، 26 يونيو 2009

GWT's future: 2.0 and my wishes

Programming web applications with GWT has been a revelation. Having mature tools and a single code base for client and server is great. In this blog post, we'll first look at the new features of the upcoming version 2.0 of GWT. Then I'll list a few wishes that are still unanswered by 2.0.

New features in GWT 2.0

GWT 2.0 has some incredible features in store:
  • In-browser hosted mode: see your hosted mode webapp in a real web browser. This obviates many needs for compilation. Plus both compilation and starting hosted mode will become faster.
  • Developer-guided code splitting: you tell the compiler roughly were to split to lazily load code and the compiler figures out how to package your code.
  • Better layout: the GWT team seems to have worked on better CSS-based layouts. I'll believe it when I see it, but if this works, it will fix one of the biggest Ajax problems.
Get more details about GWT 2.0 at “GWT Can Do What?! A Preview of Google Web Toolkit 2.0”.

Open wishes

Alas, a few of my wishes are still unfulfilled. I've collected them below, they are the result of my experiences while implementing Hyena. If all of these wishes were to come true, then this would make web applications true competitors to desktop applications (well, one would still have to figure out packaging and access to desktop features; Trephine is very useful here, but an even cleaner solution would be nice).
Platform
  • Server-side image generation: generate a JPG, PNG or SVG image on the server, send it to the client, display it in an image. Right now, the work-around is to use a data: URL with base-64 encoded binary data and assign it to an image. But that wastes space and does not work with SVG in a cross-browser fashion.
  • @Ignore annotation for methods: This would mark server-only methods and prevent client-side code from being generated. The current work-around is to move server-only code to static methods in a different class.
  • Swapping a server-only implementation of an interface with a client-side place holder: With custom field serializers you can control how a class is serialized but not what class is instantiated. This is a problem whenever you have a nested data structure that contains server-only implementations. I currently do my own reflection-based traversal and swap implementations to solve this problem (directed by annotations). Hardly a simple solution.
  • True dynamic loading of client-side GWT code: would be the perfect client-side complement to server-side OSGi modules. Then OSGi modules (or even just plug-in JARs) could bring their own client-side code. Currently this does not work, because GWT always compiles the reachable code of all used modules into a single monolithic "binary". The kind of code splitting that is planned for GWT 2.0 seems to be almost there, but serves a different purpose.
  • GWT API for Bespin's widget library: This widget library is completely drawn by JavaScript in the canvas tag. Sounds crazy, works really well, because JavaScript has gotten so fast.
Language
  • Full client-side regular expressions (preferably with an API that works server-side, too).
  • Non-static GWT.create(): It would be nice if class objects could be sent to the client for instantiation. Currently, the only work-around is to register serializable factories (that actually do the instantiation, statically) and send those to the client.
  • String.format(): is useful, easy to implement, and should work on the client.
  • Class.getSimpleName(): same as above.
GUI
  • Better layout: Hopefully GWT 2.0 delivers on this front. What I miss is to be able to specify “take up as little space as possible” (as opposed to * or fixed spaces). Vertical spacing is often tricky, too.
  • Better widgets: The scarcity of widgets is still one of GWT's weak spots. Mappings to JavaScript widget libraries are possible, but then one does not profit from GWT's small code size. A few widgets I'd like to see are:
    • A more flexible suggest box (that can make suggestions anywhere and has a configurable trigger character; both things are relatively easy to add to the current suggest box).
    • A tab bar where one can add widgets to the right of the tabs (right-justified).
    • A span-based HTML widget.
    • Tables: a table that can be translated back to a model (with the incubator's ScrollTable, row numbers change when sorting), a table with grouping (see SmartGwt), and a tree table.
    • More events: an OnEnterKey event for TextBox and onChange events that are fired whenever a change happens; not just when un-focusing a TextBox or TextArea.

الجمعة، 10 أبريل 2009

What should be the platform of your next application?

I'm currently thinking about the next steps for my information manager Hyena. It exists in two versions, as an Eclipse plugin and as a GWT-based web application. Having to maintain two versions is a major burden, so I've been thinking: What would would be the ideal platform on which to base one's application?

My wishes for such a platform are as follows:

  • Simple deployment: Nothing beats pure webapps in this regard. Having a webapp available everywhere is cool, too.

  • Extensibility: For larger applications, if you want someone to code new functionality, doing it as a plugin is very elegant.

  • Development tools: With inadequate tools, implementing and maintaining an application becomes much more work. It should be easy to find one's way around a platform and source code should be easy to change and navigate.


Technology-wise, times have never been better for developers. A lot of exciting stuff is available, for free:

  • Eclipse: I love its GUI (which is remarkably clean considering how much functionality it has), but am not too fond of its innards. They always felt harder to understand than necessary, slightly overengineered, and include anti-patterns that make it difficult to discover things (see “Eclipse 4 wishes: simplification first, then innovation”). I'm also not sure that the pride of amassing frameworks serves Eclipse well. This leads to design by committee, instead of a single tight overarching vision. Lastly, Eclipse seems to pin its hopes for web enabledness on RAP (or something like it). What I've seen so far of RAP did not instill confidence: It is slow, its UI awkward, and it will never work in offline mode.


  • OSGi: Very useful and powerful if you need extensible software. Still a bit complex but that will hopefully change as it finds its way into the Java language.


  • GWT: I was long very sceptical and wrote my own JavaScript, but now I am a convert, because having a single language and the power of the Java tools leads to a lot of productivity. Even though writing GUIs with GWT is almost as simple as with, say, Java Swing, one problem remains: layout. Many things that are easy in Swing or SWT are difficult or impossible in a browser.

  • DWR: Nicely done. But I've tried it (together with Dojo) and maintaining two code bases (client + server) is not much fun. Plus, JavaScript development tools are not yet at the level of the Java tooling.

  • Appcelerator: Intriguing option for turning a web application into a desktop application. I'm not sure coding the UI and the application in two different, usually not well integrated languages works. Thus, I can imagine using it with GWT or with JavaScript.

  • Trephine: Brings desktop features such as the clipboard or file system access to web applications via a small signed Java applet.


  • Bespin: Ajax application that draws its own UI via the canvas API (see picture below). Very impressive and indicative of web browsers soon being superior deployment platforms. I would also assume that by being canvas-based, rendering and UI differences between browsers are less of an issue.




So where does that leave one when writing the next application that should be web-deployable? I see the following options:



  • GWT plus


  • Running GWT on OSGi could deliver extensibility, but I'm not sure how well the client side could be extended, since GWT cannot currently dynamically instantiate classes. GWT.create() only works statically. That means that plugins cannot contribute code to the client side of a GWT application.


  • Pure JavaScript: That is client-side JavaScript and server-side JavaScript. Currently, neither language nor tools nor (non-canvas) browser-based UIs are there yet. But they probably will be eventually.

  • Applets, Flex, Silverlight: either don't integrate well with web browsers or have inadequate development tools or don't integrate well with web servers (meaning that it is useful if server and client can share data structures easily, having to define the same class and/or tool functions twice is unnecessary overhead).

Other inspiring technologies that are interesting, but not (yet) relevant for me:

  • Newspeak: Takes discoverability and clean but powerful language design to a whole new level.


  • Lively Kernel: Sun Lab's go at a pure JavaScript runtime environment. Still feels a bit strange to use and I'm not sure about their server story. But a cool project none the less.

  • Mobile webapps: When it comes to mobile devices, the predominant browser is Webkit, so it is really easy to write cross-platform applications as webapps there. Google leads the way via its mobile versions of GMail and GCal.

Am I missing something? Did I misjudge some of the technologies?



Related reading:

الثلاثاء، 6 يناير 2009

UUIDs for GWT

UUIDs are useful for many purposes, one of them is generating unique URIs for semantic web applications. Alas, under GWT, java.util.UUID is server-side only, so I looked for a client-side alternative. After some googling, I've found a nice JavaScript implementation, translated it to Java and can now use it with GWT. I'm publishing it here (with the consent of the original author), in case others find it useful.

الأحد، 21 ديسمبر 2008

The future of Ajax

GUI layout in Ajax goes like this: You are fine as long as long as you have absolute values (“this sidebar is 300 pixels wide” etc.), but when it comes to relative sizing (“I want the toolbar to be as small as possible and the content to take up the remaining space”) one is in for a world of pain. After having spent way too much time in that world recently, I wondered when web browsers are finally going to implement better layout features. After all, this problem has been largely solved (really nice layout managers for Java are JGoodies Forms and MiG Layout). Here is what I found:
  • The OpenAjax Alliance has voted on a browser wishlist that includes a lot of interesting details. This wishlist is supposed to guide browser vendors towards features that make sense for the Ajax community. Not suprisingly, layout issues rank high on that list.
  • The Future of CSS and the end of 3.0: This article is almost one and a half years old, but it still rings very true to me.
  • XUL is a Firefox-based widget toolkit that can be programmed in JavaScript. It avoids many of the Ajax CSS problems, because it has specifically been designed for applications (and not for hypertext). Firefox-only, but it should not feel alien to Ajax developers because it does not stray to far from browser technologies. While some test code for using XUL via GWT is out there, I wish there was something more usable.
Update 2008-03-16: The browser wishlist entry “Better UI Layout” links to a css-flexbox proposal that borrows layout ideas from XUL.