vrijdag 20 december 2013

Global Day of Code Retreat

Afgelopen zaterdag ben ik naar de Global Day of Code Retreat geweest. Deze werd gehost door Luminis in Arnhem en was georganiseerd door Daan van Berkel.

De dag was afwisselend ingedeeld. En werd na elk blok van 1,5 uur onderbroken om even allemaal bij elkaar te komen en de ervaringen uit te wisselen (wat heb je gedaan? hoe ging dat? en liep je tegen dingen aan?). Het belangrijkste doel voor de dag was: Have Fun.

We begonnen met een blok van code kata. Dit houdt in dat je tijdens de kata werkt aan je programmeervaardigheden (het is niet erg als je aan het einde van het blok iets hebt dat niet werkt, sterker nog dat is de bedoeling). Dit hebben we via pair programming en TDD gedaan.
Na een korte onderbreking en samenkomst hebben we de tweede kata gedaan. Voor een aantal van de code kata's is er een online 'coding dojo' gebruikt, nl. cyber-dojo.

Vervolgens konden we aangeven wat we graag wilden gaan doen en welke kennis/materialen er aanwezig was. Hiervan ben ik een blok met OpenGL, A.R. Drone en een silent pair programming kata bezig geweest. De OpenGL kregen we helaas niet volledig aan de praat binnen 1,5 uur. Voor de A.R. Drone was er een app beschikbaar voor de smartphone waarmee je hem kunt besturen. Vervolgens hebben we de SDK gedownload, helaas wilde deze niet compileren. Tijdens de samenkomst kregen we te horen dat NodeCopter snel op te zetten is, misschien ga ik dat de volgende keer uitproberen.

Dit was voor mij de eerste keer en ik wist nog niet goed wat ik kon verwachten. Ik heb me laten verrassen en het was een geslaagde dag. Moe maar voldaan ging ik naar huis en de volgende keer ga ik weer :-)

dinsdag 3 december 2013

Why there's no such thing as quick 'n dirty, or how making a mess is slowing people down

Imagine you're at home and you're looking for something. Now, you can create a mess while you're looking... You're throwing stuff around, move things around to a random place and really just making a mess. Because of that you might actually look in the same place multiple times. When you've found it, the mess is still there.

  • You can leave everything where it is and the next time you're looking for something (the chance gets bigger that you have to look for something, because the mess is still there) you spend more time looking for it.
  • Another option is to clean up afterwards, but don't forget... the time spent sorting things out and putting them back is also part of the looking process (I believe people tend to forget that now and then).
Or, you look in different places and when you have to move things, put them back where they were. This may seem to take longer, perhaps because you're spending more time in the same place, but the actual time spent on the total looking process is less. Leaving your room clean and when you keep it clean, you'd have to search less for things and you can find things sooner.

In code it works the same. When you're making a mess it's harder to figure out what the code does, where the functionality is that you're looking for, or worse to find bugs. Keeping code clean may seem to take longer, but it actually takes less time. Or when you leave the mess, the next time you have to look for some code (which will happen sooner if you made a mess) will get harder. This may seem small or barely noticeable, but in due time, this will take up a lot of time; this doesn't always have to be true in the long run, it can (and will) happen in a short amount of time.

In short: People want to do things quick 'n dirty, because they think it's faster. In reality, however, this is an illusion, because 'dirty' doesn't go quick, that's all in their minds.

vrijdag 8 november 2013

Hello World with Wicket, Maven and embeddable Jetty in Eclipse - Part 2: Adding components

To add a component there are two things that we need to create:
  1. html file
  2. java class file

In Wicket the convention is to add html files to the same package as the class file is, this isn't mandatory.

1. html file
The html file tells wicket where to put which component.

2. java class file
Tells Wicket to fill the elements with which components and/or data.

In part 1 I've set up a basic application, in which I've added a HTML file and a Java class file. For this example I'm going to reuse these files and add a tabpanel there.

I've updated the HTML file by adding a placeholder for the tabpanel. HelloWicket.html now looks like:

<!DOCTYPE html>
<html>
<body>

 <h1 wicket:id="message">Message goes here</h1>

 <div wicket:id="tabs" class="tabpanel" />

