Archive

Posts Tagged ‘open source’
  • Improving the Vaadin 4 Spring project with a simpler MVP

    I’ve been using the Vaadin 4 Spring library on my current project, and this has been a very pleasant experience. However, in the middle of the project, a colleague of mine decided to “improve the testability”. The intention was laudable, though the project already tried to implement the MVP pattern (please check this article for more detailed information). Instead of correcting the mistakes here and there, he refactored the whole codebase using the provided MVP module… IMHO, this has been a huge mistake. In this article, I’ll try to highlights the stuff that bugs me in the existing implementation, and an alternative solution to it.

    The existing MVP implementation consists of a single class. Here it is, abridged for readability purpose:

    public abstract class Presenter<V extends View> {
    
        @Autowired
        private SpringViewProvider viewProvider;
    
        @Autowired
        private EventBus eventBus;
    
        @PostConstruct
        protected void init() {
            eventBus.subscribe(this);
        }
    
        public V getView() {
            V result = null;
            Class<?> clazz = getClass();
            if (clazz.isAnnotationPresent(VaadinPresenter.class)) {
                VaadinPresenter vp = clazz.getAnnotation(VaadinPresenter.class);
                result = (V) viewProvider.getView(vp.viewName());
            }
            return result;
        }
    
        // Other plumbing code
    }
    

    This class is quite opinionated and suffers from the following drawbacks:

    1. It relies on field auto-wiring, which makes it extremely hard to unit test Presenter classes. As a proof, the provided test class is not a unit test, but an integration test.
    2. It relies solely on component scanning, which prevents explicit dependency injection.
    3. It enforces the implementation of the View interface, whether required or not. When not using the Navigator, it makes the implementation of an empty enterView() method mandatory.
    4. It takes responsibility of creating the View from the view provider.
    5. It couples the Presenter and the View, with its @VaadinPresenter annotation, preventing a single Presenter to handle different View implementations.
    6. It requires to explicitly call the init() method of the Presenter, as the @PostConstruct annotation on a super class is not called when the subclass has one.

    I’ve developed an alternative class that tries to address the previous points - and is also simpler:

    public abstract class Presenter<T> {
    
        private final T view;
        private final EventBus eventBus;
    
        public Presenter(T view, EventBus eventBus) {
            Assert.notNull(view);
            Assert.notNull(eventBus);
            this.view = view;
            this.eventBus = eventBus;
            eventBus.subscribe(this);
        }
    
        // Other plumbing code
    }
    

    This class makes every subclass easily unit-testable, as the following snippets proves:

    public class FooView extends Label {}
    
    public class FooPresenter extends Presenter<FooView> {
    
        public FooPresenter(FooView view, EventBus eventBus) {
            super(view, eventBus);
        }
    
        @EventBusListenerMethod
        public void onNewCaption(String caption) {
            getView().setCaption(caption);
        }
    }
    
    public class PresenterTest {
    
        private FooPresenter presenter;
        private FooView fooView;
        private EventBus eventBus;
    
        @Before
        public void setUp() {
            fooView = new FooView();
            eventBus = mock(EventBus.class);
            presenter = new FooPresenter(fooView, eventBus);
        }
    
        @Test
        public void should_manage_underlying_view() {
            String message = "anymessagecangohere";
            presenter.onNewCaption(message);
            assertEquals(message, fooView.getCaption());
        }
    }
    

    The same Integration Test as for the initial class can also be handled, using explicit dependency injection:

    public class ExplicitPresenter extends Presenter<FooView> {
    
        public ExplicitPresenter(FooView view, EventBus eventBus) {
            super(view, eventBus);
        }
    
        @EventBusListenerMethod
        public void onNewCaption(String caption) {
            getView().setCaption(caption);
        }
    }
    
    @Configuration
    @EnableVaadin
    public class ExplicitConfig {
    
        @Autowired
        private EventBus eventBus;
    
        @Bean
        @UIScope
        public FooView fooView() {
            return new FooView();
        }
    
        @Bean
        @UIScope
        public ExplicitPresenter fooPresenter() {
            return new ExplicitPresenter(fooView(), eventBus);
        }
    }
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = ExplicitConfig.class)
    @VaadinAppConfiguration
    public class ExplicitPresenterIT {
    
        @Autowired
        private ExplicitPresenter explicitPresenter;
    
        @Autowired
        private EventBus eventBus;
    
        @Test
        public void should_listen_to_message() {
            String message = "message_from_explicit";
            eventBus.publish(this, message);
            assertEquals(message, explicitPresenter.getView().getCaption());
        }
    }
    

    Last but not least, this alternative also let you use auto-wiring and component-scanning if you feel like it! The only difference being that it enforces constructor auto-wiring instead of field auto-wiring (in my eyes, this counts as a plus, albeit a little more verbose):

    @UIScope
    @VaadinComponent
    public class FooView extends Label {}
    
    @UIScope
    @VaadinComponent
    public class AutowiredPresenter extends Presenter<FooView> {
    
        @Autowired
        public AutowiredPresenter(FooView view, EventBus eventBus) {
            super(view, eventBus);
        }
    
        @EventBusListenerMethod
        public void onNewCaption(String caption) {
            getView().setCaption(caption);
        }
    }
    
    @ComponentScan
    @EnableVaadin
    public class ScanConfig {}
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = ScanConfig.class)
    @VaadinAppConfiguration
    public class AutowiredPresenterIT {
    
        @Autowired
        private AutowiredPresenter autowiredPresenter;
    
        @Autowired
        private EventBus eventBus;
    
        @Test
        public void should_listen_to_message() {
            String message = "message_from_autowired";
            eventBus.publish(this, message);
            assertEquals(message, autowiredPresenter.getView().getCaption());
        }
    }
    

    The good news is that this module is now part of the vaadin4spring project on Github. If you need MVP for your Vaadin Spring application, you’re just a click away!

    Categories: JavaEE Tags: open sourcespringvaadin
  • Simple templating solution with SiteMesh

    In this article, I will show you how to use SiteMesh in your JEE web sites in order to bring a sense of unity to them.

    When talking about templating, the method everyone uses at first is to use <@include> tags throughout the JSP pages. This course of action is flawed from the start since all JSPs are responsible to call includes and thus, there’s no real enforcement to use the correct ones.

    The most used method is Apache Tiles. To be frank, I didn’t have a look at Tiles since it went from Struts to Apache. Struts Tiles were meant to be used in conjunction with Struts. Apache Tiles seems to support many more technologies (JSP, Velocity, Freemarker, …) but I didn’t see any JSF support out-of-the-box though there seem to exist plenty of articles that tackle the subject and its problems.

    When I used Struts Tiles, I found it was a very powerful framework, yet many junior developers had some problems with it. In most projects I worked on, a senior developer assembled tiles while junior ones created the pages themselves. I found Tiles very configurable but this came at the cost of complexity. In most cases, I didn’t need all the functionalities of Tiles: I only wanted to have a header, a footer and a menu nicely crafted around my main page.

    When investigating AppFuse, I stumbled upon a nice templating tool that just does that: SiteMesh. SiteMesh is technology-neutral, meaning it can be used with whatever view framework is used, JSF included. It is based on the very simple concept of servlet filters. An XML file forms the basis of the template’s configuration. This configuration holds what pages are decorated and with what templates.

    The templating mechanism is made so each page is seen as complete either when viewed standalone or when viewed through the filter. For example, when you write the page normally, you provide the title’s text (what is displayed in most browser’s title bar). If you are using SiteMesh, nothing changes. At runtime, the servlet filter reads the title’s text value from the source HTML (which can come from a dynamic source) and outputs the decorated page with the same title’s text value, although the page design will be different.

    The following example shows how it is achieved in the template:

    <html>
      <head>...</head>
      <body>
        <div id="top">Header</div>
        <h1><decorator:getProperty property="title" /></h1>
        ...
      </body>
    <html>
    

    Nothing could be simpler. Yet, the solution decouples the standalone view from the decorated view. The former has no need to know about the latter!

    A common use-case is to put common CSS and JavaScript declarations in the template.

    Moreover, the choice of which decorator(s) to use can come from different strategies:

    • configuration files,
    • cookies,
    • browser language,
    • display agent (browser or printer),
    • etc.

    The simplicity and the robustness of the solution is what will make me deeply think about using it if I have simple templating needs. On the opposite site, if you have complex templating requirements, SiteMesh won’t be enough.

    You will find a very simple project here in Maven/Eclipse format.

    To go further:

  • Shark! Shark! in the IT business

    Shark! Shark! screenshot

    Do you remember the classic Atari ST game where you, as a fish, eat other fishes while getting bigger and avoiding bigger fishes to eat you? It seems the last 4 years has seen its share of fishes eat and being eaten in the IT business.

    Oh, it began innocently enough. JBoss just hired the Hibernate team. It was in November 2005. Less than 6 months later, JBoss was bought by Red Hat. I thought: “Wow, now Red Hat can provide a whole stack from Operating System to Middleware!”

    January 2008: Oracle finally buys BEA Systems, the only serious commercial concurrent of IBM in the application server market. It already tried the buyout in October 2007. I then thought: “Oracle can provide the last 2 tier of any JEE application, Middleware and Database (please don’t raise the issue of Oracle Application Server). That’s interesting!”

    About the same time, Sun has got the same idea the other way around when it buys MySQL. I thought: “They have both invested in OpenSource, that’s good strategy!”

    When SpringSource bought Hyperion, my sense of wonder began to dry.

    Now that Oracle has bought Sun and VMWare has bought SpringSource, I’m finally more concerned than ecstatic. Concurrent products that competed against one another are now in the same provider’s portfolio. No business has interest in having the same redundant softwares in its catalog. And lacking competition means no evolution, like Darwin theorized.

    I always complained about Microsoft’s choices being more marketing oriented than technically sound. It could do that until it was the major player in its field. Java and Google put an end to that (ok, not entirely, this is open to discussion but let me make my point). In turn, and although Java was meant to stay a loooong time in version 1.4, Sun made it evolve because of the progress made by the .Net framework. From my humble point of view, that’s a vertuous circle in IT darwinism.

    One may rightfully think the circle is now broken, when one looks at the following points:

    • Oracle Application Server and WebLogic are now owned by Oracle. Whereas stopping the development of OC4J may not be a bad thing in itself, I can't be so sure about the whole stack surrounding both.
    • Even worse, why would Oracle need to put money in Glassfish development, now that it has WebLogic? I'm not an ardent Glassfish defender but it plays its role in the JEE ecosystem.
    • I can't even think about Oracle database and MySQL, now that Oracle distributes Oracle Lite for free. That goes without saying but it is for development purposes only and without an OpenSource license of course.
    • What about JDeveloper and NetBeans? I fear only very bad things since if NetBeans development is stopped, it will mean IBM will do as it pleases with Eclipse (yes, I know about the Eclipse Foundation, but it still smells).
    • And poor JRockit?
    • And so on, ad nauseam.

    The present concentration trend raises concerns, at least from me, because it may well end when there’s only one single player left standing. Remember the Atari game I talked about at the beginning? It was aptly named “Shark! Shark!” because regardless of the size you were, you could always be eaten by the shark. Whoever will end up being the shark, I can only guess, but if this doesn’t stop soon, we are all about to get eaten!

  • Manage the quality of your projects with Sonar

    Sonar is a free OpenSource product that provides you with a general dashboard displaying information about the codebase of each configured project, such as:

    • Number of failed tests,
    • % of code coverage,
    • % of rules compliance (more later),
    • % of duplicated lines,
    • and much more.

    Then you get an additional graphical information showing:

    • a square for the size of your project's codebase relative to the entire codebase's size,
    • a color (from red to green) for the % of rules compliance.

    Sonar Dashboard screenshot

    Yet, what are considered rules compliance? These are rules defined by products you (may) already know:

    Sonar provides you with the means to configure these rules in 3 categories: mandatory (error), optional (warning) or inactive. Some rules can even be configured with parameters, i.e: the maximum number of lines of a method. In this case, you can override the default value.

    Sonar uses two modules:

    • a Maven plugin that does the real analysis,
    • a web application for configuring rules and displaying information.

    Analysis results are saved in a database. This enables to you to display the trend of your projects. In Sonar, it is called the Time Machine: if codebase’size stays the same, are there more violations? Or if the codebase’s size increases, does the number of violations increases too?

    Sonar Dashboard screenshot

    By default, Sonar uses a Derby (sorry, JavaDB) database but it can easily be configured with a 3rd party database such as Sun MySQL.

    Sonar is very simple to use. Just type this line on your Maven2 project directory to do the analysis:

    mvn clean install org.codehaus.sonar:sonar-maven-plugin:1.5.1:sonar

    The web application must be separately installed but the install process is on par with the analysis. You can have a running Sonar instance in less than 2 minutes (I did it, so anyone can do!).

    Since Sonar is a Maven plugin, it should be a breeze to integrate the analysis on a Continuous Integration platform.

    All in all, Sonar is a nice easy-to-use product intended for quality managers, project managers and architects alike. Some features, such as the Time Machine, are not provided by any other OpenSource projects that I know of. If you already use one of Checkstyle / PMD / Findbugs, I can’t recommend enough taking a very thorough look at Sonar, you won’t regret it.

    Categories: Java Tags: open sourceopensourcequalitysonar