Tuesday, October 5, 2010

The industrial mindset

There is an industrial age mindset that has carried over in the software industry and it's horribly broken.

It's the belief that management is science. 

Management has very little to do with science (although there are tons of studies of actions that do and don't work from a management perspective) and should be mostly about dealing with individual personal issues, the things that make employees non-interchangeable, the things that keep employees motivated.

Unfortunately, it looks like very few organizations are able to apply modern management strategies that help workers stay happy and motivated. Workers are often regarded as interchangeable Lego bricks. Taylor inheritance? Corrupted business schools?

The three essentials for motivation from a managerial perspective when dealing with non-repetitive work are autonomy, flow-mastery and purpose.

Autonomy is essential for happiness. You need to feel like you're making the decisions that affect you directly. This will probably be the hardest one for traditionally-schooled managers to absorb. Employees come in whenever it works for them, work at home, meetings are not mandatory by default and there are no time clocks. The only thing that matters is results. Superfluous to say is that autonomy builds on trust and purpose.

Flow is the daily satisfaction you get from doing something that's not too easy but not too hard. Ideally you get flow every day, and it's what carries you through the difficulties of achieving mastery.

To achieve flow, you need:
  • Clear goals
  • Immediate feedback
  • A challenge that is not too easy nor too difficult
  • Autonomy
  • Something that engages you
  • Enough structure
Continuous flow leads to mastery over time.

Examples: TDD, iteration ending with functionality demo

Purpose is the feeling that you are working towards a higher goal. The idea that there's a reason (mainly non-profitable) why we do what we do (Maslow's self-actualization).

You really need all of them in order to feel happy & motivated. For example, you could be working in an environment where you feel autonomous but you get no sense of flow at all (not enough structure, no feedback in time).

Monday, October 4, 2010

Continuous integration anti-patterns


Rare check-ins

The most important practice for CI to work properly is frequent check-ins to trunk.

Many projects use branches and forget that if you are not merging your changes to trunk often then you are not doing truly continuous integration since you are not integrating the changes done in different branches.

There's a collision between branching and CI. That's why branches are not recommended except in very limited circumstances.

Lack of a comprehensive test suite

Without unit, component and acceptance tests being run by your CI system, how do you know that your software is working?
Many projects just rely on a passing compile build which is clearly not enough for most applications.

Long build times

Ten minutes is probably the limit. More than that will make people check in code less often which in turn could lead to more failing builds.

The problem is usually long-running tests. To overcome the problem, split your test process into 2 stages that run separately: the commit stage that just creates a deployable binary after running unit-tests (on every check in) and the heavy-testing stage that uses the binary from the first stage and runs a series of acceptance, integration, performance or other type of long-running tests against it.

Slow development workspace

The most common problem is that the application cannot be run locally or it takes a long time to do so. This means that the application cannot be tested on the developer's machine prior to check-in without going through a lot of pain.

Possible solutions include deploying the application on lighter containers on the local machine or use products e.g JRebel that make it possible to skip (longer) redeployment phases.

Wednesday, September 22, 2010

Expected exceptions in JUnit 4

In Junit 4 we can use the annotation @Test(expected=SomeException.class) to mark that tests should pass when the expected exception is thrown from the test.

The problem with this is that the test will still pass even if the exception is thrown from the wrong place.

JUnit 4.7 addresses this issue by introducing rules. Rules are just another extension mechanism for JUnit. Check how the following code allows us to verify both the type and the message of the exception and, above all, specify where the exception should be raised.

@Rule
public ExpectedException thrown = ExpectedException.none();


    @Test
    public void testRules() throws FileNotFoundException {
        File file = new File("whateverfile");
        thrown.expect(FileNotFoundException.class);
        thrown.expectMessage("(No such file or directory)");
        FileInputStream fis = new FileInputStream(file);

    }

Saturday, September 4, 2010

CIO talk: How to get rid of your developers

Step 1: Outsource your operations

Step 2: Buy your whole production platform from one single vendor

Step 3: Force agile

Step 4: Do little effort to spread information

Step 5: Believe people are "resources" that are interchangeable (Lego bricks)
 

Monday, July 5, 2010

Groovy tip: using methodMissing


There are 4 metaprogramming hooks in Groovy. These are:
  • invokeMehod: interceps method dispatch
  • methodMissing: intercepts fail method dispatch
  • get/setProperty: intercepts property access
  • propertyMissing: intercepts failed property access