</body>
</html>

I've added the next few lines to HelloWicket.java and created the method addTabs(), which returns an empty List for now.
List<AbstractTab> tabs = addTabs();
add(new TabbedPanel<AbstractTab>("tabs", tabs));

Adding tabs

A tab panel without tabs isn't very useful... so lets start with adding tabs to the tab panel.

I've created four tab panels named: TabPanel1 through 4 (not very creative, I know).

Here's the HTML from TabPanel1.html
<wicket:panel>
 <h1>Tab 1 - TextField Example</h1>
</wicket:panel>

Notice that for the Panel a Wicket specific tag is used.

And the corresponding Java from TabPanel1.java

public class TabPanel1 extends Panel {

 public TabPanel1(String id) {
  super(id);
 }

}

TabPanel1 extends Panel. This matches to the html tag <wicket:panel>.

At this point a tab is created, but it isn't added to the tab panel yet.

Add tab to tab panel

To add the tab to the tab panel, we first need to know where to add it. In the HelloWicket.html the tab panel is added (see example above). The tabs are added in HelloWicket.java through the following Java code:
private List<AbstractTab> createTabs() {
 List<AbstractTab> tabs = new ArrayList<AbstractTab>();

 AbstractTab tab1 = new AbstractTab(new Model<String>("first tab")) {
  public Panel getPanel(String panelId) {
   return new TabPanel1(panelId);
  }
 };

 tabs.add(tab1);

 return tabs;
}

The tab is now added to the tab panel. When you run the application you'll see a tab containing a Header with Tab 1.

Check out the sources to see the complete application with all four tabs all containing other components


References:

Source code (GitHub)

Wicket component reference (including link to source code)

Wicket user guide (free ebook)


dinsdag 5 november 2013

Hello World with Wicket, Maven and embeddable Jetty in Eclipse - Part 1: Setting up project

Currently I'm starting to get to know Wicket for a project at work. For this, I've set up a hello world application. I've created a step-by-step description on how to create a basic application.

1. Create Dynamic web project in Eclipse.

2. Convert to Maven project
    a. Add necessary folders (if not added automatically):

src/main/java
src/main/resources
src/main/server
src/test/java
src/test/resources

    b. Add configuration for the folders in pom.xml:
<resources>

 <resource>
  <filtering>false</filtering>
  <directory>src/main/resources</directory>
 </resource>

 <resource>
  <filtering>false</filtering>
  <directory>src/main/java</directory>
  <includes>
   <include>**/*.java</include>
  </includes>
 </resource>

 <resource>
  <filtering>false</filtering>
  <directory>src/main/server</directory>
 </resource>

</resources>

<testResources>

 <testResource>
  <filtering>false</filtering>
  <directory>src/test/resources</directory>
 </testResource>

 <testResource>
  <filtering>false</filtering>
  <directory>src/test/java</directory>
  <includes>
   <include>**/*.java</include>
  </includes>
 </testResource>

</testResources>

<sourceDirectory>src/main/java</sourceDirectory>


3. Add Wicket dependency to pom
<dependency>
        <groupId>org.apache.wicket</groupId>
        <artifactId>wicket-core</artifactId>
        <version>${wicket.version}</version>
</dependency>


4. Add Jetty dependencies to pom
<dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>${jetty.version}</version>
        <scope>provided</scope>
</dependency>

<dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-webapp</artifactId>
        <version>${jetty.version}</version>
        <scope>provided</scope>
</dependency>


5. Add Java Servlet API dependency
<dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>${javax.version}</version>
        <scope>provided</scope>
</dependency>


6. Create Application class
The application class should extend WebApplication and implement the getHomePage() method. In the getHomePage() method the HomePage class should be returned (e.g. HelloWicket.class).

package nl.sparkle.hellowicket;

import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.WebApplication;

public class HelloWicketExample extends WebApplication {

        @Override
        public Class getHomePage() {
                return HelloWicket.class;
        }

}


7. Create WebPage class
The WebPage class should extend WebClass.

package nl.sparkle.hellowicket;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;

public class HelloWicket extends WebPage {
        private static final long serialVersionUID = -1099836337542784152L;

