السبت، 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.

You have been coding too much in Eclipse if...

You have been coding too much in Eclipse if:

  • you are typing Control-1 to make the red underline from a spell checker go away.


  • you are typing Control-Shift-O to expunge deleted emails from your inbox.

(I did both today.)

الجمعة، 12 مارس 2010

File system storage and servlets

One of the blessings of the JVM is that there are many “pure” databases available for it; Sesame (RDF) and Apache Derby (relational) come to mind. Alas, these databases need to save their files somewhere. This becomes a challenge with Servlets: Where should one put these files? Pre-packaged, read-only, files usually reside in SERVER/webapps/app/WEB-INF/, but mutable files? Putting them in WEB-INF makes upgrading a web application more difficult. I can easily imagine myself accidentally removing such data during an upgrade. The best solution, that I was able to come up with, is:

  • By default, the data directory of a web application “app” is SERVER/webapps/app.data/WEB-INF/ (WEB-INF is necessary to protect against serving secret files).

  • This can optionally be configured via a file SERVER/webapps/app.properties. There, one can specify the servlet data directory via a relative or an absolute path. The former case is useful if you want this directory to be a sibling of SERVER/webapps. The latter case is useful for putting this directory anywhere on a system.

I do realize that there are security issues with this scheme: While it worked for me on Tomcat, I would expect other servlet containers to prevent servlets from writing files in this manner. Other options are:

  • Make the data directory a servlet parameter in web.xml: Complicates upgrades.

  • Specify a directory via the Java preference API: Prevents installing the same web application multiple times on the same system.

  • Storing the data in a temporary (as in File.createTempFile()) directory: Not a solution for long-term persistence.


Are there other solutions out there? Let us know in the comments.



Update 2010-12-14: One of the comments already mentioned this solution: I finally opted for storing files in the home directory. In Windows, the home directory is rarely directly accessed, while under Unix you can hide your web-application-specific directory by prefixing its name with a dot. So this solution works out well in both cases and fulfills all of the above requirements.

الثلاثاء، 9 مارس 2010

Collecting only those BibTeX entries that are used in a document

Scenario: You have a large single file with all your BibTeX entries. This is convenient while writing, say, a paper, because everything is immediately available. After you are finished, it becomes a problem, though, because when you send the sources to someone else, you always have to send the complete BibTeX database with them. I’ve found two solutions for extracting only those BibTeX entries that one has actually used from a database:

  • RefTeX (comes with Emacs): Invoke “Ref -> Global Actions -> Create BibTeX File”. RefTeX continues to amaze me, it has many useful features for managing references, tables of contents, etc.


  • Bibtool (available e.g. via MacPorts)