Let's see how to use methodMissing to add dynamic finders (accessing data store) to a class.


If we run this code it will fail at runtime since we haven't defined the finder. In order to do this we need to add some metaprogramming.

All we're doing here is selecting the appropriate column in the database depending on the kind of finder invoked. This is working but it's not as efficient as it should be. What we can do is create a closure from that code and the cache it in the class. So now we have:

So instead of running through the whole methodMissing implementation every time the same finder method is called now we create a method dynamically and we add it to the class. This means that next time we call the same method it will be found (cached).

This is a trick that can be used to improve performance when using the metaprogramming hooks in Groovy.

Friday, July 2, 2010

Groovy tip: adding methods dynamically at runtime


From Groovy's perspective every class (including Java classes) have a meta-class associated to them. This meta-class can be used to obtain information on the underlying class or to add methods and properties on the fly. In other words, this is AOP made easy.

So let's say we have a Java class:

public class SuperHero {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

And I want to add a constructor that takes a name as a parameter. I also want to add a method:

SuperHero.metaClass.constructor = {String name -> new SuperHero(name:name)}
SuperHero.metaClass.fight = {"BAM!"}

println new SuperHero("Batman").name
println new SuperHero("Batman").fight()

The constructor is just a closure that sets the property for us.

Monday, June 14, 2010

Bookmarkable URLs with JSF2



Parameters are now defined in the page itself so a request like:

http://localhost:8080/contactInfo.jsf?contactId=manu%40ffff.se

would have its parameters defined as

<f:metadata>
        <f:viewParam name="contactId" value="#{contactController.email}"/>
    </f:metadata>

If the parameter value isn't specified in the request then the value will be null, so make sure the property receiving the parameter value isn't a primitive (i.e. it must be nullable).

You will also need an action to load data into the view. Any component can have pre-render events attached to it. For example, a form:

<h:form id="contactInfoForm">
            <f:event type="preRenderComponent" listener="#{contactController.loadContact}"/>

All you need to do is declare the parameters to be bound and the action on the page/view you wish to make bookmarkable.

Sunday, June 6, 2010

JSF2 on Google App Engine

I updated my JSF2 on Google GAE demo (a simple address book). I added more Primefaces stuff, authentication (using Google accounts), integration with Google Maps, persistence with Objectify, and a some servlets to be able to upload and serve images using the image service (the upload component in Primefaces does not yet work on GAE). There's a blobstore service that makes image uploads much easier but it's only available when billing is enabled on your appengine account.

The next step could be to add conversation support for this (using WELD). 

The code is here: https://github.com/manuel-palacio/JSF2-Primefaces-GAE-Sample-Project

The application also demonstrates how to use @Controller and @Inject together with Spring.

Some thoughts

I started prototyping with Twig but I didn't find it intuitive enough. I switched to Objectify and things started working right away :)

Objectify does not provide "managed" relationships in the way that JDO or JPA does. This means that you have to write more code in order to manage them (you have to explicitly load the relationships unless you are using GWT?)

When you create relationships to other entities in your system, the type of the entity relationship should be Key.



@Entity
public class Contact {

    @Id
    String email;

    String name;