        public HelloWicket(){
                add(new Label("message", "Hello World!"));
        }
        
}


8. Create html file
By default this HTML file must have the same name of the related page class and must be in the same package (maybe it's possible to create the same structure in the resources folder and add the HTML files there, but haven't looked at it at time of writing).

<!DOCTYPE html>
<html>
<body>
    <span wicket:id="message">Message goes here</span>
</body>
</html> 


9. Create web.xml in src/main/server/webapp/WEB-INF/

<web-app version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Wicket Examples</display-name>

    <filter>
        <filter-name>HelloWicketExample</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
          <param-name>applicationClassName</param-name>
          <param-value>nl.sparkle.hellowicket.HelloWicketExample</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>HelloWicketExample</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>


10. Start server

package nl.sparkle.hellowicket;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Start {
        private static final Logger LOGGER = LoggerFactory.getLogger(Start.class);

        /**
         * Startup method.
         *
         * @param args
         * the arguments (none?)
         * @throws Exception
         * any exception.
         */
        public static void main(String args[]) throws Exception {
                new Start().start();
        }

        /**
         * Starts the server.
         *
         * @throws Exception
         * when bad things happen.
         */
        public void start() throws Exception {
                String hostname = "localhost";
                int port = 8080;
                String webappPath = Start.class.getClassLoader().getResource("webapp")
                                .getFile();

                Server server = new Server();

                WebAppContext webapp = new WebAppContext();
                webapp.setContextPath("/");
                webapp.setResourceBase(webappPath);
                webapp.setParentLoaderPriority(true);

                server.setHandler(webapp);

                // socket connector supposedly solves problem with windows lock on files
                SocketConnector connector = new SocketConnector();
                connector.setPort(port);
                connector.setHost(hostname);
                server.addConnector(connector);

                server.start();

                String hostedAddress = "http://" + hostname + ":" + port + "/";
                LOGGER.info("Started web application on: {}", hostedAddress);
                server.join();
        }

}


Application is now accessible through http://localhost:8080/

The source can be found on GitHub: https://github.com/sparkle-sparkle/HelloWicketExample

A Wicket project can also be created using Maven from the command-line see the Quickstart on how to do so.

vrijdag 1 november 2013

Oracle Certified Professional Java Programmer

After some time of preparation I decided, at the end of september, that it was time to pick a date. I decided that all of the preparation that I still needed to do, could be done within a month.

Last wednesday was my exam day. I went to the testing facility (which was easy to find, thanks to a colleague who told me the door was easy to miss). Once I've gotten there I had to register... it took some time before they found my name... because I'm a woman they assumed I wouldn't be there for a technical exam (they offer a lot of different exams). Yay for prejudices.

After registration was complete it was time to take the test.
While I was preparing for the test, in the book that I used, they focused a lot about small things that could cause compiler errors (e.g. missing semi-colons (;)). In the actual exam there were questions that were tricky, but less than I had anticipated.
After I finished the test, I went back to the registration desk to get my things. Right after I turned my phone back on, I received an email from Oracle stating I could see my test results online (at the end of the test there's a message on the computer stating that you'd have to wait 30 minutes before you can see your result). I passed my exam and when I notified my colleagues, they wanted to know where the cake was ;-)

maandag 7 oktober 2013

Seminar Behavior Driven Development (BDD)

Last thursday I went to a seminar about BDD. It was hosted by Tricode.

We started the evening with food (always good). After our bellies were filled, our brains were fed. We started with writing down our learning goals for that evening on sticky notes and made groups of four. After that we had to choose a product owner and a business analyst in our group and we received a description of a game. We had the description of a poker variant called 'willow'. After reading the description we had to give the descriptions back, and the product owner and business analyst switched groups. Now, with the new product owner and business analyst, we had to create user stories. Early in the discussion we discovered that the business analyst and product owner in our group had a different game description, namely 'Lamarckian Poker' (for a description of both games check the site of cheapass games). When we had this figured out, we let the product owner decide what the game should actually do (whether it was according to the description or not). For this we had seven minutes, and it was the first of multiple short sessions we had. Next we had a seven-minute-session for writing scenarios from the user stories and start an actual demo. The scenarios had to be written in the format Given-When-Then. After writing some scenarios we got ourselves a deck of cards an started the demo, trying out different cases for each scenario. We figured out that this would give us quick feedback about whether the scenarios were written correctly and if something was missing, we immediately changed the scenario to make it more complete. We also used the Then from the previous scenario as the Given for the next scenario, which made it more logical what the order of the scenarios should be. After that we had a couple more rounds of the same type of sessions. Between the sessions we got some information about BDD, and at the end it was time for testing the scenarios by players from other teams. Unfortunately our game wasn't tested due to the time.

