Sunday, March 24, 2013

Automatically generated Class Diagrams using Maven & UMLGraph

Drawing Class Diagrams preemptive is sometimes nice to optimize your thought of design. But it will still most likely change in the development phase. Since your Class Diagram is part of your documentation it should be up to date all the time. There is no point in having a Class Diagram if the code does not fit it. You could keep adapting the changes to the Class Diagram by hand, but that can get very time-consuming and exhausting. You should rather automate that process, and there are several ways to achieve exactly that. You could for example search for a UML Class Diagram Tool supporting roundtrip engineering. There are some commercial, and even some free ones available. Not all of them work very well and it can be a frustrating task to figure out which way to go. You would probably try out some and throw them away because they are just not what you expected.
Thats why i want to show you a different approach: Letting a Javadoc Doclet draw the Class Diagrams in build phase and embed them into your javadoc automatically. UMLGraph is such a doclet. It analyzes your code, draws Class Diagrams automatically and embed them into your javadoc.

Since maven can run javadoc at build phase it's perfect. You just have to configurate the maven-javadoc-plugin to use UMLGraph.

Configurate Maven to use UMLGraph


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<reporting>                                                                              
    <plugins>                                                                            
        <plugin>                                                                         
            <groupId>org.apache.maven.plugins</groupId>                                  
            <artifactId>maven-javadoc-plugin</artifactId>                                
            <version>2.9</version>                                                       
            <configuration>                                                              
                <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>                         
                <docletArtifact>                                                         
                    <groupId>org.umlgraph</groupId>                                      
                    <artifactId>umlgraph</artifactId>                                    
                    <version>5.6</version>                                               
                </docletArtifact>                                                        
                <additionalparam>-views -all</additionalparam>                           
                <useStandardDocletOptions>true</useStandardDocletOptions>                
            </configuration>                                                             
        </plugin>                                                                        
    </plugins>                                                                           
</reporting>                                                                             

Beware that the javadoc doclet api has changed from jdk 1.6 to jdk 1.7 and most of the online tutorials are outdated because of that. UMLGraph adapted to jdk 1.7 since version 5.5.

If we run mvn site right now, we will just get that error:
java.io.IOException: Cannot run program "dot": java.io.IOException: error=2, No such file or directory 
This means that the program dot was not found which is a part of the graphviz library.
 

Install Graphviz

For UMLGraph to run you need graphviz installed. Go to the Download Page, and choose your package. On linux you could even sudo aptget install graphviz. Beware that you might have to reboot or relogin to use graphviz, because the Systems Path is extended during installation.

First Result

Run mvn site, and open target/site/apidocs/index.html afterwards.


As you can see its drawing beautiful and accurate UML Class Diagrams.

Custom Configuration

If you dont want attributes/methods or other extras you are totally free to configurate those graphs. See Class Diagram Options. Just add them to the
<additionalparam>-views -all</additionalparam>
tag in pom.xml

Saturday, March 16, 2013

8 Things you should not be afraid of as a Developer

Change

In Software Development there is no such thing as stagnancy. Everything you develop now is just another version of a component that will probably change in the future. Change is the most common thing in Software Development, and you're better of accepting it as a fact. Expect future changes to everything you develop, and therefor design your Code more modular. This makes changes more easy and increases the Quality at the same time. Adapt the concepts of DRY and YAGNI. You will often come to the Situation, where you look at your Code and imagine that you could have done that "better". Don't let this thought prevent you from sleeping. Take action immediately and Refactor! If you don't do it now, you will probably never do it. The longer you wait, the harder and more costly it gets. And you slowly grow up a mess you cant deal with anymore.
"Good code is code that is easy to change. Code tends to change until it is no longer easy to change. All code becomes bad code." - Unknown

Removal of dead / commented out Code

If you experience dead or commented out code that is not required anymore, but you dont want to delete it because you dont know if you'll still need it in the future - DELETE IT RIGHT NOW!! Its your versioning tools's job to remember that code, not the comment's!!!! I've seen too much software filled with tons of commented out Code that no one can even remember any more. And then if you cant remember, you are easily even more afraid to delete it. Well, just delete it - now - for real.
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." - Antoine de Saint-Exupery

Making Mistakes

Nobody is perfect and everyone makes mistakes. Making mistakes is a process of learning. There is no improvement if you don't make or recognize any mistakes. So: Everytime you make a mistake, you learn something new greatly improving your knowledge. The more mistakes you make and recognize the better you get. Also, there is no point in hiding your mistakes or feeling ashamed for them. Being honest and frankly about your mistakes makes you a great character and a reliable colleague. Therefor criticism, in a constructive way, is an important tool for successful teams.
"Anyone who has never made a mistake has never tried anything new." - Albert Einstein

Showing your code to others