    Key<ContactImage> contactImage;

if (imageId != null) {
            contact.setContactImage(new Key<ContactImage>(ContactImage.class, imageId));

        }


This is a simple one to one relationship. If I wanted the contact to have a list of images I'd write:

class Contact{
    @Id Long id;
    String name;
}

class ContactImage{
    @Id Long id;
    Key<Contact> contact;
    String caption;
    String blobStoreKey;

} 

And query like:

Query<ContactImage> query = createQuery(ContactImage.class).filter("contact", contactKey);
List<ContactImage> fetched = ofy.prepare(query).asList(); 

In GAE, this is more efficient than defining a collection of ContactImage in the Contact itself although it may look counter-intuitive.


Tuesday, May 25, 2010

Concise Groovy

The power of closures


Filter duplicates and write to csv file
def set = new HashSet();

new File("C:/temp/no2.csv").eachLine {
  line -> set.add(line)
}

new File("C:/temp/no3.csv").withWriter {writer, count = 0 ->
  set.each {
    element ->
    writer.append(element)
    count++
    if (count < set.size()) writer.append(",")
  }
}

Wednesday, May 19, 2010

"Autologin" with Seam

Sometimes we've just built our login routine in the traditional Seam way using the Identity instance wired to a form like:

In order to login the user automatically when i.e. clicking on a link we just need to add the following to pages.xml and to our Authenticator


So now the parameters will be automatically propagated by Seam and we can programmatically call login() on the Identity instance. In this example the URL would be /login.seam?username=xxx&password=xxx

Of course we could use the URL rewriter to make Seam react to more RESTful URLs. See the docs for that.

Wednesday, April 14, 2010

Adding a version number with Maven


Sometimes it's handy to be able to see the version number of the application somewhere on a page. The version number should ideally be "inserted" by Maven while it's building. I.e something like:

<div id="footer">
Version: 1.1
</div>

An easy way to do it is by adding the following 2 plugins to the build section of the POM.

The template just contains the following somewhere

<h:outputText value="Version: @VERSION_NUMBER@"/>

Wednesday, March 17, 2010

Editing tables with modal panels with RichFaces and Seam




A typical GUI use case is to be able to edit a table with a modal dialog (one row at a time). This is easily done with RichFaces and Seam.

In the template we define a datatable and the modal dialogues that are displayed when we right-click on the row.

Note that:
Due to a limitation in JSF, UIInputs that do not fail validation are sticky i.e. they retain their values through multiple requests. This behavior makes sense on many occasions as most of the time users will just correct the errors and resubmit the form, but on the odd occasion is not really desirable such as when using a form to display multiple objects selected by Ajax requests like in this case since if we leave some empty values in the form and select another row the new values selected will not be shown in the panel. See http://wiki.apache.org/myfaces/ClearInputComponents

That's why we have a cancel() method that clears submitted values if we close the dialog while we still have validation errors.

Monday, March 15, 2010

I18N with Seam


Define the available locales in faces-config.xml.


        com.sun.facelets.FaceletViewHandler
        
            sv
            sv            
        
    

Then when you need to present for example a date you can just the locale selector like

@In
private LocaleSelector localeSelector;                 

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("d MMMM yyyy", localeSelector.getLocale());

Wednesday, March 10, 2010

Culture and science

Is there a way of understanding why humans continuously and constantly and without exception engage in cultural activity? It seems to be something that we are biologically inclined to do. If we are, then what is the nature of that drive? What is it doing for us? The better off humans are the more time they spend engaged in issues of style: buying art, buying gadgets, clothes, cars, furniture or whatever and making choices between one look of things and another look of things.

The root of this behavior lies in the need to play at being someone else or at inhabiting other worlds. We have a fantastic ability to move from the world in our heads to the "possible" world in our heads and all the other possible worlds that we can imagine.

The most important thing humans can do is to imagine how things could otherwise be and make choices about them. That's the key to our evolutionary success. We only notice how powerful that process is when we meet people who can't do it - severely autistic children for example, who are incapable of switching worlds - who in many senses can appear completely intelligent, but they are completely incapable of seeing that there's any world other than the one they perceive at this moment. This makes them incapable of cooperation and deception since they can neither create common worlds nor create situations in which one could see a different world from the one it really exists.

To a very large degree, cooperation and deception is what distinguishes humans from other animals. The constant engagement in culture enables us to continually rehearse this ability we have - imagining, exploring, extrapolating other worlds.

This is the point at which there is a deep connection between art and science: each is a highly organized form of saying "let's see what would happen if the world was like this".

Monday, March 8, 2010

External configuration with Seam



Sometimes you want to load environment-specific configuration properties from a file located in the file system. With Spring this is very easy as all you need to do is to use a property placeholder

<context:property-placeholder location="file:/opt/etc/myprops.properties"/>


Seam does not have an out-of-the-box component to do that but you can write your own

@Name("environment")
@Scope(ScopeType.APPLICATION)
@AutoCreate
public class Environment {
    private Properties properties;

    @Create
    public void setup() {
        try {
            properties = new Properties();
            properties.load(new FileInputStream("/opt/etc/myprops.properties"));
        } catch (IOException e) {
            throw new RuntimeException("Unable to load environment.properties", e);
        }
    }

    public String getProperty(String name) {
        return properties.getProperty(name);
    }
}

Then you can use this component anywhere in your application. For example:

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:async="http://jboss.com/products/seam/async"
            xmlns:transaction="http://jboss.com/products/seam/transaction"
            xmlns:mail="http://jboss.com/products/seam/mail"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                 http://jboss.com/products/seam/async http://jboss.com/products/seam/async-2.2.xsd
                 http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.2.xsd
                 http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">


