• Home
  • About
  • GWT Dependency Injection recipes using GIN (III)

    June 20th, 2011

    This is the third part of a series about Dependency Injection in Google Web Toolkit using GIN. If you have not yet read the first and second parts, you maybe should do it before reading this third and last article.

    In this article, we will introduce two GIN features: “constants binding” and “static injection”.
    To do this with an example, let’s refactor the “serve button” in the “Simulator” main class of the second part into an own class:

    
    ...
            final Button button = new Button("Serve!");
            button.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    button.setVisible(false);
                    injector.getRacket().serve();
                }
            });
    ...
    

    Here the new extracted “ServeView” class:

    
    public class ServeView extends Button {
        @Inject
        public ServeView(final Racket racket, @Named("ServeText") String serveText) {
            super(serveText);
            addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    setVisible(false);
                    racket.serve();
                }
            });
        }
    }
    

    As you can see, the constructor of this new class is annotated with the “@Inject” annotation and receives two parameters. One of them is the racket and the other is the button’s label. In the case of the racket, it is already defined as an injectable dependency in the injector interface and in the case of the button’s label, it should be a configurable constant.
    GIN, by mean of “constants binding”, performs the binding of injectable dependencies to constants.
    Because the type of the “serveText” is String, we need to be more specific here and therefore we have annotated this dependency with the “@Named” annotation. To configure the constant value to bind to, we need to add the following line into our “InjectorModule” class:

    
    ...
            bindConstant().annotatedWith(named("ServeText")).to("Serve!");
    ...
    

    To let the other constants in the application be configured in the same way and to introduce the last GIN feature (“static injection”), let’s now modify the “Simulator” main class as follows:

    
    public class Simulator implements EntryPoint {
        @Inject
        static ServeView SERVE_VIEW;
    
        @Inject
        static AssistedInjectionFactory FACTORY;
    
        @Inject
        @Named("PingText")
        static String PING_TEXT;
    
        @Inject
        @Named("PongText")
        static String PONG_TEXT;
    
        public void onModuleLoad() {
            initInjection();
            RootPanel.get("buttonSlot").add(SERVE_VIEW);
            RootPanel.get("pingSlot").add(FACTORY.createPingPongView(PING_TEXT, PingEvent.class));
            RootPanel.get("pongSlot").add(FACTORY.createPingPongView(PONG_TEXT, PongEvent.class));
        }
    
        private void initInjection() {
            GWT.create(Injector.class);
        }
    }
    

    And our “InjectorModule” like this:

    
    public class InjectorModule extends AbstractGinModule {
        @Override
        protected void configure() {
            bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
    
            install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
    
            bindConstant().annotatedWith(named("PingText")).to("Ping");
            bindConstant().annotatedWith(named("PongText")).to("Pong");
            bindConstant().annotatedWith(named("ServeText")).to("Serve!");
    
            requestStaticInjection(Simulator.class);
        }
    }
    

    The “static injection” allows us to inject the static fields of a class. This happens by mean of the method “requestStaticInjection” of the GIN module class and, in our application, we use it to inject the static dependencies of the “Simulator” class.

    This way, even when the “Simulator” class does not participate in the dependency injection context, its static members will be injected making the explicit references to the injector not required.

    This has the side-effect of making the “Injector” getters no more necessary leaving our injector interface “empty”:

    
    @GinModules(InjectorModule.class)
    public interface Injector extends Ginjector {
    }
    

    Please note that, in order to get the dependency injection context configured and initialized, it is required to instantiate the “Injector” interface by mean of the “GWT.create()” method as part of the application initialization. This is done in our case within the “initInjection” method in the “Simulator” main class.

    Conclusions

    If you have read the 3 articles of this series, maybe you can remember how our demo application looked like at the beginning. While the functionality and appearance has not changed at all, the intern structure of the application is completely different.

    In my opinion, dependency injection allows a much cleaner structure, enables configuring the application in an elegant and easy way and, when used together with an event bus, produces low-coupled high-modular applications.

    Of course, “there is no free lunch” and using GIN means also that the development team has to learn new concepts and introduce a new framework in the application. Anyway, dependency injection is an already proven concept and GIN is being intensively used in most of the new GWT projects and GWT frameworks.

    While some minimal application structure optimizations could still be applied to the application, the thing that I still find improvable in it is the verbosity of the GWT events definitions. This requires writing some boilerplate classes to ensure the type safety (event handlers), and also the definition of the own event classes is too verbose, being possible to generate them automatically in most of the cases by using either GWT’s deferred binding or a JDK 6 annotation processor. If you know how the events in CDI are defined, very probably you will agree with me that such an approach would be much more elegant and concise.

    A solution for that, even when it requires dependency injection, is more related to other topics and therefore a subject for a different thread. If you got curious, stay tuned for a future post on code generation in GWT! :)

    The source code of the application can be downloaded here. To see the application working, unzip the file, change to the folder where the Maven pom file is stored and type the command: “mvn clean gwt:run”. After the GWT “Development mode” application starts, click on the “Launch Default Browser” button.

    As always, I hope that you enjoyed reading this series of articles as much as I did writing it and hope to see you soon in a future post!


    GWT Dependency Injection recipes using GIN (II)

    June 14th, 2011

    This is the second part of a series about Dependency Injection in Google Web Toolkit using GIN. If you have not yet read the first part, there we explained how to integrate GIN in an existing GWT sample application. In this second part, we will continue enhancing the sample application while explaining other types of injection supported by GIN.

    Encapsulating the event bus

    In the first part of this series, we configured the GWT event bus used in the original application to be injected in some of the application elements. Using an event bus is a “best practice” that helps communicating the different components in the application while keeping a low coupling between them. The point here was to show how to declare and configure a first dependency using the “injector” and the “module”. Because the class “SimpleEventBus” is provided by GWT, it was not possible to annotate the code of the class with “@Singleton” to set the “injection scope”. Instead, we use the Java DSL provided by GIN.
    In order to see how to do the same with annotations, let’s use now an application class (instead of a framework class) where we can use the annotations.
    As you probably noticed, we are using the event bus to emulate the “ping-pong” strokes. Instead of such a technical artifact, let’s create a “racket”:

    
    @Singleton
    public class Racket {
        private final EventBus fEventBus;
    
        private GwtEvent<?> fLastEvent;
    
        @Inject
        public Racket(EventBus eventBus) {
            fEventBus = eventBus;
        }
    
        public void serve() {
            fLastEvent = null;
            hit();
        }
    
        public void hit() {
            fEventBus.fireEvent(getNextEvent());
        }
    
        private GwtEvent<?> getNextEvent() {
            if (fLastEvent == null || fLastEvent instanceof PongEvent) {
                fLastEvent = new PingEvent();
            } else {
                fLastEvent = new PongEvent();
            }
            return fLastEvent;
        }
    
        public void onStroke(Class<?> pingPongEvent, final Command command) {
            if (pingPongEvent == PingEvent.class) {
                fEventBus.addHandler(PingEvent.TYPE, new PingEventHandler() {
                    public void onEvent(PingEvent event) {
                        command.execute();
                    }
                });
            } else {
                fEventBus.addHandler(PongEvent.TYPE, new PongEventHandler() {
                    public void onEvent(PongEvent event) {
                        command.execute();
                    }
                });
            }
        }
    }
    

    As you can see at the code, our class is annotated with “@Singleton” to indicate the injection scope and “@Inject” to get the event bus injected in the constructor. The class is a more adequate wrapper for the event handling and offers three methods: “serve”, “hit()” and “onStroke()”.
    To configure the injection please adjust the “injector” class like this:
    
    @GinModules(InjectorModule.class)
    public interface Injector extends Ginjector {
        public static final Injector INSTANCE = GWT.create(Injector.class);
    
        public Racket getRacket();
    
        public PingView getPingView();
    
        public PongView getPongView();
    }
    

    This time, we only need to declare the dependency in the “Injector” interface (the method will be invoked from the “Simulator” class) but no additional configuration is required and therefore no changes should be made in the “InjectorModule” class.
    Because now the event bus will not be directly accessed from the “Simulator” class, we have removed it from the “Injector” interface. But, let’s see the rest of the code changes:
    
    public class PingView extends Label {
        @Inject
        public PingView(final Racket racket) {
            racket.onStroke(PongEvent.class, new Command() {
                public void execute() {
                    setText("Pong");
    
                    new Timer() {
                        public void run() {
                            setText("");
                            racket.hit();
                        }
                    }.schedule(1000);
                }
            });
        }
    }
    

    The “PongView” class is almost identical and will not be shown here.
    
    public class Simulator implements EntryPoint {
        public void onModuleLoad() {
            final Injector injector = Injector.INSTANCE;
            RootPanel.get("pingSlot").add(injector.getPingView());
            RootPanel.get("pongSlot").add(injector.getPongView());
    
            final Button button = new Button("Serve!");
            button.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    button.setVisible(false);
                    injector.getRacket().serve();
                }
            });
            RootPanel.get("buttonSlot").add(button);
        }
    }
    

    Recapitulating what we have seen so far:

    • GIN allows to define “injectors” by mean of interfaces (“Injector” interface) that can be configured using one or more “modules” each (“InjectorModule” class).
    • If we need to configure an injection aspect we can use annotations in the class code or the Java DSL in the module.
    • In at least one point of the application we will need to access the “injector” to retrieve a top-level injected object (ex: “Racket”, “PingView”, “PongView” ). For these objects to be accessible through the injector, we need to declare them in the “injector” interface.
    • Any other dependency that is declared to be injected (annotated with @Inject) will be resolved by GIN using the algorithm described in the first part of this series and does not need to be declared in the “injector” interface (ex: “EventBus”).

    If you are familiar with GUICE, you probably already know other ways of configuring dependencies and injection. Let’s see in the next point how to avoid the repetition in the views by using “assisted injection”.

    Using assisted injection to avoid code repetition

    One of the main applications of dependency injection is to avoid coding factory classes and singletons and also centralizing the application’s configuration values. This is a very powerful tool to configure application-wide objects like services, which typically are either “singletons” or “prototypes” and scarce.

    When working with data, persistency tools like JPA assist us with the task of generating Java objects for our numerous domain model entities. These objects have normally no behavior or just a little which is typically coded in the “entity” classes. But, what happens if we want to inject our services in some of these entities to have a richer domain model? Normally, we have to tackle this task ourselves and inject the services by hand. This happens because such objects do not by default participate in the injection context (unless we are using JEE or weaving).

    While this not a difficult task, it is a purely programmatic one and breaks one of the principles of dependency injection: declarative dependencies definition.
    In GUICE (and therefore in GIN) there is a concept called “assisted injection” that helps us to create objects which require dependencies from the injection context but also instance specific property values. Basically, it consists of using a factory interface with methods to instantiate the objects as managed beans (injected objects) receiving each method only the object’s specific properties as parameters. The object constructors receive of course not only the object properties but also the dependencies who should be retrieved from the dependency injection context.

    Because an image is worth a thousand words, let’s see this with an example. What we would like to achieve here is to have only one view class (“PingPongView”) instead of two specific ones that have almost the same code. If we inspect both view classes, the differences are: to which event each reacts and which text each shows. If we refactor these values as constructor parameters, we have the following resulting class:

    
    public class PingPongView extends Label {
        @Inject
        public PingPongView(final Racket racket, @Assisted final String text, @Assisted Class<? extends GwtEvent> eventClass) {
            racket.onStroke(eventClass, new Command() {
                public void execute() {
                    setText(text);
    
                    new Timer() {
                        public void run() {
                            setText("");
                            racket.hit();
                        }
                    }.schedule(1000);
                }
            });
        }
    }
    

    Probably you already noticed the @Assisted annotation in the new extracted parameters. It just indicates GIN that the non-annotated parameters should be resolved as dependencies and that the annotated ones should be provided though parameters in a factory method of the assisted injection factory:
    
    public interface AssistedInjectionFactory {
        public PingPongView createPingPongView(String text, Class<? extends GwtEvent> eventClass);
    }
    

    To install this factory in our dependency injection context we need to modify our GIN module class like this:
    
    public class InjectorModule extends AbstractGinModule {
        @Override
        protected void configure() {
            bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
    
            install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
        }
    }
    

    And in the injector class, we have to expose the factory as any other dependency:
    
    @GinModules(InjectorModule.class)
    public interface Injector extends Ginjector {
        public static final Injector INSTANCE = GWT.create(Injector.class);
    
        public Racket getRacket();
        public AssistedInjectionFactory getFactory();
    }
    

    And last but not least, let’s use the assisted injection in our application:
    
    ...
        public void onModuleLoad() {
            final Injector injector = Injector.INSTANCE;
            final AssistedInjectionFactory factory = injector.getFactory();
            RootPanel.get("pingSlot").add(factory.createPingPongView("Ping", PingEvent.class));
            RootPanel.get("pongSlot").add(factory.createPingPongView("Pong", PongEvent.class));
    ...
    

    In this article, we have applied new dependency injection recipes to our GWT demo application. I hope that they can help you give a better structure to your GWT applications and also learn dependency injection features and its “best practices”.

    The source code of the application can be downloaded here. To see the application working, unzip the file, change to the folder where the Maven pom file is stored and type the command: “mvn clean gwt:run”. After the GWT “Development mode” application starts, click on the “Launch Default Browser” button.

    The other parts of this series can be found here and here.

    I hope that you enjoyed reading this article as much as I did writing it.
    See you soon!


    Hackergarten at Canoo 27.05.2011

    May 26th, 2011

    Don’t forget! Tomorrow night is Hackergarten.

    On the last Friday of the month Canoo opens our doors for an open source programming group called Hackergarten. Our goal is to contribute in some way to open source software, to meet new friends, and to generally have a good time. In the past we have made contributions to Groovy, Gradle, NetBeans, Griffon, GPars… and the list goes on and on. Canoo provides food, drinks, and wifi. Please note, there is a Hackergarten tomorrow! If you’re coming tomorrow then please let me know because I am cooking American hamburgers for everyone and need to know how much food to buy. To learn more about Hackergarten you can see our main site at http://hackergarten.net/ or join the low-volume mailing list at http://groups.google.com/group/hackergarten.

    This month we have an open topic. There is always interest in hacking on Gradle and other Groovy technologies, and contributing to IntelliJ IDEA was also proposed. The topic can be anything you’d like… so please just show up with ideas. As always, Canoo provides food and drink, and the party starts at 5 PM. We are grilling hamburgers tomorrow, so if you’d like one please respond to the active mailing list thread.

    I hope to see you tomorrow night!


    Git training at Canoo with Matthew McCullough

    May 6th, 2011

    Yesterday I was lucky to attend an excellent git training at Canoo headquarters in Basel. Matthew McCullough of Ambient Ideas, Denver USA was invited by Canoo to share his expert Git knowledge with the people of Basel and nearby. Matthew is a first class trainer, speaking about Git at many conferences and also providing the online git training (https://github.com/training/online).

    The training was open to everyone and very well attended, probably because it was very affordable. Over the one-day workshop “fast-forward” became a new meaning to me. Starting at the very beginning, such as where to get, install and host git repositories, Matthew quickly passed over all the base concepts and commands including comprehensive exercises. The workshop was rounded off by more advanced concepts like how to handle your revision graph in every imaginable way, including highlights like “fast-forward” and “octopus” merges, “cherry-picking“, “rebasing” and “bisecting“. The hours flew by and over the full day Matthew never lowered his fast pace not in the slightest.

    Before attending the training my perception of git was merely of “yet another version control system, but distributed”, but this changed significantly afterwards. Now I believe the distributed nature of Git is not the most important aspect. Git’s value derives from its most fundamental concept: make the handling of branches easy and treat all branches equally. This opens up the door for a much more fine grained revision management, having branches literally for single features or experiments. Treating branches equally opens up the door for distribution on a larger scale …

    Liberating branching wouldn’t work if you didn’t have tools to bring back together you and your colleagues’ work. This is another aspect where git excels and impresses. Similarity detection, multi-branch merges and rebasing techniques, together with sophisticated revision graph inspection tools, help you with this normally non-trivial task. As an interesting side aspect Matthew also talked about the design principals behind git, which are very cunning. Git actually tracks content, not files and is designed to be very reliable and fast.

    If possible I’ll switch to git for my next software projects. Thank you Matthew for the excellent training and multiple insights.

    Matthew can be reached at twitter: @matthewmccull and maintains a blog under: http://ambientideas.com/blog/. He is the author of a huge amount of git tutorials, documentation and related links: http://bit.ly/gitlinks.

    As a suggestion to programmers: if you want to have a famous speaker at your office then just send them an email and ask. At a minimum they will be thankful; at best they will come and speak at your office! That’s what we did, and the result was great.

    Did you not know that Canoo was offering a Git training? Canoo is offering a lot of free (or very affordable) public events. Basel does not have a permanent Java User Group, but we hold “Reading Groups” every few months. The best way to be kept informed is to follow @Canoo on Twitter or send an email to info@canoo.com. Also, we host Hackergarten (http://www.hackergarten.net) every month, which is your chance to come and hack on open source software with some great friends. We have pizza and drinks on a Friday and then try to make a patch or contribution to an open source project. Our goal is to make Basel a great technology community. Care to help us make it so?


    Command Line Usage for Diff Viewer from IntelliJ IDEA, RubyMine, and PyCharm

    May 4th, 2011

    The Diff Viewer from JetBrains is by far my favorite file diff and merge tool, and I’ve used a ton of different diff tools over the years. I finally figured out how to run the tool reliably from the command line, so now you can easily use it as a standalone tool. The diff tool was first featured in IntelliJ IDEA, is the exact same tool now seen in RubyMine and PyCharm, and is part of the IDEA Community Edition. If you use these products then you already have it installed. If you’re on WebStorm or PHPStorm (or anything else), you can still install the IDEA community edition and use the diff viewer as an external diff tool.

    The diff tool shows the lines and blocks of a file that have been added, removed or changed. And it does a good job of it, allowing you to easily move, edit, and remove lines between files. Within the IDE there are more options as well, like code completion, syntax highlighting, intentions, and more. From the command line it is a little more basic because it doesn’t have a project file sitting behind it. But it does give you the nice “accept changes” interface and you won’t have to learn and use a second, inferior diff tool.

    PLEASE NOTE: This is tested on the IDEA 10.5 EAP. If you are on an earlier version, then it works correctly as long as IDEA is not already open. If IDEA is open, then you’ll simply open the two files in the editor. Bear with me while I find a solution…

    So here is what I do… I wrote a shell script so that it compares two files:

    diffx file1 file2

    Which opens up the Diff Viewer. If IDEA is already opened, then it uses the running IDEA process and the window opens very quickly. If no IDEA is running then there is a few second startup time; but there are no files to parse so the startup time is only a few seconds and nothing like the startup of a full Java project.

    screenshot

    Without my shell script it is a little difficult to run. You need to change to the $IDEA_HOME/bin directory and then invoke:

    idea.sh diff file1 file2
    or
    idea.exe diff file1 file2

    There is also an inspect_diff.sh script you can run, but I found my method just as easy. The problem with the IDEA provided shell scripts is that file1 and file2 must be absolute paths because you’re in the IDEA/bin directory. If you’re on Windows (without cygwin) then perhaps this is the best you can do. On any system with Bash you can use my bash script (available here). Basically, the script is called “diffx”, and it handles the directories and paths correctly so that you can invoke diffx from anywhere with parameters of either relative or absolute paths. If anyone has improvements then please let me know! You’ll need to have a symlink that points ~/bin/idea/bin to the IDEA/bin directory, do a “chmod +x diffx” to give the file execute permissions, then drop it in your path (you have ~/Dropbox/bin on the path, right?). Otherwise it should all work.

    #!/bin/bash
    
    # makes sure file exists in current dir or as absolute path
    getFile() {
        local FILENAME=$1; local CURRENT_DIR=$2; local RESULTVAR=$3
    
        if [ -e $FILENAME ]
        then
            eval $RESULTVAR=$FILENAME  # if file exists then use it
        else
            # otherwise try to discover the correct path
            local FULLFILENAME=$CURRENT_DIR"/"$FILENAME
            if [ ! -e $FULLFILENAME ]
            then
                echo "Couldn't read $FILENAME or $FULLFILENAME."
                exit 1
            fi
            eval $RESULTVAR=$FULLFILENAME
        fi
    }
    
    # save the current directory and then move to the IDEA dir
    CURRENT_DIR=`pwd`
    pushd .  > /dev/null
    
    cd ~/bin/idea/bin   # you may want to change this or make an environment variable
    
    getFile $1 $CURRENT_DIR FILE1
    getFile $2 $CURRENT_DIR FILE2
    
    ./idea.sh diff $FILE1 $FILE2
    
    popd > /dev/null

    There are a lot of tools that allow you to configure an external diff viewer, and you can always point those tools to this diffx script to use IDEA as the tool. Also, coming in IDEA 10.5 is the ability to compare directories using the Diff Viewer, and this script should work for directories at that point, however I don’t have it working yet. You can read about the directory diffs over at the idea blog if you’d like.

    Thanks everyone, and I look forward to seeing some Bash script refactorings. This is the first bash function I’ve ever written.