Are you afraid of other people reviewing your code? Why is that? Did you not write as good as you could have? Well, then its probably not an adequate job for you. Are you afraid that you have made any mistakes? Well you shouldn't - because you could benefit of every mistake that you have made that is found in the review - see "Making Mistakes". You should always write your code as thoughtful as you can. Therefor you should rather be proud of what you have written, and not be afraid of others having a look at it.

Failure

And this is one of the most important. If you come to a point where you dont see any solution for your problem: Never give up hope. Take it as a challenge. Try to see things from another angle or explain to other people. Maybe you are just stuck in the wrong perspective. Successfully solving this ridiculous puzzle will make you an even stronger Developer.
"I have not failed. I've just found 10,000 ways that won't work." - Thomas A. Edison

Your own codes stability

Everyone knows this situation. You come to present your project to your boss or the customer, and you start worrying: "Will it work this time!? Hopefully i havent overlooked anything in the process of development!". This is a bad sign, and you shouldn't have to worry. You should rather have tested your project deliberately earlier. Of course, You can never make  100% sure that it works perfectly. But you can greatly improve the trust in your code by writing automated tests. It makes you feel more comfortable adapting changes and showcasing your software.

New & Complex Technology

Developers are lazy and often sit on their "good ol" technology way too hard. IT is improving incredibly fast, new and better technology is born every day. Be open minded, read blogs and stay up to date. If a technology/framework seems to exactly fit your needs, give it a try. Also show it to your colleagues an spread the word. This is a great story about developers being afraid to try something new.

Fighting Time Pressure

Do not ever let time pressure ruin the Quality of your Project. It is your Job to keep your Code clean and stable. Quality requires deliberate decision making and takes time. And sometimes you need to fight for it. Your customer expects a 100%, maybe even 120%, complete Product that is maintainable and state-of-the-art. If you let the quality down and deliver a poor Result, you will end up in even more changerequests, maintenance effort and distrust. The time you saved earlier will be eaten up by the technical debt that you allowed. Also if you allow a single leak, the inhibition of allowing many more significantly drops. Be honest with your boss and show some backbone when it comes to Quality.
"Programming is like sex: one mistake and you’re providing support for a lifetime." - Michael Sinz

Saturday, March 9, 2013

Wanna Cache? Decorate!!

The Decorator Pattern

Class Diagram:

Decorator Pattern is one of the most powerful Design Patterns, and its important to understand why. It allows you to add functionality to a Class without changing it. You use delegation instead of inheritance by just wrapping the existing Class in a "Suite" of your choice while the Interface stays the same. This way, you can even wrap a Class into multiple layers of Decorators where every Layer has its own and different purpose, and the Original Class even stays the same. Other than that the Layers are completely interchangeable and removable, because they all have the same Interface.
You can use your naked Object in the same manner as a decorated one with multiple Layers, and the rest of the Application wont even notice. Other components dont need to know whether a Class is decorated or not, because the only thing they care about is the Interface. The following Graphic should clear things up:
Just follow the Steps:
In the first example there is no Decorator. So SomeClass directly speaks to BookService
In the second example there is a single Decorator. Therefore the following steps apply
  1. SomeClass calls SomeDecoratorA.
  2. SomeDecoratorA delegates the call to the real BookService. The Decorator could even manipulate the call in this step.
  3. BookService returns a result. SomeDecoratorA now holds the result, and may manipulate it.
  4. Finally, SomeDecoratorA hands the result over to the original caller SomeClass.
In the third example, there are even 2 Nested Decorators. Since every Decorator speaks the Interface of the BookService Class you can wrap an infinite amount of Decorators upon.

Usage Examples

Most examples in Books and online Guides describe the Decorator Pattern used by some Graphic related stuff. You would have a normal line, and a line decorated with a shadow. Another example would be a Window in a GUI where you vary Decorators that add different kinds of styles (e.g. different Colors).

But its important to understand, that Decorators are not intended to just make Styling more dynamic. It is just one way to use them. Instead, there are many more great use cases for Decorators and i will show you an example applying cache functionality.

Applying Cache with Decorator Pattern

Class Diagram:

As you can see i am adding a BookServiceCacheDecorator that holds a Cache Component which temporarily stores a List of Books. The BookServiceCacheDecorator in the first place asks the Cache if there is a result available. If thats true, the decorator will use the cached result. Otherwise it will fetch the Result of the BookService itself, and store the Result in the Cache for later use.

I start with the BookService Interface,

1
2
3
public interface BookService {
    public List<Book> findAll();
}

and its prime implementation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class BookServiceImpl implements BookService {

    @Override
    public List<Book> findAll() {
        System.out.println("load new data");
        List<Book> books = new ArrayList<Book>();
        books.add(new Book("BookA"));
        books.add(new Book("BookB"));
        books.add(new Book("BookC"));
        return books;
    }
}