    <core:init transaction-management-enabled="false"/>

    <transaction:no-transaction/>

    <mail:mail-session session-jndi-name="mail/pdfGeneratorSession"/>


    <component name="ftpHandler">
        <property name="ftpHost">#{environment.getProperty('ftpHost')}</property>
        <property name="ftpPort">#{environment.getProperty('ftpPort')}</property>
        <property name="ftpUser">#{environment.getProperty('ftpUser')}</property>
        <property name="ftpPassw">#{environment.getProperty('ftpPassw')}</property>
    </component>

</components>

Friday, March 5, 2010

Easy PDF generation with Seam

Seam is a fantastic integration framework that can do many things. It is mostly known for its integration with JSF 1.x making it actually usable and adding a lot of features that have now become standard in JSF 2.0 i.e. page actions, factory methods, better navigation, etc. 
But there are many more features worth mentioning: JPA lazy loading, BPM support in web applications, integration with quartz, iText integration and many more.

iText integration
The iText library is a widely used open source Java library for generating PDF documents. However, using its programatic API to construct a PDF document is time consuming (think building a XML document using DOM or construct a UI using Swing). Seam neatly ties iText, JSF, and Facelets together and allows developers to declaratively write PDF pages with dynamic content, just as you would do for JSF web pages. Furthermore, you can now use templates in PDF pages.

The key to do this the special XHTML tag library for PDF elements that transparently calls iText when the page is rendered. Let's see a simple example of how we to use the iText integration to send a number of PDF documents attached in an email.
@Name("pdfSender")
@AutoCreate
public class PdfSender {

    @In
    private Renderer renderer;

    @In
    private PdfAssembler pdfAssembler;

    @In
    private FtpHandler ftpHandler;

    public void sendPdf() throws IOException, ParseException {

        Map<String, String> files = ftpHandler.getData();
        if (files.isEmpty()) {
            throw new IllegalArgumentException("No data found on FTP server");
        }

        List<Pdf> pdfList = processFTPData(files);
        Contexts.getEventContext().set("pdfList", pdfList);
        renderer.render("/pdf/sendPdf.xhtml");  //sends mail
        ftpHandler.deleteFiles();
    }

    private List<Pdf> processFTPData(Map<String, String> files) throws ParseException {

        List<Pdf> pdfList = new ArrayList<Pdf>();
        for (final String location : files.keySet()) {
            final String data = files.get(location);
            if (StringUtils.isEmpty(data)) {
                throw new IllegalArgumentException("Empty data file for: " + location);
            }
            pdfList.add(pdfAssembler.assemblePdf(location, data));
        }

        return pdfList;
    }
}

We just gather a bunch of data files via FTP, process them into a collection of DTOs representing the PDF structure and then add it to Seam's event context.  The DTOs are used to transfer data to the view (xhtml templates). Next we just "render" the mail with the attachments.

<?xml version="1.0" encoding="UTF-8"?>
<m:message xmlns="http://www.w3.org/1999/xhtml"
           xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:p="http://jboss.com/products/seam/pdf"
           xmlns:m="http://jboss.com/products/seam/mail">

    <m:header name="X-Sent-From" value="PDFGenerator"/>
    <m:from name="PDF Generator" address="#{mailAddress}"/>
    <m:to name="Manuel Palacio">#{mailAddress}</m:to>
    <m:subject>PDF</m:subject>
    <m:body>
        <ui:repeat value="#{pdfList}" var="pdf">
            <m:attachment fileName="#{pdf.location}.pdf">
                <ui:include src="/pdf/pdf.xhtml"/>
            </m:attachment>
        </ui:repeat>
    </m:body>

</m:message> 
 
Pdf.xhtml generates the sections of the document

<p:document xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:c="http://java.sun.com/jsp/jstl/core"
            xmlns:p="http://jboss.com/products/seam/pdf"
            title="Report"
            keywords="Report #{pdf.artNr}"
            subject="Report #{pdf.artNr}"
            author="MP"
            creator="MP">


   
     <ui:repeat value="#{pdf.sections}" var="section" varStatus="status">
        <p:chapter number="#{status.index + 1}">
            <p:title><p:font size="18"><p:paragraph spacingAfter="12"
                                                    alignment="center">#{section.title}</p:paragraph></p:font></p:title>