At the end we would get our sticky notes with goals back and give answers to our questions.

We ended the evening with a quiz (I ended third) and drinks.



http://webmail.dalton-vatel.nl/wordpress-daltoncontact/wp-content/uploads/2012/07/petje-op-petje-af-300x237.jpg
http://webmail.dalton-vatel.nl/wordpress-daltoncontact/wp-content/uploads/2012/07/petje-op-petje-af-300x237.jpg

** update:
One of the questions I got is:

"What is the difference between TDD and BDD?"

To start with, BDD is based on TDD. Next to that BDD is focussed on behavior, functional behavior that is. When you look at the format for the scenarios (given-when-then), it's the same as a lot of functional testing tools use (e.g. Cucumber, JBehave, RSpec). BDD also focusses on creating common ground between the product owner, business analyst, and so on and the development team. A product owner for example, might not be familiar with the development process and that shouldn't matter. In BDD the behavior is described in 'natural language', which makes it understandable for everybody, and creates a common language.

This might be an interesting read about history of BDD and comparison of different BDD tools.
http://blog.jonasbandi.net/2010/03/classifying-bdd-tools-unit-test-driven.html



maandag 8 april 2013

PrimeFaces DynaForm

DynaForm is a PrimeFaces extention and can be used to build forms dynamically. You can define the display of the elements based on element types (e.g. input field, checkbox, paragraph, h2, etc.). If for example you want to display an input field you define in your .xhtml file:



TEXT_INPUT is the name I gave to all input fields.

Between the dynaFormControl elements you can define how the element should be rendered. In this example there's no label defined in the xhtml, but DynaForm renders it for you.


In the model you can define the label, elementType, value, whether a field is required and anything else you might need. The model is added to the form control and by adding value="#{elem.value}" DynaForm will assign any filled in value to the value field of the model.



In the bean is where you tie everything together. Here you create the DynaFormModel, -Rows, -Labels and -Controls.



The DynaFormModel contains all rows. In the rows you can add as many labels and controls as you want.



dinsdag 26 maart 2013

Multiple abstraction bug in Weld

A colleague of mine just had some issues with multiple abstractions (interface extends interface). The interface was injected via the @Inject annotation. 
In our project we use Glassfish, which uses Weld as CDI implementation.
Apparently, there's a bug in Weld that has some problems using multiple abstractions with @Inject. We changed @Inject to @EJB and the problem is solved.

vrijdag 22 maart 2013

Bundelen, bundelen en nog eens bundelen

Vandaag ben ik bij een seminar geweest over modulaire applicaties in de cloud. Dit seminar werd gehouden door Luminis. Tijdens dit seminar lag de insteek op OSGi en Amdatu.

Het seminar begon met een korte intro over modulariteit (wat is het, waarom is het belangrijk). Al vrij snel werd het 'down to business' en hebben we een uitgebreide demo gekregen van OSGi in combinatie met BndTools om daarmee verschillende soorten bundles te maken in Eclipse. In bundles kun je één of meerdere packages stoppen en bepalen waar de 'buitenwereld' (lees andere code buiten de bundle) wel/niet bij mag. Deze bundle is als het ware een module.

Na een korte koffiepauze gingen we verder met het cloud-deel. Hierbij werd er persistence (MongoDB) gehangen aan de demo-applicatie, werd er een REST-service gemaakt en vervolgens werd er met behulp van Amdatu de applicatie gedeployed naar de server.

Kortom een zeer interessante en informatieve avond (en een boek gewonnen :-) )