Here is the Code of the Cache Class. In this example it's caching forever, but thats alright.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class Cache {

    private List<Book> storage;

    public void save(List<Book> books){
        this.storage = books;
    }

    public boolean hasResult(){
        if(storage != null){
            return true;
        }

        return false;
    }

    public List<Book> load(){
        System.out.println("load from cache");
        return storage;
    }
}

Now lets continue with the Decorator Base Class. It has a preemtive Constructor to hand over the decorated Object.

1
2
3
4
5
6
7
8
abstract public class BookServiceDecorator implements BookService{

    protected BookService decorated;

    public BookServiceDecorator(BookService decorated){
        this.decorated = decorated;
    }
}

And finally the CacheDecorator. It Checks the Cache before calling BookServiceImpl.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class BookServiceCacheDecorator extends BookServiceDecorator {

    private Cache cache;

    public BookServiceCacheDecorator(BookService decorated) {
        super(decorated);
    }

    public BookServiceCacheDecorator(BookService decorated, Cache cache) {
        super(decorated);
        this.cache = cache;
    }

    @Override
    public List<Book> findAll() {
        if(cache.hasResult()){
            return cache.load();
        }
        List<Book> books = decorated.findAll();
        cache.save(books);
        return books;
    }
}

Now two different use cases. One without Decorator, and one with the Cache Decorator:

1
2
3
4
5
6
7
8
9
BookService bookService = new BookServiceImpl();
bookService.findAll(); // prints: load new data
bookService.findAll(); // prints: load new data
bookService.findAll(); // prints: load new data

BookService cachedBookService = new BookServiceCacheDecorator(new BookServiceImpl(), new Cache());
cachedBookService.findAll(); // prints: load new data
cachedBookService.findAll(); // prints: load from cache
cachedBookService.findAll(); // prints: load from cache

Thats basically it. Just read the Code carefully. The final use cases should make clear how the Decorator applies functionality. Decorator pattern really helps you create a very modular Code in many circumstances. You should not be afraid of the additional Classes the Pattern depends on, since they are really not a big deal. The modularity gained easily outweighs them.

Wednesday, March 6, 2013

Avoid too many Parameters using the Builder Pattern

Today i want to show you another way to use the Builder Pattern. From what i've seen there are tons of examples of the Builder Pattern online. But they do all have one thing in common: They are used to create an Instance of an Object and "replace" its constructor. This way you can create a complex Object in a very clean and readable fashion using a Fluent Interface.

Other than that, there is also a slightly different way you can benefit of the Builder Pattern. Think of a Method with like 10 Parameters. Thats not quite nice, and should not ever happen. Robert C. Martin recommends a maximum amount of 3 Parameters in his book: Clean Code. You should rather use some kind of a Config Object holding those 10 parameters, to clean it up. But lets say, you have a BookService Class with a find(..) method, that allows to search by 10 different parameters, and every single one of them is optional. You could use the Builder Pattern with some kind of Query Object to solve the problem.

As we should always program against Interfaces to keep things modular, ill start with the Interface:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface BookService {

    public Book create(Book book);

    public void delete(String isbn);

    public Query query();

    public interface Query {

        public Query isName(String name);

        public Query hasAuthor(String author);

        public Query isCheaperThan(Float price);

        public Query isIsbn(String isbn);

        public Query hasMorePagesThan(Long pages);

        public Query isAvailable();

        public List<Book> find();

    }
}

So the Interface looks pretty neat. It allows you to write something like:

bookService.query().hasAuthor("Bob").isCheaperThan(20.9).isAvailable().find();

While the Query could be considered as an implementation of the Query Object pattern it is not tied to any Database related stuff, which is very important. You dont want to be tied to Criteria Queries or SQL in this Layer. It should be independent of any implementation (e.g. Database or Filesystem).

To clear things up, i want to show you an implementation example using Spring-Data. I am a big fan of Spring-Data, since it allows you to create full featured DAOs with little to no Programming effort for many different Persistence Providers. If you havent used it yet, you should definitely give it a try.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@Transactional
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    // ...

    @Override
    @Transactional(readOnly=true)
    public Query query() {
        return new QueryImpl(this.bookRepository);
    }

    public class QueryImpl implements Query{

        private BookRepository bookRepository;
        private Specifications<Book> filters = null;

        public QueryImpl(BookRepository bookRepository) {
            this.bookRepository = bookRepository;
        }

        private void addFilter(Specification<FlowMessage> filter) {
            filters = (filters == null) ? where(filter) : filters.and(filter);
        }

        public Query isName(String name) {
            if (name == null) return this;
            addFilter(BookSpecifications.isName(name));
            return this;
        }

        public Query hasAuthor(String author) {
            if (author == null) return this;
            addFilter(BookSpecifications.hasAuthor(author));
            return this;
        }

        // other criterias ...

        public List<Book> find() {
            return this.bookRepository.findAll(filters);
        }
    }
}