            <ui:repeat value="#{section.areas}" var="area">
                <p:section>
                    <p:title>
                        <p:font size="8" style="bold"><p:paragraph
                                spacingBefore="10">#{area.name}</p:paragraph></p:font>
                    </p:title>
                    <p:paragraph spacingBefore="1" spacingAfter="0" leading="10" keepTogether="true">
                        <ui:include src="/pdf/displayObject.xhtml"/>
                    </p:paragraph>
                </p:section>
            </ui:repeat>
        </p:chapter>
    </ui:repeat>

</p:document>


DisplayObject.xhtml generates the data in each section

<ui:repeat value="#{area.displayObjects}" var="displayObject" xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:p="http://jboss.com/products/seam/pdf">
    <p:paragraph>
        <p:font size="8" style="bold">#{displayObject.name}</p:font>
        <p:font size="8">&#160;(#{displayObject.formattedId})</p:font>
        <p:font size="8" rendered="#{not empty displayObject.address}">&#160;#{displayObject.address}</p:font>
    </p:paragraph>
    <ui:repeat value="#{displayObject.events}" var="event">
        <p:paragraph>         
            <p:font size="7">#{event.text}&#160;#{event.date}</p:font>
         </p:paragraph>
    </ui:repeat>
    <p:paragraph spacingAfter="5"/>
</ui:repeat>

It takes time to learn how to tweak all the parameters to make the PDF look the way you want but it's definitely much easier and intuitive than using the iText API directly. For very advances formatting you may want to look at jasperreports.

Now we could define a cron job that runs the sendPdf task at defined intervals.

@Name("schedulerController")
public class SchedulerController {

    @In
    ScheduleProcessor processor;
    
    /**
    Method called when framework is initialized
    */ 
    public void startScheduler(String cronExpression) throws IOException, ParseException, ExecutionException, InterruptedException {
        processor.createQuartzTimer(new Date(), cronExpression);
    }
}

/**
 * Timer class. The methods annotated as asynchronous will be called by Quartz or other implementations
 * as specified by @IntervalCron
 */
@Name("processor")
@AutoCreate
@Scope(ScopeType.APPLICATION)
public class ScheduleProcessor {


    @Logger
    private Log log;

    @In
    private PdfSender pdfSender;

    @Asynchronous
    public QuartzTriggerHandle createQuartzTimer(@Expiration Date when, @IntervalCron String interval) throws IOException, ParseException, ExecutionException, InterruptedException {
        
        log.info("[#0] Processing pdf document with interval #1", when, interval);
        pdfSender.sendPdf();

        return null;
    }
}

In components.xml we make sure the cron job is started when Seam is initialized

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:async="http://jboss.com/products/seam/async"
            xmlns:transaction="http://jboss.com/products/seam/transaction"
            xmlns:mail="http://jboss.com/products/seam/mail"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                 http://jboss.com/products/seam/async http://jboss.com/products/seam/async-2.2.xsd
                 http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.2.xsd
                 http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">


    <core:init transaction-management-enabled="false"/>

    <transaction:no-transaction/>

    <mail:mail-session session-jndi-name="mail/pdfGeneratorSession"/>


    <component name="ftpHandler">
        <property name="ftpHost">localhost</property>
        <property name="ftpPort">2121</property>
        <property name="ftpUser">admin</property>
        <property name="ftpPassw">admin</property>
    </component>

    <async:quartz-dispatcher/>

    <factory name="mailAddress" scope="STATELESS" value="xxx@xxx.xx" auto-create="true"/>

    <event type="org.jboss.seam.postInitialization">
        <action execute="#{schedulerController.startScheduler('0 0/1 * * * ?')}"/>
    </event>


</components>

Seam has definitely made simple tasks like sending mail and generating PDFs even simpler and more elegant.

Wednesday, March 3, 2010

Interface naming

Some not so good examples of interface naming are:

interface PersonDS{}

PersonDSEJB implements PersonDS {}

class User implements IUser {}

The first example shows how ugly and meaningless it can be when you are forced to implement an interface by the framework.

In the second example the prefix hurts readability. On top of that, when changing from an abstract class to an interface, a coding convention with prefix implies renaming all the occurrences of the class.

There is also another convention, used by many open source projects including Spring

interface User {}

class DefaultUser implements User {}

class AnotherClassOfUser implements User {}

Much better :)