As you can see i am just joining filter Criterias together, and thats it. The implementation is really simple but also expandable. These filter Criterias are supported by my BookRepository (=DAO). I just have to define them in a helper class first. Check out this and that for a deeper understanding how to combine spring-data with criteria queries.




Saturday, March 2, 2013

Selenium Test Automation with Maven

Today i want to help you manage your Automated GUI Tests (Selenium) better. In the past i have seen many different ways people handle this. Some people just write those plain HTML TestCases with Selenium-IDE, store it somewhere on the HDD and run manually when needed. Others dont even use Selenium-IDE. They write pure Java for Example, and automate their execution with JUnit. My todays solution lies inbetween.

Precondition

  • I want plain HTML TestCases, created with Selenium-IDE. So that someone with little Programming skills can still create them.
  • I want these GUI Tests to be run automatically in my Build process, so my CI-Tool can notify me on errors.
  • I also want all TestCases under Versioncontrol in my Projects Repository since the Tests grow with the Source.
  • I want the most little effort with the highest outcome. So i dont want to export JUnit Tests out of my HTML TestCases since it would be kind of a Duplication - and i want to stick to the DRY Principle.

Solution

First of all i create a Folder in my Project for the Selenium-Tests.

Folder Structure
        1. TestSuite
        2. SomeTest1
        3. SomeTest2
  1. pom.xml

Example TestSuite

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
    <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium">
    <tbody>
    <tr>
        <td><b>Test Suite</b></td>
    </tr>
    <tr>
        <td><a href="./SomeTest1.html">SomeTest1</a></td>
    </tr>
    <tr>
        <td><a href="./SomeTest2.html">SomeTest2</a></td>
    </tr>
    </tbody>
</table>
</body>
</html>

 

Example Test

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link rel="selenium.base" href=""/>
    <title>SomeTest1.html</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
    <thead>
    <tr>
        <td rowspan="1" colspan="3">SomeTest1</td>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>open</td>
        <td>/</td>
        <td></td>
    </tr>
    <tr>
        <td>waitForElementPresent</td>
        <td>//div[@id='someId']</td>
        <td></td>
    </tr>
    <tr>
        <td>click</td>
        <td>css=button.create</td>
        <td></td>
    </tr>
    <!-- Some Steps -->
    <tr>
        <td>assertText</td>
        <td>
            //div[@id='someId']
        </td>
        <td>${expectedText}</td>
    </tr>
    </tbody>
</table>
</body>
</html>

 

Setup WebServer

So i have my TestSuite in place. But how do i run them? Most importantly, it should run within the Maven Build Process, so it will also run on Jenkins-CI or whatever. As we are testing against a real running WebApp this is an End-to-End-Test per definition. In Maven we have the opportunity to run such Tests within the integration-test Phase. If you want to learn more about the Maven Build Life-cycle and its phases check out this. So we need some kind of WebServer to run our WebApp, otherwise the tests wont work. The WebServer should be started before the integration-test phase, and be stopped afterwards. We could Use Tomcat7 or Jetty for example. In this example i will use the tomcat7-maven-plugin. I configure my pom.xml to start Tomcat7 pre-integration-test.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.0</version>
    <executions>
        <execution>
            <id>tomcat-run</id>
            <goals>
                <goal>run-war-only</goal>
            </goals>
            <phase>pre-integration-test</phase>
            <configuration>
                <port>8080</port>
                <fork>true</fork>
            </configuration>
        </execution>
        <execution>
            <id>tomcat-shutdown</id>
            <goals>
                <goal>shutdown</goal>
            </goals>
            <phase>post-integration-test</phase>
        </execution>
    </executions>
</plugin>

If you are running multiple Projects on a CI-Server you might consider using a different Port-Number for each Project.

Finally: Run the Tests

Last but not least we need to run the tests. Luckily there is this selenium-maven-plugin available that does the job.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>selenium-maven-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <browser>*firefox</browser>
        <suite>src/test/selenium/TestSuite.html</suite>
        <startURL>http://localhost:8080</startURL>
    </configuration>
    <executions>
        <execution>
            <id>run-selenium-tests</id>
            <phase>integration-test</phase>
            <goals>
                <goal>selenese</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Now,  whenever we execute mvn clean verify or even mvn clean install in console, the Tests are run and reports are stored within the target directory. This will also be done by your CI-Tool.

Conclusion

We do have a complete and clean Setup.
  • We have a place to store our Tests,  
  • They are within the Sourcecode and Version control
  • They can be run automatically by CI-Tools
  • Even Non-developers can add new TestCases
Btw: Dont give up if something is not working as intended. Selenium seems a little buggy, and some times you have to dig a little to solve problems. But it really works, i figured it out.
I hope you enjoyed this Guide. Greetings.