tag:blogger.com,1999:blog-11788053121542101592024-03-05T21:39:02.722+01:00Be a better DeveloperQuality important is. Fight for it you must.Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.comBlogger22125tag:blogger.com,1999:blog-1178805312154210159.post-84183680347198027762014-12-19T19:22:00.003+01:002015-01-09T09:49:44.085+01:00Between the linesAs coders we are constantly making decisions. This is what we do, this is what it`s all about. It is our job. Our decisions have a lot of impact. They affect all aspects of the software, the users that are going to use it, and even the company that hires the employees that are going to use it. And of course they affect our own and our company's reputation, what problems we face when we engage upcoming tasks, the success of the project, our co-workers mood and even our own mood in the future. Bad decisions can easily make us suffer.<br />
<br />
What we do is not a routine, ever. We might have patterns, practices and problems that have already been solved. Yet still, every new decision that we make has a unique context. In fact the context changes everytime we learn and gain new experience. This is why we are engineers. This is why our work is very creative.<br />
<br />
Sometimes we make good decisions, and sometimes we make bad ones. This is true for all types of coders from juniors to masters. Sometimes we make bad decisions because we just don't know any better, due to a lack of programming-, technology- or domainknowledge. And sometimes we make bad decisions because we are being put under pressure.<br />
<br />
Bad decisions are expensive and dangerous. They produce technical debt, and it is not uncommon that they lead us to even more bad decisions. Slowly but surely this burden becomes heavier. It cost us time, energy and money. In extreme cases it gets so expensive that it would be favorable to completely start over.<br />
<br />
Willingly or not, because of the decisions we make, we coders are in great power. We are leaders, and we can easily steer towards failure. We are not just the ones to write lines. We are not just code monkeys. We are the ones who design the heart of the Software and bear great responsibility.<br />
<br />
When everyone gets mad because of a problem, maybe a date or even a deadline, we coders are the ones to stay strong. We are the ones to keep calm, and disillusion the others. We know the code, so we know the truth. If we don't stand up, whoelse should?<br />
<br />
It is hard to act professionally and responsible at any time, but it's mostly a good choice. Thankfully, code is very forgivingly in its nature. Technology nowadays allows us to easily change it, thus allowing us to revert our decisions. We should value changeability in the code. We should even take action to improve changeability in the code. Maybe that'd be a good choice!?<br />
<br />
I would like to end this post with a quote by <a href="https://twitter.com/WoodyZuill">@WoodyZuill</a>:<br />
<blockquote class="tr_bq">
<span style="color: #292f33; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="line-height: 22px; white-space: pre-wrap;">„</span></span><span style="background-color: white; color: #292f33; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 22px; white-space: pre-wrap;">Be the programmer you want to see in the world.</span><span style="color: #292f33; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="line-height: 22px; white-space: pre-wrap;">“</span></span></blockquote>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-4010794286634055302014-07-11T15:04:00.001+02:002017-10-12T10:35:18.494+02:00Improve your Feedbackloop with Continuous TestingHave you ever though about what the most valueable thing in software development was for you? And im not talking about things that value for you personally, but for the success of the development itself. Well i have thought about it, and for me it was Feedback - in any form. It is so important, because it enables steering. Development practices are made for the purpose of better
feedback. TDD, Continuous Integration, Iterations, to name only a view. Many of the agile methods and XP are basically about better feedback.<br />
<br />
It begins with customer interaction. I need as much feedback as possible, as frequent as possible. If i don't get feedback, i'm likely to get on the wrong track, resulting in a product that is not going to be used, because it's not what the customer needed. The more feedback i get, the better the outcome will be. If i get feedback rarely, i am unable to steer. I'm forced to make assumptions which are likely just obstacles. The quicker i get feedback, the faster i can deliver value to my customer. Feedback allows me to steer. <br />
<br />
Feedback is as important for programming. I want it early and often. If i write hundreds of lines of code without running them, they will most likely result in a very long and painful debugging session, and a lot of changes. I don't want that, so i take baby steps. They make me go safer, faster and happier. There are two phases that define my programming feedback loop.<br />
<ol>
<li>The phase where i write code. Lets call it <span lang="grc">alpha, like so '<span style="color: #cc0000;">α</span>'. </span></li>
<li>The phase where i evaluate my code, and eventually fix errors. Lets call it beta, like so '<span style="color: #38761d;">β</span>'.</li>
</ol>
You could also see those phases as modes. It is important to understand here, that these phases have nothing todo with the alpha/beta definition of a software cycle. I just invented them to describe my programming feedbackloop.In the following graphics you'll notice that the lines get shorter and shorter by example which is intentional and should point out how i got faster using new strategies.<br />
<ol>
</ol>
When i first started coding, i did not write any tests. I wrote lots of code before i tried it out manually. Obviously it didn't work when i first ran it. I ended up in rather long <span lang="grc"><span style="color: #cc0000;">α-phases</span>, where i just wrote code, and also long <span style="color: #38761d;">β-phases</span>, where i evaluated (got my feedback), and fixed it. Like this: </span><br />
<span lang="grc"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7_3uxYRwxEwTbELZlWTRXgdtu80dIBDAzn0jPtzAXRutY0P860qa_U1PImaia6enkOGUITdncTbj4L8zHEh14H2u-k-oZ_6j3-y7fKxLrJv4qySV-3jMxIvODFyuyR6DrszJIGb19A4Q/s1600/slow.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="75" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7_3uxYRwxEwTbELZlWTRXgdtu80dIBDAzn0jPtzAXRutY0P860qa_U1PImaia6enkOGUITdncTbj4L8zHEh14H2u-k-oZ_6j3-y7fKxLrJv4qySV-3jMxIvODFyuyR6DrszJIGb19A4Q/s1600/slow.png" width="640" /></a></div>
<br style="clear: both;" />
<span lang="grc">I was very slow back then.</span><br />
<span lang="grc"><br /></span>
<span lang="grc">I soon started with an interpreted language, which was very cool because i could run the scripts immediately. No need to compile or anything. Just write and run. It shortened my feedback loop, and </span><span lang="grc">i became faster overall:</span><br />
<span lang="grc"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXSmRba_5YG6s7JROaH_pzWH3RBldvStO0xB2OhjMKVs0biUGlD4MCC1Lru2AB1enXgqP4HO8id4vJU1BZ4I229e4hPKSeSRP0qSmN-ZHBgFHAKDy71KroVVWCm49nToVsB1-AZE9AiIs/s1600/medium.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXSmRba_5YG6s7JROaH_pzWH3RBldvStO0xB2OhjMKVs0biUGlD4MCC1Lru2AB1enXgqP4HO8id4vJU1BZ4I229e4hPKSeSRP0qSmN-ZHBgFHAKDy71KroVVWCm49nToVsB1-AZE9AiIs/s1600/medium.png" width="640" /></a></div><br style="clear: both;" />
<span lang="grc">Sooner or later i eventually started tdd. And regardless of the language that i was using, interpreted or not, it again shortened my feedback loop and made me go faster. The loop was shortened to a single 'unit', which is obviously smaller than anything manually executable. It allowed me to evaluate small behaviours, long before the program was even runnable.</span><span lang="grc"> It is important to understand, that the </span><span lang="grc"><span lang="grc"><span style="color: #cc0000;">α-phase</span></span> in the following graphic contains both writing tests and implementation. The </span><span lang="grc"><span lang="grc"><span style="color: #38761d;">β-phase</span></span> is much shorter, since unittests run very fast.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoj4qjrBRPRJXN-hfX0Gd1svyMsZRSwuOyrcVCE5WiyhgL2HLpCCO3XAx9BSHiHKGOvd2V-7Yu8oZ545V1hhYaIyDKx7vaog3DFtOkbyuxGhYVd52Owo-DD7ITBzVT-TlNSupVSVBP2sA/s1600/fast.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoj4qjrBRPRJXN-hfX0Gd1svyMsZRSwuOyrcVCE5WiyhgL2HLpCCO3XAx9BSHiHKGOvd2V-7Yu8oZ545V1hhYaIyDKx7vaog3DFtOkbyuxGhYVd52Owo-DD7ITBzVT-TlNSupVSVBP2sA/s1600/fast.png" width="640" /></a></div>
<br style="clear: both;" />
<span lang="grc">I thought this was just great, and it could not get any better. Wrong i was!! Later, i tried something that made me go like this:</span><br />
<span lang="grc"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ6FzeQtnXyGJVVpRNwcY7wxL8klfO-5n7qEXwIChET2K63jant8UCgojH7EskAbFuRpNRDCHOn4zhGxtoJa7zM_4F45jnq1e5J9PEGmfi4HvF90rW47R9p0Iw6JiLA729Ja-n6VgP9Qg/s1600/fastest.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="60" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ6FzeQtnXyGJVVpRNwcY7wxL8klfO-5n7qEXwIChET2K63jant8UCgojH7EskAbFuRpNRDCHOn4zhGxtoJa7zM_4F45jnq1e5J9PEGmfi4HvF90rW47R9p0Iw6JiLA729Ja-n6VgP9Qg/s1600/fastest.png" width="640" /></a></div>
<br style="clear: both;" />
<span lang="grc">"What the ...?" You might ask. No, i did not break space-time. The thing i tried was Continuous Testing. Which basically means, that i do tdd, but i don't run my tests by pressing a button and then wait. I just have them run all the time in the background automatically... Everytime i change my code, my tests immediately run automatically, and show me "OK" or "NOT OK" on a small icon on my screen. Since the tests only take about a second to run, this feedback is instant. And since my IDE saves my files onchange automatically, i do not have to press ctrl+s or anything. I just code... and as i code my files get saved.... and as the files get saved my tests get run... fluently, immediately. This is HUGE. I am now progressing without disruption. I completely broke out of the phases, or if you want to call them 'modes'. I love it.</span><br />
<span lang="grc"><br /></span>
<span lang="grc">I have used <a href="http://infinitest.github.io/">infinitest</a> for this. It is a Continuous Testing plugin for Intellij/Eclipse. If you are doing javascript, i can also recommend <a href="http://gruntjs.com/">grunt</a> for Continuous Testing.</span>Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-47061048746040434522014-06-03T19:43:00.001+02:002014-06-03T20:57:32.671+02:00About the „Is TDD Dead?“ discussionIt did not take long after <a href="http://pragdave.me/blog/2014/03/04/time-to-kill-agile/">Agile</a> died that TDD joined its party. If you havent noticed, <a href="https://twitter.com/dhh">David Heinemeier Hansson</a> put up quite a <a href="http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html">rant</a><b> </b>against TDD on his blog leading to a lot of discussion - also on Twitter. Finally they ended up doing a live online discussion regularely featuring <a href="https://twitter.com/KentBeck">Kent Beck</a>, <a href="https://twitter.com/martinfowler">Martin Fowler</a> and David not (yet) involving the TDD advocate <a href="https://twitter.com/unclebobmartin">Robert C. Martin</a> aka uncle bob. If you haven't watched it live, here is the initial <a href="https://www.youtube.com/watch?v=z9quxZsLcfo">30min discussion of the series on Youtube</a>. I really recommend the whole series.<br />
<br />
I think this topic and the ongoing discussion is very valueable to our craft because it is the kind of questioning and critical thinking that evolve what we do and how good we are at it. Even if we have a strong faith in something, we should not be afraid to question it, ever.<br />
<br />
I get davids points, however i do not entirely agree with all of his concerns. I want to share my thoughts in this blogpost.<br />
<br />
<blockquote class="tr_bq">
<span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b>„Test induced design damage“</b></i></span></span></blockquote>
A good design is a design that makes the software easy to change. I think this is something we all agree about. While TDD generally puts a lot of good pressure on your design, it can still make the code hard to change if you apply a high level of isolation, lots of mocking, and a high test-granularity. In this case refactorings and other changes will force us to touch a lot of test-code also. So i've come to the conclusion that its best to apply an individual level of test-isolation/granularity that suit the current requirements. Complex and/or long-lived software might take much value of a strict TDD approach, while simple and/or short-lived software might take more value of a more pragmatic approach. I've happened to experience lots of applications that were so big yet simple that "collaborating-units-tests" with reduced mocking and integration tests were just perfect. The value of this approach was that it was very easy to change/refactor production code without touching test-code. Still, the tests provided 100% functional coverage. So i think that design damage is not induced by tests or tdd, but by bad decisionmaking. Testing is engineering. Look for advantages, make tradeoffs. Trying to minimize mocking can definitely pay off. The advantages of a high test-isolation-level/granularity are<br />
<ul>
<li>a very accurate fault-feedback,</li>
<li> and that every part of the code is executed just as much as it had to, leading to a faster test-suite</li>
</ul>
<br />
<blockquote class="tr_bq">
<span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b><span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b>„</b></i></span></span>To Test first, or not to Test first</b></i></span></span><span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b>“</b></i></span></span></blockquote>
The point is, you do not want to verify if the code is working manually. You'd have to do it way too often, and it would just take too long. You want to be able to fiddle with the code, and do small changes frequently, without having to try everything out manually. You want to do it automated, and the feedback should be instant. So i see no point in 1. writing code, 2. trying it out, and then 3. writing a test. Why not write the test in the first place? Also, we tend to be very flaccid on writing a test for something that we have found to be working, because we tend to become euphoric about our success very quickly which makes us tired of digging in details. Other than that, the actual writing of the test first forces us to think about the problem to an extent that makes us recognize details, that we hadn't yet thought of. These details are better to be known before we start writing production code.<br />
<br />
<blockquote class="tr_bq">
<span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><b><i><span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b>„</b></i></span></span>TDD is so widespread nowadays</i></b></span></span><span style="font-size: x-large;"><span style="font-family: Times,"Times New Roman",serif;"><i><b>“</b></i></span></span></blockquote>
I was laughing when i noticed that there are actually people who believe that everyone does tdd nowadays. Sadly, TDD, or lets say developer testing is in fact unused and/or undiscovered in many places. I've happened to see it missed in programming education and also software companies. Sometimes, it was even unwelcome by certain customers. If you were using any kind of developer testing in these places, you were a pioneer. There is still plenty of work to do on this topic.<br />
<br />
The bottom line is, automated developer testing is good. We need it. We were silly if we didn't. The question is just: "How?". And this is where engineering comes in.Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-23621087713813019502013-12-20T20:15:00.000+01:002013-12-22T17:07:37.308+01:00An Annotation Nightmare<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@XmlElementWrapper</span><span style="color: #333333;">(</span>name<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"orders"</span><span style="color: #333333;">)</span>
<span style="color: #555555; font-weight: bold;">@XmlJavaTypeAdapter</span><span style="color: #333333;">(</span>OrderJaxbAdapter<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">)</span>
<span style="color: #555555; font-weight: bold;">@XmlElements</span><span style="color: #333333;">({</span>
<span style="color: #555555; font-weight: bold;">@XmlElement</span><span style="color: #333333;">(</span>name<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"order_2"</span><span style="color: #333333;">,</span>type<span style="color: #333333;">=</span>Order2<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">),</span>
<span style="color: #555555; font-weight: bold;">@XmlElement</span><span style="color: #333333;">(</span>name<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"old_order"</span><span style="color: #333333;">,</span>type<span style="color: #333333;">=</span>OldOrder<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">)</span>
<span style="color: #333333;">})</span>
<span style="color: #555555; font-weight: bold;">@JsonIgnore</span>
<span style="color: #555555; font-weight: bold;">@JsonProperty</span>
<span style="color: #555555; font-weight: bold;">@NotNull</span>
<span style="color: #555555; font-weight: bold;">@ManyToMany</span>
<span style="color: #555555; font-weight: bold;">@Fetch</span><span style="color: #333333;">(</span>FetchMode<span style="color: #333333;">.</span><span style="color: #0000cc;">SUBSELECT</span><span style="color: #333333;">)</span>
<span style="color: #555555; font-weight: bold;">@JoinTable</span><span style="color: #333333;">(</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"customer_order"</span><span style="color: #333333;">,</span>
joinColumns <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@JoinColumn</span><span style="color: #333333;">(</span>name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"customer_id"</span><span style="color: #333333;">,</span> referencedColumnName <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"id"</span><span style="color: #333333;">)</span>
<span style="color: #333333;">},</span>
inverseJoinColumns <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@JoinColumn</span><span style="color: #333333;">(</span>name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"order_id"</span><span style="color: #333333;">,</span> referencedColumnName <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"id"</span><span style="color: #333333;">)</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">private</span> List orders<span style="color: #333333;">;</span>
</pre>
</div>
<br />
Wait. What? Is this really what we have come to? I can't even see the damn property under this bloat. How did this happen? Yeah ok - we had to get rid of the old xml configuration horror somehow. But this? This is even WORSE. This class is supposed to be a goddamn pojo with a bunch of properties. Short and concise, easy to read. I, as a reader of this cass, am not interested at all how the database table is joining customers to orders. I'm neither interested how its being serialized. This is just implementation details. Reading this class, i am living in an object world and i want to know what data and behaviour the object has. Not more, not less. I don't care about column names, fetchtypes or json serialization for the moment. And i don't want to read, change or recompile this class for the sake of a tablename change. I don't want to add another annotation for storing this entity in a mongoDB neither. The entity should not have responsibility for these details. We are not only violating the Single Responsibility Principle here, we are doing a f****** responsibility party.<br />
<br />
Ok ok, enough of the rage. How do we deal with this issue? Some duplicate the entity for various layers with different annotation purposes. They map the entity onto the next layers related entity using an automated mapper like Dozer. Some even write that mapping themselves. But this is by no means a solution. It is just replacing one code smell with another one: Duplication.<br />
<br />
So please, focus on frameworks that don't force you to clutter your code. <a href="http://www.jooq.org/">jOOQ</a> is a nice solution to map database records to entities without annotations. Also, hibernate allows you to define your mappings in XML.<br />
<br />
<h3>
Private Field Injection</h3>
<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Inject</span>
<span style="color: #008800; font-weight: bold;">private</span> MyService myService
</pre>
</div>
<br />
This is used quite often, while it shouldn't even be possible. The myService field is private, thus it's inaccessible from outside the class. Nevertheless it's possible and people do it. In reality it is a hack. The DI-framework sets the field using reflections doing setAccessible(true). You don't want hacks in your code, do you? Lets have a look at the alternatives:<br />
<br />
<b>Setter Injection</b><br />
Well, at least its better than the private field injection, since its using a public method instead of hacking a private field. But still, ask yourself this: 'Is this class even supposed to live without the injected value?' Because if it's not, there is no reason what so ever for the class to get constructed without an instance of MyService. You want to implement this constraint on the class level and inside the constructor, not on the framework level.<br />
<br />
<b>Constructor Injection</b><br />
This is usually the way to go. It allows you to<br />
<ul>
<li>make the field immutable (there is usually no need to change it).</li>
<li>implement the constraint, that the class is not instantiatable without a given <i>MyService</i> in the right place.</li>
</ul>
Of course it means that you cannot inject by annotation. But why would you want to? The class doesn't need to know, if it gets injections by a DI-Container or a Factory Class. It should not know anything of this. No @Autowired, no @Qualifier. All it needs to know is its own behaviour. Everything else should be handled outside of the class.<br />
One could use a configuration class or file for the actual injection.<br />
<br />
A DI-Container is a usefull tool that helps you wire your classes together. Use it for this purpose, but don't let it dictate your code. Uncle Bob wrote a great <a href="http://bit.ly/1hrE1Kf">post</a> where he explained how to use DI-Frameworks without having them dictate your code. <br />
<br />
<h3>
<complete id="goog_238306818">@RunWith(SpringJUnit4ClassRunner.class) in UnitTests</complete></h3>
<complete id="goog_238306818"></complete>Why would you need this in unittests? Because it is automatically generated by your IDE/app template? No! You want to test the behaviour of a class, living in isolation in unittests. Not if the DI-Conainer is injecting a fields accordingly. Just inject yourself in a setup method. No DI-Container needed. By the way, all this testrunner does is these 3 lines of code.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">private</span> TestContextManager testContextManager<span style="color: #333333;">;</span>
<span style="color: #888888;">//..</span>
<span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">testContextManager</span> <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> TestContextManager<span style="color: #333333;">(</span>getClass<span style="color: #333333;">());</span>
<span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">testContextManager</span><span style="color: #333333;">.</span><span style="color: #0000cc;">prepareTestInstance</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">);</span>
</pre>
</div>
<br />
They are not worth blocking your only TestRunner slot. You want to keep it free for something like parameterized <i>@RunWith(<span class="ifClosed" id="crumb_links">JUnitParamsRunner.class)</span></i> or concurrency <i>@RunWith(ConcurrentJunitRunner.class)</i> tests.<br />
<br />
<h3>
@Override</h3>
Really, my IDE already knows if i am correctly overriding a method. To me, its just clutter.<br />
<br />
<h3>
@SuppressWarnings </h3>
... Don't even get me started<br />
<br />
<i><b>tl;dr</b></i><br />
<i>Annotations have become more harmful than helpful these days. We should get back to pojos and focus on keeping our code as clutterless and framework-agnostic as possible to make it more readable and reuseable. Don't let frameworks dictate your codebases, since they should be exchangable tools. Beware of what a class should know, and what not. Some annotations are useful, most aren't.</i><br />
<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@DevNull</span><span style="color: #333333;">({</span></pre>
<pre style="line-height: 125%; margin: 0;"><span style="color: #333333;"></span> <span style="color: #555555; font-weight: bold;">@SuppressWarnings</span></pre>
<pre style="line-height: 125%; margin: 0;"><span style="color: #333333;"></span> <span style="color: #555555; font-weight: bold;"><span style="color: #555555; font-weight: bold;">@Autowired</span><span style="color: #333333;">,</span> </span>
<span style="color: #555555; font-weight: bold;"><span style="color: #555555; font-weight: bold;">@Inject</span><span style="color: #333333;">,</span> </span></pre>
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;"></span> <span style="color: #555555; font-weight: bold;"><span style="color: #555555; font-weight: bold;"><span style="color: #555555; font-weight: bold;">@Override</span><span style="color: #333333;">, </span></span> </span></pre>
<pre style="line-height: 125%; margin: 0;"> <span style="color: #555555; font-weight: bold;">@XmlElementWrapper</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@XmlJavaTypeAdapter</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@XmlElement</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@JsonIgnore</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@JsonProperty</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@ManyToMany</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@Fetch</span><span style="color: #333333;">,</span>
<span style="color: #555555; font-weight: bold;">@JoinTable</span>
<span style="color: #333333;">})</span>
</pre>
</div>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-40788159461818576272013-11-28T23:17:00.000+01:002013-12-02T22:50:00.117+01:00Sessions, a Pitfall.I got asked quite often, why one shouldn't use sessions and whats so bad about them. In this post i want to sum up my thoughts and experiences.<br />
<br />
<h3>
Sessions produce unnecessary complexity </h3>
The term bugfoot is a combination of bug and bigfoot. It's used for a bug that appears only once and is not reproducable. A bugfoot tells you that something is wrong, and that it will probably come up again. But you cannot fix it, because you don't know the cause.<br />
<br />
If you want bugfoots in your software, just use sessions. Sooner or later you'll happen to see one.<br />
<br />
<h3>
Sessions don't scale </h3>
Lets say you are a professional chess player, and you'd like to play
multiple people at the same time. If you'd try to remember every game
and your strategy on it, you'll hit your capacity rather quick. Now
imagine you were not remembering anything of those games, and you were just rereading the chessboard
on every move. You could literally play 1.000.000 people at the same
time, and it wouldn't make any difference to you. <br />
<br />
Now draw an analogy to your server. If your application gets a lot of load, you might have to distribute it to different servers. If you were using sessions, you'd suddenly had to replicate all sessions to all servers. The system would become even more complex and error prone.<br />
<br />
<h3>
Sessionstate cannot be bookmarkable nor cachable</h3>
Did you try to bookmark your shopping cart? Nah, of course you can't because it's empty as soon as the session runs out. Imagine a shop that actually allowed you to bookmark your cart. Like<br />
<ul>
<li>http://example.com/carts/1337 or</li>
<li>http://example.com/cart?products=[{id:1, amount: 1}]</li>
</ul>
How wonderful that would be.<br />
<br />
<h3>
Conclusion</h3>
You want a simple system that is easy to test and whose bugs are easy to reproduce. State leads to the opposite. HTTP was never ever ment to be stateful and it should have stayed this way. <br />
<br />
If you want some rest, follow these two rules<br />
<ul>
<li>Keep all application state (not resource state) on the client </li>
<li>Keep all shared state (not session state) on the server</li>
</ul>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-36569636021432123242013-10-15T20:46:00.001+02:002017-10-12T10:32:21.799+02:00Boost your development speedI'm really pragmatic on this. To go faster, you need to avoid the things that slow you down. These blockers may vary from developer to developer, but some are pretty common. In this post i will elaborate on the more common ones. Before i do so i want to remind you that to improve, we might need to unlearn in the first place.<br />
<blockquote class="tr_bq">
<i><b>Tip:</b> Sometimes, the greatest achievement in improving is to successfully unlearn.</i></blockquote>
<br />
<h3>
Are you using your Mouse?</h3>
Don't let your mouse slow you down. If you are not using all of your fingers typing, you might want to stop reading here and go over to a <a href="http://www.learntyping.org/">typewriting course</a>. The following recommendation also assumes that you are using a feature rich editor like <a href="http://www.vim.org/">vim</a> or an ide. Every single time you move your hand over to your mouse for a click there is a keyboard shortcut for the exact action that you are not aware of, or not used to. You want to learn these. It's really not that hard, you'll get used to it faster than you'd think. Just begin by putting your mouse over to the other (or wrong) side of your keyboard. You're now forcing yourself to think every time you want to click. When this happens, remember to think of a possible solution using your keyboard. Don't know any? Ask your friends or search the internet (yes, you can use your mouse for that). BUT: Do not use your mouse for what ever action you wanted to perform. After following these simple rules for a few days, you'll notice how irrelevant your mouse has become. If you start feeling comfortable using your keyboard only, you could even try some sessions with your mouse plugged out.<b> </b>Mastering your keyboard will significantly boost your development speed.<br />
<blockquote class="tr_bq">
<i><b>Tip:</b> You could print out a list of your IDEs shortcuts and use it as a cheatsheet</i></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3bib-qZUnj6zMmotbLWAN2WIldfmdOAvLSQqYgYOWTUAcfVJOWT-smNpATLUcSfwKv0Ylfi3J2Tf5XOvLMPkm1k8NvLu940lnaHfLyYXqzXWiRH_BYF0KW6DcfTbOggE4g4nBj7sWvhk/s1600/mouse-kill.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3bib-qZUnj6zMmotbLWAN2WIldfmdOAvLSQqYgYOWTUAcfVJOWT-smNpATLUcSfwKv0Ylfi3J2Tf5XOvLMPkm1k8NvLu940lnaHfLyYXqzXWiRH_BYF0KW6DcfTbOggE4g4nBj7sWvhk/s1600/mouse-kill.jpg" /></a></div>
<br />
<h3>
Reduce the Time debugging</h3>
Debugging costs an awful lot. It's not rare that we end up hunting a bug for hours or even days. Quite often we engage multiple co-workers to solve it. This is really not a scenario we want to be in, since its not only expensive, but also depressing. How can we avoid such a scenario? Pretty easy. Just separate the software into pieces that work in isolation, and write automated tests that cover the components behaviour. This way, we can easily distinguish the component the bug is actually sitting in, and the debugging will become a cinch. The better the tests, the easier to find the bug. However, you wont write good tests, if the system that you are testing is already done and working. You'll assume that there is no additional value of writing thoughtout tests, when it's already working. Overcome this dilemma by writing your tests BEFORE the implementation. As a side effect, this will also help you coding in many ways. You want to treat your tests as first class citizens and as what they are - at least as important as your implementation. Think of a blacksmith who's casting metal into a mold. What would be more important for him. The mold, or the first sculpture coming out of it? You know the answer. And guess what... the tests are your mold. I don't care what you call it. TDD, BDD or whatever. Just automate tests to cover your softwares behaviour, write them before the implementation, and treat them as what they are - at least as important as your implementation.<br />
<blockquote class="tr_bq">
<i><b>Tip:</b> When using TDD, you want to use a shortcut to quickly navigate between the test and its implementation. I've bound it to Alt+T</i></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRsTHVfKLaB4zIL1reCSqzsf_MNs2Z0SG9_QzjXsJDALDNvtZqyd7z7Yx0bb-UZqf22VFb_NX12gLMUOvjb0M-npuSu1nWTO6I_YDOz9JpuGAQIPAAziDVklrZXqNt_ydqHDrT9oH9uWc/s1600/mold1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRsTHVfKLaB4zIL1reCSqzsf_MNs2Z0SG9_QzjXsJDALDNvtZqyd7z7Yx0bb-UZqf22VFb_NX12gLMUOvjb0M-npuSu1nWTO6I_YDOz9JpuGAQIPAAziDVklrZXqNt_ydqHDrT9oH9uWc/s1600/mold1.jpg" /></a></div>
<br />
<br style="clear: both;" />
<h3>Reduce the Time reading code</h3>
I can't stress this enough: You spend more time reading code than writing code. Believe it or not, while implementing a new feature or solving a bug, you repeatedly read code. You read code before you start writing new code, you read code multiple times inbetween writing code, and you read code after you have written it. Reading a 50 line method is pretty time consuming. Thus you want to make reading as easy and smooth as possible. Write self explanatory code with good names and short methods. And Don't Repeat Yourself. Who wants to read anything twice? Invest some time on this, and it will pay off.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDGUR1PXY-6PlySr7OZ7mLyoKMtpur99uN_qJCxt4VRrEOt774lwXnX-dFlq7Uon3uWHVqG7_LtxhCX_MK1f5LIhDAQv-oxOZYY2jLYXgV5VXD3X4e-aZzPj6Y1hTh-bA0AhXaS-rK1Jw/s1600/y-u-so-hard-to-read.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDGUR1PXY-6PlySr7OZ7mLyoKMtpur99uN_qJCxt4VRrEOt774lwXnX-dFlq7Uon3uWHVqG7_LtxhCX_MK1f5LIhDAQv-oxOZYY2jLYXgV5VXD3X4e-aZzPj6Y1hTh-bA0AhXaS-rK1Jw/s1600/y-u-so-hard-to-read.png" /></a></div>
<h3>
Improve your search skills</h3>
This is an important one. A searchengine has become the most important development tool. It is even more important than your ide. You can do anything without your ide if you can find out how, but you cannot do anything with your ide if you dont know how. You are probably googling regularely, so it's worth improving. Improve your searchterms. Anticipate helpful words like 'how to' or 'problem'. Try different variants and quote important words and sentences. If you keep getting bad results of a common subject or website, filter them out using a preceeding minus. Here are some examples:<br />
<ul>
<li>while c -do
-c++</li>
<li>SomeException -helpme.com</li>
<li>How to "clean code" </li>
</ul>
If you keep getting out-dated information, limit your search to the last month/year. This can easily be done in the search options. On stackoverflow, do not always read the first post since its usually a question and code thats not working. Scroll down to the answers with the most upvotes. They are worth reading. Bookmark the sites/docs that you are using regularely. You don't want to search them over and over again. Also, consider code search engines (Examples <a href="http://www.makeuseof.com/tag/open-source-matters-6-source-code-search-engines-you-can-use-for-programming-projects/">here</a> and <a href="http://knightknetwork.com/2007/09/13/5-great-code-search-engines/">here</a>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTif4dU30XUTOB1SSq9wt8dLlLvqwfq3tm0YBzOh_4V4LnduM3sm1geQAPwAnhwN0mq3aJyFxF8-K_5oYCAjkDNfUB6WV_P8OLuKEIV_SfDF1eIKji6yYYDqqXVdTlbCxrwmrJRkbX-B4/s1600/search.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTif4dU30XUTOB1SSq9wt8dLlLvqwfq3tm0YBzOh_4V4LnduM3sm1geQAPwAnhwN0mq3aJyFxF8-K_5oYCAjkDNfUB6WV_P8OLuKEIV_SfDF1eIKji6yYYDqqXVdTlbCxrwmrJRkbX-B4/s1600/search.jpg" /></a></div>
<br />
<h3>
Focus & Calm</h3>
You want to get into and keep a good focus when working on a task. Get into your flow and do not allow disruptions. Several disruptions can easily cost you an hour or two each day. Use headphones in louder environments, and communicate that you'll be available for questions a little later. Focus requires a clear mind. Make sure you don't have to remember too much stuff. You don't want to be afraid of forgetting things. If you can feel the fear to forget, write that thing down - so you can forget. Also, don't work on too many different tasks/projects at the same time. One is perfect, two is ok. More is probably just slowing you down. I've happened to work on 7 different projects a single day. It's really really dragging from you. Also, stay calm even in the most stressful situation. Huddling just slows you down even more.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8HYQZ1FSz66OiXPBl4B5JWtSifek2uesv-0vAOzJrtHBgR3YbhVIskrLSnCX-Jf7Fz1TL8ylHJUjVtJ8h58qZKivjESBLEhlUzyhDvY4WNvkEyGJwhZvidiOq4nx3VrcLSywPziS8_2o/s1600/focus.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8HYQZ1FSz66OiXPBl4B5JWtSifek2uesv-0vAOzJrtHBgR3YbhVIskrLSnCX-Jf7Fz1TL8ylHJUjVtJ8h58qZKivjESBLEhlUzyhDvY4WNvkEyGJwhZvidiOq4nx3VrcLSywPziS8_2o/s1600/focus.png" /></a></div>
<h3>
Invest in Hardware</h3>
Hardware is cheap, workhours are not. Good hardware will save lots of time in the long term. An SSD that makes you boot within seconds and loads everything real quick, saves at least 10 minutes a day which is 40 hours a year. Same goes with ram and cpu of course. Also, screensize really matters. Choose a large monitor to be able to see everything without resizing/scrolling windows/panels. I personally feel comfortable with ~27". You can speed up many tasks using two monitors also. Web development would be such a task for example.<br />
<blockquote class="tr_bq">
<i><b>Tip:</b> 16:9 is standard nowadays but not quite optimal for coding. The higher the screen, the more lines of code you see. Try a 16:10 instead.</i></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_n73I1Qn24yuGtAg7z2SENo3rMD4otzrnBxrlDjfcI0ATeq8oP_xf7dWGh4k62wqgthd9W07tFKI0_QRViVq3RznwPMKMEBnwzmw9y7lWcwf2ZU1wgPBOJgstKJ6iuP4kl97f9Yf0JsQ/s1600/ridiculously-old-computer.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_n73I1Qn24yuGtAg7z2SENo3rMD4otzrnBxrlDjfcI0ATeq8oP_xf7dWGh4k62wqgthd9W07tFKI0_QRViVq3RznwPMKMEBnwzmw9y7lWcwf2ZU1wgPBOJgstKJ6iuP4kl97f9Yf0JsQ/s400/ridiculously-old-computer.jpg" width="400" /></a></div>
<br />
<h3>
Optimize your Workflow, Question your Tools </h3>
It depends on what you are working on, but the goal stays the same. You want the most lean workflow and you will constantly have to reevaluate and improve it. For example: If you are working on a Java Webapp, you want to be able to quickly get feedback without redeploying. You can do this by using a class-reloader like spring-loaded or JRebel, or use the Play Framework which does not require redeployments at all due to its architecture. You could also question the language. Is there something else than java that could be more appropriate? Automate everything: testing, building, deployment, notifications. Consider rapid prototyping if you are in the early stages of a project.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrUpFnMPgeSF5m5blG8jQW57YImiy4Be2xzCKUILHHhCFkqMAapH5XcVT1apy19YnNavDp9CYlFxBRvL1YNzQWcnNcFSvh-YbI6DK0NHlyRGR1ysHvMvxPX9v0HpySZclmaCxNCsC_ubI/s1600/workflow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrUpFnMPgeSF5m5blG8jQW57YImiy4Be2xzCKUILHHhCFkqMAapH5XcVT1apy19YnNavDp9CYlFxBRvL1YNzQWcnNcFSvh-YbI6DK0NHlyRGR1ysHvMvxPX9v0HpySZclmaCxNCsC_ubI/s1600/workflow.png" /></a></div>
<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-37167934360956045602013-08-28T22:53:00.000+02:002013-10-15T21:06:55.316+02:00Agility demands good Software DesignFrom what i have seen, Agile Software Development is widely misinterpreted nowadays. Many people think to be agile, they just need a process like scrum to define a framework of sprints and iterations. They will sprint until they exhaust and change until they stagnate. But when you'd ask them what principles of objectoriented design are, they'd answer: "Aww yes, we use classes". And when you'd asked them if they did test driven development, they'd reply: "Ahh, this is the thing where you write tests first, isn't it?". Bottom line, people think to be agile without caring about good software design. But in the end, the most important thing is what nobody cares about. It is the agility of the software that they are producing. So if you want to be agile, a process and a mindset is not enough. You need to keep your software agile. By that i mean, you need to keep the design of the software as clean and flexible as possible, to be able to apply any future changes at minimal cost. Software design of course includes your source code. In the end, you are only as agile as your software is.<br />
<br />
<h3>
<b><span style="font-weight: bold;">Why Agile?</span></b></h3>
A customer does not know what he wants in the first place. He might have a rough idea, but thats it. We cant even blame him for that, because the actual problem that we are supposed to solve is influenced by so many factors and opinions that it is almost impossible to define the best solution right away. Other than that, miscommunication will most likely make things worse. To solve these issues we start small, and deliver fast. Seeing the first result, the customer can verify if we are on track or not. He can check if we have understood, or if he himself made a bad call. He might recognize things that he hasnt thought of before. Delivering repeatedly and iteratively like that, our software will more likely be useful and accepted by the customer in the end. It will more likely lead our project to success. Of course we will have to deal with changes more often, which is why we have to make the software itself agile. In the end it is the software which needs to be changeable, not us.<br />
<br />
<h3>
What it takes </h3>
Not only does an agile development process put our software under frequent change, it also demands progress at a fast and steady pace. These facts can quickly cause our software to rot if we don't watch out. And when it does, we get slowed down even more and changes suddenly become impossible. So we'd better not forget about the most important part in agile software development: Keeping our software design as agile as possible, from high-level architecture to the very code itself. Sadly, this gets ignored way too often, and many agile projects fail because of it. They fail because they chose to go faster by neglecting quality, and they quickly rush into a deadend of code rot leading to stagnation. So please remember: It is the Software you
are building that needs to be agile in order to adapt to change defined by the customer. It is the software that needs to be agile in order to react to change with minimal effort. Rushing is not gonna make your software agile. Rushing is not gonna make YOU agile. Agility comes hand in hand with quality. And high quality is not even slow, hell no. Good quality done right makes you go even faster.<br />
<br />
<h3>
So what is Agile Software Design? </h3>
Agile Software Design is what makes your software as clean and flexible as you need it to be. It demands deliberate adoption of discovered and well established design patterns and principles of objectoriented programming. This is not easy. In fact it's hard, it's very hard. Even if you are really good and experienced at it, you might fail at some point, having to rethink many of your previous design decisions. Agile Software Design is not something that you can rush. It needs time and deliberateness. But it will pay off in the long term by making you progress at a more constant pace, which will in fact be much faster than it would be without agile design. The graphic below should clarify how quick ignorant rushing can slow you down tremendously. The graphic is not based on statistics, but on experience.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg86HK9r1SmIiGv7xRQIsLr3kbwghhvTw_xP97x5umYbZbouNafHqzBowOsVYB6N0ecytuT8r7WKTIPNm2eF1O1axE0-Y-8FDBp0wbAeWvTEMlBIbYJ89sVuRbRZlQu0MpRg5TeZCyLCbY/s1600/agile_vs_rush.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg86HK9r1SmIiGv7xRQIsLr3kbwghhvTw_xP97x5umYbZbouNafHqzBowOsVYB6N0ecytuT8r7WKTIPNm2eF1O1axE0-Y-8FDBp0wbAeWvTEMlBIbYJ89sVuRbRZlQu0MpRg5TeZCyLCbY/s1600/agile_vs_rush.png" /></a><br />
Agile Software Design does not end at high-level architecture. It goes on with coding. Bad code can quickly make your project more clumsy than a bad high-level design could. So the devil is in the details.<br />
<br />
<h3>
What can you do to make your Software Design more Agile?</h3>
<b>From a Managers perspective?</b> Trust your Developers, don't push them. Invest in experience and expertise.<br />
<br />
<b>From a developers perspective?</b> First of all, learn the principles and patterns of objectoriented programming - not just in theory. Being good at those needs lots of practice. There are plenty of books for this:<br />
<ul>
<li><a href="http://www.amazon.com/Design-Patterns-Elements-Object-Oriented-ebook/dp/B000SEIBB8">Design Patterns: Elements of Reusable Object-Oriented Software</a>,</li>
<li><a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_cc_1?s=aps&ie=UTF8&qid=1377428897&sr=1-1-catcorr&keywords=agile+software+development+principles+patterns+and+practices">Agile Software Development, principles, patterns and practices</a></li>
</ul>
and many more.<br />
<br />
Keep your code clean - don't underestimate this! When you are programming, you spend more time reading code, than writing code. Thus you want to minimize the time you have to read code by making it more readable. It's not a secret how clean code looks like. Take a look at <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code</a>.<br />
Other than that, use the right practices like<br />
<br />
<h3>
<b><span style="font-weight: bold;">Test Driven Development </span></b></h3>
Just do it already. And if you don't know how, go on and start learning. I have heard numerous opinions of TDD where people said<br />
<ul>
<li>"Unittests are too expensive. The Customer wont pay for that."</li>
<li>"Unittests slow us down, we needed to write more code in that time."</li>
<li>"I don't know. I'm pretty good at programming, Test-First feels needlessly hard and awkward."</li>
</ul>
But these are just subjective opinions of people who are not experienced in TDD.<br />
TDD should in fact boost your longterm development speed if you are doing it right. I have not seen a single project in my life that has been as small and simple as that it would not have taken a significant profit from a TDD approach. And i have in fact seen very simple ones. The thing is, you have to test it anyways. What else would speed up your testing more than to automate it? Also, TDD significantly reduces the amount of time you have to spend debugging which already eats up lots of your time - at least more than you'd think. Other than that those tests<br />
<ul>
<li>become a reliable documentation of your code,</li>
<li>allow you to fearlessly clean up your code,</li>
<li>force you to think of the problem before thinking of the actual solution, which will improve your initial draft,</li>
<li>enforce decoupling of components, which will make your design more agile.</li>
</ul>
<h3>
<span style="font-weight: bold;">Pair Programming</span></h3>
It's not only that 4 eyes will see more defects than 2 eyes do, but also that the transfer of knowledge is taking place. You want all developers to learn from each other to become equally valuable. And you always want more than one person to know a specific module to improve the <a href="http://en.wikipedia.org/wiki/Bus_factor">truck factor</a>. Heck yeah, some people even do <a href="http://mobprogramming.org/">mobprogramming</a> - Seriously.<br />
<br />
<h3>
<span style="font-weight: bold;">Collective Code Ownership</span></h3>
Don't allow one guy to own that modules code. All code on the project must belong to everybody. Everyone is allowed and invited to view, question and improve everyones code. This might be hard for some people, and might provoke conflicts, but it is absolutely mandatory to make the code better.<br />
<br />
<h3>
<span style="font-weight: bold;">Code Reviews</span></h3>
Constantly review code changes. It is the only way to stay up to date, and it will reveal code smell. You need to reveal code smell, because if you don't, you will get stuck.<br />
<br />
<h3>
<span style="font-weight: bold;">Refactoring</span></h3>
Refactor often. Everytime you see something that could be refactored, you need to do it right on the spot. The earlier you do it, the more time you save. So if you do it right then, you save the most possible amount of time.<br />
<br />
<br />
<b>tl;dr: You are just as agile as your software design, which of course includes code. High speed does not demand low quality. It doesn't work like that. In fact high quality is needed to allow high speed. Agile design evolves high quality. </b><br />
<b><br /></b>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com2tag:blogger.com,1999:blog-1178805312154210159.post-77195031489291381542013-08-12T09:46:00.001+02:002013-08-15T18:13:53.866+02:00spring-data-rest in Action<h3>
</h3>
<h3>
What is spring-data-rest?</h3>
<h3>
</h3>
<a href="http://www.springsource.org/spring-data/rest">spring-data-rest</a>, a recent addition to the <a href="http://www.springsource.org/spring-data">spring-data</a> project, is a framework that helps you expose your entities directly as RESTful webservice endpoints. Unlike rails, grails or roo it does not generate any code achieving this goal. spring data-rest supports JPA, MongoDB, JSR-303 validation, <a href="http://stateless.co/hal_specification.html">HAL</a> and many more. It is really innovative and lets you setup your RESTful webservice within minutes. In this example i'll give you a short overview of what spring-data-rest is capable of.<br />
<br />
<h3>
Initial Configuration </h3>
I'm gonna use the new Servlet 3 Java Web Configuration instead of an ancient web.xml. Nothing really special here.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">WebAppInitializer</span> <span style="color: #008800; font-weight: bold;">extends</span> AbstractAnnotationConfigDispatcherServletInitializer <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> Class<span style="color: #333333;"><?>[]</span> getRootConfigClasses<span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">new</span> Class<span style="color: #333333;"><?>[]{</span>AppConfiguration<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">};</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> Class<span style="color: #333333;"><?>[]</span> getServletConfigClasses<span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">new</span> Class<span style="color: #333333;">[]{</span>WebConfiguration<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">};</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> String<span style="color: #333333;">[]</span> <span style="color: #0066bb; font-weight: bold;">getServletMappings</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">new</span> String<span style="color: #333333;">[]{</span><span style="background-color: #fff0f0;">"/"</span><span style="color: #333333;">};</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/WebAppInitializer.java">WebAppInitializer.java on github</a><br />
<br />
I am initializing hibernate as my database abstraction layer in the <i>AppConfiguration</i> class. I'm using an embedded database (<a href="http://hsqldb.org/">hsql</a>), since i want to keep this showcase simple stupid. Still, nothing special here.<br />
<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Configuration</span>
<span style="color: #555555; font-weight: bold;">@EnableJpaRepositories</span>
<span style="color: #555555; font-weight: bold;">@EnableTransactionManagement</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">AppConfiguration</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Bean</span>
<span style="color: #008800; font-weight: bold;">public</span> DataSource <span style="color: #0066bb; font-weight: bold;">dataSource</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
EmbeddedDatabaseBuilder builder <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> EmbeddedDatabaseBuilder<span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">return</span> builder<span style="color: #333333;">.</span><span style="color: #0000cc;">setType</span><span style="color: #333333;">(</span>EmbeddedDatabaseType<span style="color: #333333;">.</span><span style="color: #0000cc;">HSQL</span><span style="color: #333333;">).</span><span style="color: #0000cc;">build</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Bean</span>
<span style="color: #008800; font-weight: bold;">public</span> LocalContainerEntityManagerFactoryBean <span style="color: #0066bb; font-weight: bold;">entityManagerFactory</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
HibernateJpaVendorAdapter vendorAdapter <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> HibernateJpaVendorAdapter<span style="color: #333333;">();</span>
vendorAdapter<span style="color: #333333;">.</span><span style="color: #0000cc;">setDatabase</span><span style="color: #333333;">(</span>Database<span style="color: #333333;">.</span><span style="color: #0000cc;">HSQL</span><span style="color: #333333;">);</span>
vendorAdapter<span style="color: #333333;">.</span><span style="color: #0000cc;">setGenerateDdl</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">true</span><span style="color: #333333;">);</span>
LocalContainerEntityManagerFactoryBean factory <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> LocalContainerEntityManagerFactoryBean<span style="color: #333333;">();</span>
factory<span style="color: #333333;">.</span><span style="color: #0000cc;">setJpaVendorAdapter</span><span style="color: #333333;">(</span>vendorAdapter<span style="color: #333333;">);</span>
factory<span style="color: #333333;">.</span><span style="color: #0000cc;">setPackagesToScan</span><span style="color: #333333;">(</span>getClass<span style="color: #333333;">().</span><span style="color: #0000cc;">getPackage</span><span style="color: #333333;">().</span><span style="color: #0000cc;">getName</span><span style="color: #333333;">());</span>
factory<span style="color: #333333;">.</span><span style="color: #0000cc;">setDataSource</span><span style="color: #333333;">(</span>dataSource<span style="color: #333333;">());</span>
<span style="color: #008800; font-weight: bold;">return</span> factory<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Bean</span>
<span style="color: #008800; font-weight: bold;">public</span> PlatformTransactionManager <span style="color: #0066bb; font-weight: bold;">transactionManager</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">JpaTransactionManager</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/AppConfiguration.java">AppConfiguration.java on github</a><br />
<br />
Now to the application servlet configuration: <i>WebConfiguration</i><br />
<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Configuration</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">WebConfiguration</span> <span style="color: #008800; font-weight: bold;">extends</span> RepositoryRestMvcConfiguration <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/WebConfiguration.java">WebConfiguration.java on github</a><br />
<br />
Oh, well thats a bit short isnt it? Not a single line of code required for a complete setup. This is a really nice application of the <a href="http://en.wikipedia.org/wiki/Convention_over_configuration">convention over configuration</a> paradigm. We can now start creating spring-data-jpa repositories and they will be exposed as RESTful resources automatically. And we can still add custom configuration to the <i>WebConfiguration</i> class later if needed.<br />
<br />
The Initialization was really short and easy. We didn't have to code anything special. The only thing we did was setting up a database connection and hibernate, which is obviously inevitable. Now, that we have setup our "REST Servlet" and persistence,
lets move on to the application itself, starting with the model.<br />
<br />
<h3>
The Model</h3>
I'll keep it really simple creating only two related entities. <br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQO7h6zcmw2O3Z1ORQq4E2W8SDyPKMZvh4h4IP4O_IhxcEYFAK7r5Gj70KEan2zjKTLIs72iqqggRXKWVRIxzcvOeHExJKr_6yJQglYo7RzEUXbL3ChoVFG8jhmV9h-pShvaPbGbonmH4/s1600/bookapi_model.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQO7h6zcmw2O3Z1ORQq4E2W8SDyPKMZvh4h4IP4O_IhxcEYFAK7r5Gj70KEan2zjKTLIs72iqqggRXKWVRIxzcvOeHExJKr_6yJQglYo7RzEUXbL3ChoVFG8jhmV9h-pShvaPbGbonmH4/s1600/bookapi_model.png" /></a></div>
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Entity</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Book</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Id</span>
<span style="color: #008800; font-weight: bold;">private</span> String isbn<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> String title<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> String language<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@ManyToMany</span>
<span style="color: #008800; font-weight: bold;">private</span> List<span style="color: #333333;"><</span>Author<span style="color: #333333;">></span> authors<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/model/Book.java">Book.java on github</a><br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Entity</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Author</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Id</span>
<span style="color: #555555; font-weight: bold;">@GeneratedValue</span><span style="color: #333333;">(</span>strategy <span style="color: #333333;">=</span> GenerationType<span style="color: #333333;">.</span><span style="color: #0000cc;">SEQUENCE</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">private</span> Integer id<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> String name<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@ManyToMany</span><span style="color: #333333;">(</span>mappedBy <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"authors"</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">private</span> List<span style="color: #333333;"><</span>Book<span style="color: #333333;">></span> books<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/model/Author.java">Author.java on github</a><br />
<br />
To finally make the entities persistent and exposed as a RESTful webservice, we need spring-data repositories. A repository is basically a <a href="http://en.wikipedia.org/wiki/Data_access_object">DAO</a>. It offers <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> functionality for our entities. spring-data takes away most of your programming effort creating such repositories. We just have to define an empty interface, spring-data does everything else out of the box. Still, it is easily customizable thanks to its design by convention over configuration!<br />
<br />
<h3>
The Actual Repositories</h3>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@RestResource</span><span style="color: #333333;">(</span>path <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"books"</span><span style="color: #333333;">,</span> rel <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"books"</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">interface</span> <span style="color: #bb0066; font-weight: bold;">BookRepository</span> <span style="color: #008800; font-weight: bold;">extends</span> PagingAndSortingRepository<span style="color: #333333;"><</span>Book<span style="color: #333333;">,</span> Long<span style="color: #333333;">></span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/BookRepository.java">BookRepository.java on github</a><br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@RestResource</span><span style="color: #333333;">(</span>path <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"authors"</span><span style="color: #333333;">,</span> rel <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"authors"</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">interface</span> <span style="color: #bb0066; font-weight: bold;">AuthorRepository</span> <span style="color: #008800; font-weight: bold;">extends</span> PagingAndSortingRepository<span style="color: #333333;"><</span>Author<span style="color: #333333;">,</span> Integer<span style="color: #333333;">></span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/main/java/com/blogspot/babdev/bookapi/AuthorRepository.java">AuthorRepository.java on github</a><br />
<br />
Again, there is nearly no code needed. Even the <i>@RestResource</i> annotation could be left out. But if i did, the path and rel would be named after the entity, which i dont want. A REST resource that contains multiple children should be named plural though.<br />
<br />
<h3>
Accessing The Result</h3>
Our RESTful webservice is now ready for deployment. Once run, it lists all available resources on the root, so you can navigate from there.<br />
<br />
<b><i>GET http://localhost:8080/</i></b><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{
<span style="color: #007700;">"links"</span> : [ {
<span style="color: #007700;">"rel"</span> : <span style="background-color: #fff0f0;">"books"</span>,
<span style="color: #007700;">"href"</span> : <span style="background-color: #fff0f0;">"http://localhost:8080/books"</span>
}, {
<span style="color: #007700;">"rel"</span> : <span style="background-color: #fff0f0;">"authors"</span>,
<span style="color: #007700;">"href"</span> : <span style="background-color: #fff0f0;">"http://localhost:8080/authors"</span>
} ],
<span style="color: #007700;">"content"</span> : [ ]
}
</pre>
</div>
<br />
Fine! Now lets create an author and a book.<br />
<br />
<b><i>POST http://localhost:8080/authors</i></b><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{<span style="color: #007700;">"name"</span>:<span style="background-color: #fff0f0;">"Uncle Bob"</span>}
</pre>
</div>
<br />
<b>Response</b>
<br />
<pre><span style="color: #666666;">201 Created</span>
<span style="color: #666666;">Location: http://localhost:8080/authors/1</span>
</pre>
<b><i>PUT http://localhost:8080/books/0132350882</i></b><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{
<span style="color: #007700;">"title"</span>: <span style="background-color: #fff0f0;">"Clean Code"</span>,
<span style="color: #007700;">"authors"</span>: [
{
<span style="color: #007700;">"rel"</span>: <span style="background-color: #fff0f0;">"authors"</span>,
<span style="color: #007700;">"href"</span>: <span style="background-color: #fff0f0;">"http://localhost:8080/authors/1"</span>
}
]
}
</pre>
</div>
<br />
<b>Response</b>
<br />
<pre><span style="color: #666666;">201 Created</span></pre>
Noticed how i used PUT to create the book? This is because its id is the actual isbn. I have to tell the server which isbn to use since he cant guess it. I used POST for the author as his id is just an incremental number that is generated automatically. Also, i used a link to connect both, the book (<i>/books/0132350882</i>) and the author (<i>/authors/1</i>). This is basically what hypermedia is all about: Links are used for navigation and relations between entities.<br />
<br />
Now, lets see if the book was created accordingly.<br />
<br />
<b><i>GET http://localhost:8080/books</i></b><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{
<span style="color: #007700;">"links"</span> : [ ],
<span style="color: #007700;">"content"</span> : [ {
<span style="color: #007700;">"links"</span> : [ {
<span style="color: #007700;">"rel"</span> : <span style="background-color: #fff0f0;">"books.Book.authors"</span>,
<span style="color: #007700;">"href"</span> : <span style="background-color: #fff0f0;">"http://localhost:8080/books/0132350882/authors"</span>
}, {
<span style="color: #007700;">"rel"</span> : <span style="background-color: #fff0f0;">"self"</span>,
<span style="color: #007700;">"href"</span> : <span style="background-color: #fff0f0;">"http://localhost:8080/books/0132350882"</span>
} ],
<span style="color: #007700;">"title"</span> : <span style="background-color: #fff0f0;">"Clean Code"</span>
} ],
<span style="color: #007700;">"page"</span> : {
<span style="color: #007700;">"size"</span> : <span style="color: #0000dd; font-weight: bold;">20</span>,
<span style="color: #007700;">"totalElements"</span> : <span style="color: #0000dd; font-weight: bold;">1</span>,
<span style="color: #007700;">"totalPages"</span> : <span style="color: #0000dd; font-weight: bold;">1</span>,
<span style="color: #007700;">"number"</span> : <span style="color: #0000dd; font-weight: bold;">1</span>
}
}
</pre>
</div>
<br />
Fine!<br />
<br />
Here is an Integration Test, following these steps automatically. It is also available in the example on github.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">BookApiIT</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">final</span> RestTemplate restTemplate <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> RestTemplate<span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">final</span> String authorsUrl <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"http://localhost:8080/authors"</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">final</span> String booksUrl <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"http://localhost:8080/books"</span><span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@Test</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">testCreateBookWithAuthor</span><span style="color: #333333;">()</span> <span style="color: #008800; font-weight: bold;">throws</span> Exception <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">final</span> URI authorUri <span style="color: #333333;">=</span> restTemplate<span style="color: #333333;">.</span><span style="color: #0000cc;">postForLocation</span><span style="color: #333333;">(</span>authorsUrl<span style="color: #333333;">,</span> sampleAuthor<span style="color: #333333;">());</span> <span style="color: #888888;">// create Author</span>
<span style="color: #008800; font-weight: bold;">final</span> URI bookUri <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> URI<span style="color: #333333;">(</span>booksUrl <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"/"</span> <span style="color: #333333;">+</span> sampleBookIsbn<span style="color: #333333;">);</span>
restTemplate<span style="color: #333333;">.</span><span style="color: #0000cc;">put</span><span style="color: #333333;">(</span>bookUri<span style="color: #333333;">,</span> sampleBook<span style="color: #333333;">(</span>authorUri<span style="color: #333333;">.</span><span style="color: #0000cc;">toString</span><span style="color: #333333;">()));</span> <span style="color: #888888;">// create Book linked to Author</span>
Resource<span style="color: #333333;"><</span>Book<span style="color: #333333;">></span> book <span style="color: #333333;">=</span> getBook<span style="color: #333333;">(</span>bookUri<span style="color: #333333;">);</span>
assertNotNull<span style="color: #333333;">(</span>book<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">final</span> URI authorsOfBookUri <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> URI<span style="color: #333333;">(</span>book<span style="color: #333333;">.</span><span style="color: #0000cc;">getLink</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"books.Book.authors"</span><span style="color: #333333;">).</span><span style="color: #0000cc;">getHref</span><span style="color: #333333;">());</span>
Resource<span style="color: #333333;"><</span>List<span style="color: #333333;"><</span>Resource<span style="color: #333333;"><</span>Author<span style="color: #333333;">>>></span> authors <span style="color: #333333;">=</span> getAuthors<span style="color: #333333;">(</span>authorsOfBookUri<span style="color: #333333;">);</span>
assertNotNull<span style="color: #333333;">(</span>authors<span style="color: #333333;">.</span><span style="color: #0000cc;">getContent</span><span style="color: #333333;">());</span>
assertFalse<span style="color: #333333;">(</span>authors<span style="color: #333333;">.</span><span style="color: #0000cc;">getContent</span><span style="color: #333333;">().</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">());</span> <span style="color: #888888;">// check if /books/0132350882/authors contains an author</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> String <span style="color: #0066bb; font-weight: bold;">sampleAuthor</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"{\"name\":\"Robert C. Martin\"}"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">final</span> String sampleBookIsbn <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"0132350882"</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> String <span style="color: #0066bb; font-weight: bold;">sampleBook</span><span style="color: #333333;">(</span>String authorUrl<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"{\"title\":\"Clean Code\",\"authors\":[{\"rel\":\"authors\",\"href\":\""</span> <span style="color: #333333;">+</span> authorUrl <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"\"}]}"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> Resource<span style="color: #333333;"><</span>Book<span style="color: #333333;">></span> <span style="color: #0066bb; font-weight: bold;">getBook</span><span style="color: #333333;">(</span>URI uri<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> restTemplate<span style="color: #333333;">.</span><span style="color: #0000cc;">exchange</span><span style="color: #333333;">(</span>uri<span style="color: #333333;">,</span> HttpMethod<span style="color: #333333;">.</span><span style="color: #0000cc;">GET</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">null</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">new</span> ParameterizedTypeReference<span style="color: #333333;"><</span>Resource<span style="color: #333333;"><</span>Book<span style="color: #333333;">>>()</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}).</span><span style="color: #0000cc;">getBody</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> Resource<span style="color: #333333;"><</span>List<span style="color: #333333;"><</span>Resource<span style="color: #333333;"><</span>Author<span style="color: #333333;">>>></span> <span style="color: #0066bb; font-weight: bold;">getAuthors</span><span style="color: #333333;">(</span>URI uri<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> restTemplate<span style="color: #333333;">.</span><span style="color: #0000cc;">exchange</span><span style="color: #333333;">(</span>uri<span style="color: #333333;">,</span> HttpMethod<span style="color: #333333;">.</span><span style="color: #0000cc;">GET</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">null</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">new</span> ParameterizedTypeReference<span style="color: #333333;"><</span>Resource<span style="color: #333333;"><</span>List<span style="color: #333333;"><</span>Resource<span style="color: #333333;"><</span>Author<span style="color: #333333;">>>>>()</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}).</span><span style="color: #0000cc;">getBody</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<a href="https://github.com/gregorriegler/babdev-spring/blob/master/spring-data-rest/src/test/java/com/blogspot/babdev/bookapi/BookApiIT.java">BookApiIT.java on github </a><br />
<br />
<h3>
Conclusion </h3>
We have created a complete RESTful webservice without much coding effort. We just defined our entities and database connection. spring-data-rest stated that everything else is just boilerplate, and i agree.<br />
<br />
To consume the webservices manually, consider the <a href="https://github.com/SpringSource/rest-shell">rest-shell</a>. It is a command-shell making the navigation in your webservice as easy and fun as it could be. Here is a screenshot:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJliYL7a4UF2rjX0m2b0Re_EUqRedwVCX4cJ4zJG8pP6yfyQC_Q6ENXDGhY4a8E_IuFk0h3XzTAHlab80mBFOiAQRF0cS6mRdk4f_hd9dfBWGvLQ_0PeCQ3NpQLNZ6bXIZ71Z735waW8A/s1600/rest_shell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJliYL7a4UF2rjX0m2b0Re_EUqRedwVCX4cJ4zJG8pP6yfyQC_Q6ENXDGhY4a8E_IuFk0h3XzTAHlab80mBFOiAQRF0cS6mRdk4f_hd9dfBWGvLQ_0PeCQ3NpQLNZ6bXIZ71Z735waW8A/s1600/rest_shell.png" /></a></div>
<br />
The complete example is available on my github<br />
<a href="https://github.com/gregorriegler/babdev-spring/tree/master/spring-data-rest">https://github.com/gregorriegler/babdev-spring/tree/master/spring-data-rest</a><br />
<a href="https://github.com/gregorriegler/babdev-spring">https://github.com/gregorriegler/babdev-spring</a><br />
<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com2tag:blogger.com,1999:blog-1178805312154210159.post-50453387193384477402013-08-02T21:56:00.000+02:002013-10-15T21:07:27.177+02:00Good Bye Redeployment. spring-loaded, an Opensource ClassreloaderRedeem yourself from hot deployments and OutOfMemoryException. <a href="https://github.com/SpringSource/spring-loaded">spring-loaded</a> is an opensource classreloader and a promising alternative to <a href="http://zeroturnaround.com/software/jrebel/">JRebel</a>. It does not offer as many features as JRebel does, and it does not support any framework just yet. Nevertheless, its a great tool that can save the time you are waiting for that servletcontainer to restart again.<br />
<br />
What it can do:<br />
<ul>
<li>add/modify/delete methods/fields/constructors</li>
<li>modify annotations on types/methods/fields/constructors</li>
<li>add/remove/change values in enum types </li>
</ul>
What it cant:<br />
<ul>
<li>support framework specific changes like Spring MVC @RequestMappings</li>
<li>change log configuration on the fly</li>
</ul>
It is not getting the attention that it deserves, so give it a try.<br />
<br />
Just download from <a href="https://github.com/SpringSource/spring-loaded">github</a> already, and add the following to your JVM parameters:<br />
<pre><code>java -javaagent:<pathTo>/springloaded-{VERSION}.jar -noverify</code></pre>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com1tag:blogger.com,1999:blog-1178805312154210159.post-73273462518028035172013-07-30T00:41:00.001+02:002014-07-20T16:52:19.515+02:00Why REST is so important<div class="separator" style="clear: both; text-align: center;">
</div>
This post is dedicated to REST, an architectural style of shaping webservices and one of the most misunderstood concept in the history of IT. This post is addressed to you who is designing webservice apis not being
fully aware what REST actually means. I'm trying to give you the idea.
This post is also addressed to you who think to know what REST means, when in reality you have no clue, just yet. Yes i have met such
people in the past - plenty of them. It's not going into the details of the <a href="http://martinfowler.com/articles/richardsonMaturityModel.html">Richardson Maturity Model</a>, and it's not gonna make you a REST expert. There are plenty of guides on the web for that: slides, youtube videos, blogposts, books and more. Rather than going into the details, i'm going to link some good resources at the end of this post. <br />
<br />
So lets start with<br />
<br />
<h3>
The meaning of REST</h3>
Representational State Transfer. This sentence is not only what REST stands for, it is also the tiniest possible description of what REST actually means. Didn't get it? Read it again: Representational State Transfer. It is not a standard, rather a style describing the act of transfering a state of something by its representation.<br />
<br />
Lets consider this: <br />
Marcus is a farmer. He has a ranch with 4 pigs, 12 chickens and 3 cows. He is now simulating a REST api while i am the client. If i want to request the current state of his farm using REST i just ask him: "State?"<br />
Marcus answers: "4 pigs, 12 chickens, 3 cows".<br />
This is the most simple example of Representional State Transfer. Marcus transfered the state of his farm to me using a representation. The representation of the farm is the plain sentence: "4 pigs, 12 chickens, 3 cows".<br />
<br />
So lets get to the next level. How would i tell Marcus to add 2 cows to his farm the REST way?<br />
Maybe tell him: "Marcus, please add 2 cows to your farm".<br />
Do you think this was REST? Are we transfering state by its representation here? NO! This was calling a remote procedure. The procedure of adding 2 cows to the farm.<br />
Marcus sadly answers: "400, Bad Request. What do you mean?"<br />
So lets try this again. How would we do this the REST way? What was the representation again? It was "4 pigs, 12 chickens, 3 cows". Ok. so lets try this again transfering the representation...<br />
me: "Marcus, ... 4 pigs, 12 chickens, <span style="color: red;">5</span> cows ... please!". <br />
Marcus: "Alright !".<br />
me: "Marcus, ... what is your state now?". <br />
Marcus: "4 pigs, 12 chickens, 5 cows".<br />
me: "Ahh, great!"<br />
See? It was really not that hard and it was REST.<br />
<br />
<h3>
Why RPC is a pain in the A**</h3>
So why would you favor REST over the remote procedure call (=RPC) from a logical perspective? Because it dramatically reduces the complexity of our communication by making the representation our only contract. We do not have to discuss what kinds of procedures we need (Add a cow?, Add an animal of a type? Double the chickens amount? Remove all pigs?). All we have to discuss is the representation, and use this representation to achieve anything we want. Easy, isn't it? The needless complexity of RPC is not helpful at all. It is rather increasing the risk of misunderstandings, which we don't want. We don't want our communication to fail because Marcus and I understood a procedure differently.<br />
But this is just one of many problems RPC is creating. If you want to use RPC you need to design some kind of structure to embed your procedure into. This structure requires a place to store parameters, error codes, return values and so on. I have seen lots of developers and companies who really did this. They designed their own RPC-Structure arising huge problems in the implementation of clients and client-server interaction. Why would you do this? Why would you invent your own RPC-Structure? Do you think this is helpful? What if i wanted to make an application that uses many WebServices of multiple proprietary RPC-Formats? I would have to develop something like this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiISWrjwzDX362b5Kxv28eu8T5hhS-JkuFkKuNeGbcTZcC32s5G73hZs75QkHSB8TOU0VOg5Dc9XiX_RqSpILUjN5P5aaE8ZhPK63wTc8HF8ktO6-qVRJvmDqoJIrpD0Fv4EBlrcC0p8s/s1600/chaos.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiISWrjwzDX362b5Kxv28eu8T5hhS-JkuFkKuNeGbcTZcC32s5G73hZs75QkHSB8TOU0VOg5Dc9XiX_RqSpILUjN5P5aaE8ZhPK63wTc8HF8ktO6-qVRJvmDqoJIrpD0Fv4EBlrcC0p8s/s1600/chaos.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">image #1</td></tr>
</tbody></table>
<br />
Ugh...<br />
If you really need RPC, at least choose a standard like SOAP. Don't make up your own stuff!<br />
<br />
<h3>
</h3>
<h3>
But SOAP is still bad</h3>
Still, even the standards of RPC are really painful. Well, i have to admit that with ACID Transactions, and a complete standardized Service Description Language, SOAP is not all that bad in some circumstances. Nevertheless, the overhead SOAP produces is massive and a huge performance killer. HTTP is a lightweight protocol. Its headers include anything you need. The only thing you want to put in the body is a representation - or not even that.<br />
<br />
<h3>
Sessions are Evil</h3>
Since i wrote solely about sessions and why they are bad in another post, i removed this paragraph. Please continue reading here: <a href="http://www.beabetterdeveloper.com/2013/11/sessions-pitfall.html">Sessions. A Pitfall</a><br />
<br />
<h3>
Dont reinvent Hypermedia</h3>
Since hypermedia is getting quite popular now, i beg you: Don't invent your own style.<br />
We do already have plenty. There is<br />
<ul>
<li>Hypermedia by the <a href="http://en.wikipedia.org/wiki/Atom_%28standard%29#Including_in_HTML">Atom Link specification</a> like in <a href="https://github.com/SpringSource/spring-hateoas">spring-hateoas</a> and <a href="http://www.springsource.org/spring-data/rest">spring-data-rest</a>.</li>
<li><a href="http://stateless.co/hal_specification.html">JSON-HAL</a></li>
<li><a href="http://json-ld.org/">JSON-LD</a></li>
<li>... </li>
</ul>
And we are slowly getting to the situation in <i>image #1</i> again.<br />
<br />
<h3>
Further Resources</h3>
In this post, i have only scratched the surface of the advantages of REST. <br />
Here are some good resources to get you a deeper understanding.<br />
<ul>
<li><a href="http://martinfowler.com/articles/richardsonMaturityModel.html">Fowlers Article on the Richardson Maturity Model</a></li>
<li><a href="https://speakerdeck.com/ammeep/exist-in-the-web-not-on-it">A great slide on Hypermedia</a></li>
<li><a href="http://www.youtube.com/watch?v=XzgCzjMdvRE">A talk by David Zuelke on RESTful Webservices</a></li>
<li><a href="http://www.youtube.com/watch?v=YCcAE2SCQ6k">Intro to REST (short video of GoogleDevelopers)</a></li>
<li><a href="http://www.youtube.com/watch?v=5WXYw4J4QOU">A talk of Lez Hazlewood (Stormpath)</a></li>
<li><a href="http://www.amazon.com/RESTful-Web-Services-Cookbook-Scalability/dp/0596801688/ref=sr_1_2?s=books&ie=UTF8&qid=1375133720&sr=1-2">A Cookbook for RESTful WebServices </a></li>
<li><a href="http://www.amazon.com/REST-HTTP-Einsatz-Architektur-Integrationsszenarien/dp/3898645835/ref=sr_1_30?ie=UTF8&qid=1375133651&sr=8-30">Great German Book about REST</a></li>
</ul>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com2tag:blogger.com,1999:blog-1178805312154210159.post-74327272487672807132013-07-21T01:16:00.001+02:002013-08-05T19:23:18.010+02:00Spring MVC - @RequestBody and @ResponseBody demystifiedIn this post i want to dig into spring mvc a little, revealing what happens behind the scenes when a request is converted to your parameter object and vice versa. Before we start, i want to explain the purpose of these annotations.<br />
<br />
<h3>
What are @RequestBody and @ResponseBody for? </h3>
<br />
They are annotations of the spring mvc framework and can be used in a controller to implement smart object serialization and deserialization. They help you avoid boilerplate code by extracting the logic of messageconversion and making it an aspect. Other than that they help you support multiple formats for a single REST resource without duplication of code. If you annotate a method with @ResponseBody, spring will try to convert its return value and write it to the http response automatically. If you annotate a methods parameter with @RequestBody, spring will try to convert the content of the incoming request body to your parameter object on the fly.<br />
<br />
Here is an example<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Controller</span>
<span style="color: #555555; font-weight: bold;">@RequestMapping</span><span style="color: #333333;">(</span>value <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"/bookcase"</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">BookCaseController</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> BookCase bookCase<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@RequestMapping</span><span style="color: #333333;">(</span>method <span style="color: #333333;">=</span> RequestMethod<span style="color: #333333;">.</span><span style="color: #0000cc;">GET</span><span style="color: #333333;">)</span>
<span style="color: #555555; font-weight: bold;">@ResponseBody</span>
<span style="color: #008800; font-weight: bold;">public</span> BookCase <span style="color: #0066bb; font-weight: bold;">getBookCase</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">bookCase</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@RequestMapping</span><span style="color: #333333;">(</span>method <span style="color: #333333;">=</span> RequestMethod<span style="color: #333333;">.</span><span style="color: #0000cc;">PUT</span><span style="color: #333333;">)</span>
<span style="color: #555555; font-weight: bold;">@ResponseStatus</span><span style="color: #333333;">(</span>HttpStatus<span style="color: #333333;">.</span><span style="color: #0000cc;">NO_CONTENT</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">setBookCase</span><span style="color: #333333;">(</span><span style="color: #555555; font-weight: bold;">@RequestBody</span> BookCase bookCase<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">bookCase</span> <span style="color: #333333;">=</span> bookCase<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<h3>
So what is Spring doing behind the scenes when we are using those Annotations?</h3>
<br />
Depending on your configuration, spring has a list of <a href="http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/http/converter/HttpMessageConverter.html">HttpMessageConverters</a> registered in the background. A HttpMessageConverters responsibility is to convert the request body to a specific class and back to the response body again, depending on a predefined <a href="http://de.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions">mime type</a>. Every time an issued request is hitting a @RequestBody or @ResponseBody annotation spring loops through all registered HttpMessageConverters seeking for the first that fits the given mime type and class and then uses it for the actual conversion.<br />
<br />
<h3>
How can i add a custom HttpMessageConverter?</h3>
<br />
By adding @EnableWebMvc respectively <mvc:annotation-driven />, spring registers a bunch of predefined messageconverters for JSON/XML and so on. You can add a custom converter like the following<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #555555; font-weight: bold;">@Configuration</span>
<span style="color: #555555; font-weight: bold;">@EnableWebMvc</span>
<span style="color: #555555; font-weight: bold;">@ComponentScan</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">WebConfiguration</span> <span style="color: #008800; font-weight: bold;">extends</span> WebMvcConfigurerAdapter <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">configureMessageConverters</span><span style="color: #333333;">(</span>List<span style="color: #333333;"><</span>HttpMessageConverter<span style="color: #333333;"><?>></span> httpMessageConverters<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
httpMessageConverters<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> BookCaseMessageConverter<span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> MediaType<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"text"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"csv"</span><span style="color: #333333;">)));</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
In this example i've written a converter that handles the conversion of a BookCase, which is basically a List of Books. The converter is able to convert csv content to a BookCase and vice versa. I used <a href="http://opencsv.sourceforge.net/">opencsv </a>to parse the text.<br />
<br />
Here is the model<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Book</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> String isbn<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> String title<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">Book</span><span style="color: #333333;">(</span>String isbn<span style="color: #333333;">,</span> String title<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">isbn</span> <span style="color: #333333;">=</span> isbn<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">this</span><span style="color: #333333;">.</span><span style="color: #0000cc;">title</span> <span style="color: #333333;">=</span> title<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #888888;">// ...</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">BookCase</span> <span style="color: #008800; font-weight: bold;">extends</span> ArrayList<span style="color: #333333;"><</span>Book<span style="color: #333333;">></span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">BookCase</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">BookCase</span><span style="color: #333333;">(</span>Collection<span style="color: #333333;"><?</span> <span style="color: #008800; font-weight: bold;">extends</span> Book<span style="color: #333333;">></span> c<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">(</span>c<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
and the actual converter<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">BookCaseMessageConverter</span> <span style="color: #008800; font-weight: bold;">extends</span> AbstractHttpMessageConverter<span style="color: #333333;"><</span>BookCase<span style="color: #333333;">></span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">BookCaseMessageConverter</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">BookCaseMessageConverter</span><span style="color: #333333;">(</span>MediaType supportedMediaType<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">(</span>supportedMediaType<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #0066bb; font-weight: bold;">BookCaseMessageConverter</span><span style="color: #333333;">(</span>MediaType<span style="color: #333333;">...</span> supportedMediaTypes<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">(</span>supportedMediaTypes<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">boolean</span> <span style="color: #0066bb; font-weight: bold;">supports</span><span style="color: #333333;">(</span>Class<span style="color: #333333;"><?></span> clazz<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> BookCase<span style="color: #333333;">.</span><span style="color: #0000cc;">class</span><span style="color: #333333;">.</span><span style="color: #0000cc;">equals</span><span style="color: #333333;">(</span>clazz<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> BookCase <span style="color: #0066bb; font-weight: bold;">readInternal</span><span style="color: #333333;">(</span>Class<span style="color: #333333;"><?</span> <span style="color: #008800; font-weight: bold;">extends</span> BookCase<span style="color: #333333;">></span> clazz<span style="color: #333333;">,</span> HttpInputMessage httpInputMessage<span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">throws</span> IOException<span style="color: #333333;">,</span> HttpMessageNotReadableException <span style="color: #333333;">{</span>
CSVReader reader <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> CSVReader<span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> InputStreamReader<span style="color: #333333;">(</span>httpInputMessage<span style="color: #333333;">.</span><span style="color: #0000cc;">getBody</span><span style="color: #333333;">()));</span>
List<span style="color: #333333;"><</span>String<span style="color: #333333;">[]></span> rows <span style="color: #333333;">=</span> reader<span style="color: #333333;">.</span><span style="color: #0000cc;">readAll</span><span style="color: #333333;">();</span>
BookCase bookCase <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> BookCase<span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">for</span> <span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> row <span style="color: #333333;">:</span> rows<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
bookCase<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> Book<span style="color: #333333;">(</span>row<span style="color: #333333;">[</span><span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">],</span> row<span style="color: #333333;">[</span><span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">]));</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> bookCase<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">writeInternal</span><span style="color: #333333;">(</span>BookCase books<span style="color: #333333;">,</span> HttpOutputMessage httpOutputMessage<span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">throws</span> IOException<span style="color: #333333;">,</span> HttpMessageNotWritableException <span style="color: #333333;">{</span>
CSVWriter writer <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> CSVWriter<span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> OutputStreamWriter<span style="color: #333333;">(</span>httpOutputMessage<span style="color: #333333;">.</span><span style="color: #0000cc;">getBody</span><span style="color: #333333;">()));</span>
<span style="color: #008800; font-weight: bold;">for</span> <span style="color: #333333;">(</span>Book book <span style="color: #333333;">:</span> books<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
writer<span style="color: #333333;">.</span><span style="color: #0000cc;">writeNext</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> String<span style="color: #333333;">[]{</span>book<span style="color: #333333;">.</span><span style="color: #0000cc;">getIsbn</span><span style="color: #333333;">(),</span> book<span style="color: #333333;">.</span><span style="color: #0000cc;">getTitle</span><span style="color: #333333;">()});</span>
<span style="color: #333333;">}</span>
writer<span style="color: #333333;">.</span><span style="color: #0000cc;">close</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<h3>
The Result </h3>
We can now issue text/csv requests to our Resource along with application/json and xml which are basically supported out of the box.<br />
<br />
1.)<br />
<pre><b>PUT /bookcase</b>
<i><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">Content-Type: text/csv</span></i>
<span style="color: blue;"><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">"123","Spring in Action"
"456","Clean Code"</span></span>
<b><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">Response</span></b>
<span style="color: #6aa84f;"><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">204 No Content</span></span></pre>
2.)<span style="color: #6aa84f;"><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">
</span></span><br />
<pre><b><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">GET /bookcase</span></b>
<i><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">Accept: text/csv</span></i>
<b><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">Response</span></b>
<span style="color: #6aa84f;"><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">200 OK</span></span>
<span style="color: blue;"><span class="label" data-header-id="f9beee7543227809ba788522f2ba5b9d61a0d03a" title="Content-Type: text/csv">"123","Spring in Action"
"456","Clean Code"</span></span>
</pre>
<br />
Thanks to the design of spring mvc, which is following the single responsibility principle, our controller stays thin. We don't have to add a single line if we want to support new media types.<br />
<br />
<h3>
The complete example is available on my <a href="https://github.com/gregorriegler/babdev-spring/tree/master/message-converter">github</a>
</h3>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-80581997696363679872013-07-08T18:48:00.000+02:002013-11-24T19:59:28.962+01:00Modern Web DevelopmentIn the last few years web technology has lived through rapid growth and heavy change. We went from frames to table layouts, to column layouts, to responsive layouts. From html4 to xhtml & flash to html5. From heavy server to rich client. From rpc to soap to rest. From sql to nosql and big data. From MVC to MVP and so on. In the following post i want to describe what has become state-of-the-art from my perspective.<br />
<br />
<h3>
A Backend is a REST api </h3>
Every backend should be seen as a REST api and every controller as another resource. You want to analyze your problem domain, find your resources and design proper paths for them. They become the M in your MVC Architecture. Developing a webapplication first, and adding an extra REST api later on has to be considered an antipattern. If you do make a REST api, you want to consequently use it yourself, making your frontend its first consumer. This procedure allows you to smoothly add different kinds of clients
later on, such as a mobile app or even a desktop application. It's also
the foundation to integrate your applications features into other
applications.<br />
<br />
<h3>
Separate your Frontend</h3>
The days when you made up a form using jsp with a jstl form validation are fading. You don't want to mix client with server technology anymore. The V and C of MVC has shifted over to the client and your backend just represents the Model. You want your frontend to be completely separated using client technology only (html/css/js) and consuming your REST api. GUI logic, building and aligning proper html elements can be achieved within javascript. The most appropriate content-type for information exchange between the backend and frontend would be json or even xml.<br />
<br />
<h3>
Rich Client & Hail JavaScript</h3>
The MVC pattern is nowadays implemented on the client side using javascript and it's fellow frameworks. There is no full-blown complete javascript framework that can achieve everything out of the box, but there are tons of smaller libs solving atomic tasks. This should not be considered bad or overwhelming, but advantageous. It causes a great variety of tools that focus on solving single problems outright. <a href="http://documentcloud.github.io/backbone/">Backbone</a> is a popular mvc framework built upon <a href="http://underscorejs.org/">underscore</a>, a js library delivering great utility with remarkable functional programming features. A template engine like <a href="http://mustache.github.io/">mustache</a> or <a href="http://handlebarsjs.com/">handlebars</a> could be added and <a href="http://requirejs.org/">requirejs</a> would manage the dependencies within your modules. Of course, a dom manipulator like <a href="http://jquery.com/">jquery</a> cannot be left out. The trend is leading towards <a href="http://en.wikipedia.org/wiki/Single-page_application">SPA</a>'s (Single Page Applications) with heavy <a href="http://en.wikipedia.org/wiki/AJAJ">AJAJ</a><a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">/AJAX</a>, routing through html <a href="http://en.wikipedia.org/wiki/HTML_element#Anchor">#anchors</a> representing bookmarkable view-states.<br />
<br />
<h3>
Implement a Buildprocess for your Frontend</h3>
As Browsers are continously increasing javascript performance and adding more and more support for html5, frontends have become complex and sophisticated. You now want to add a build process for your frontend, compiling all your js and css files. You want to deliver only a single minified js file to the browser. Other than that we don't break the DRY principle writing styles anymore. We use dynamic stylesheet languages like <a href="http://lesscss.org/">less</a> to make our styles smarter and cleaner and compile them to css in our build process. <a href="http://nodejs.org/">Node</a> and <a href="https://developer.mozilla.org/en-US/docs/Rhino">rhino</a> are possible engine candidates to build your frontend. While node is much faster, it requires an easy installation on the build server. Rhino runs in a jvm, thus not requiring an installation. You can add it to your project as a maven dependency. <br />
<br />
<h3>
Mobile Web & Responsive Design</h3>
Mobile devices are becoming more powerful in terms of hardware whilst html5 support is also rapidly increasing on mobile browsers. Html5 could potentially make native mobile applications obsolete one day. Localstorage, SQL, Geolocation, Multimedia, Camera Access, Web Sockets, Graphics, Touch Events, WebGL, Filesystem Access, Notifications and many more are all features to be completely available to mobile html5 webapplications one day, hopefully working on all devices. So far, we have been developing multiple applications for android/ios/windows mobile and so on, being an economic nightmare.<br />
Mobile clients have gained a substantial amount in web consumership, and cannot be ignored anymore. Therefor you want to make your GUI <a href="http://en.wikipedia.org/wiki/Responsive_design">reponsive</a>, beeing able to scale down to smaller display-resolutions. Wise companies have even started designing userinterfaces for the smallest resolution before even thinking of a desktop resolution. This makes scaling more easy, since the other way round is harder and tends to force painfull workarounds. <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> is one of many libraries that help you make your gui responsive. You can use <a href="http://www.initializr.com/">initializr</a> to get started.<br />
<br />
<h3>
<a href="http://www.gwtproject.org/">GWT</a> or <a href="http://www.zkoss.org/">ZK Framework</a>? Use Neither!</h3>
GWT/ZK are trying do deliver a framework that makes it possible to develop modern ajax web applications using Java only. So they are basically building a java wrapper for frontend technology. Other than that, they deliver a huge amount of components. BUT ... i'd like to question their philosophy for many reasons.<br />
<ul>
<li>They Both produce quite bad html code making you end in an element and dom-id nightmare that gets hard or even impossible to test, debug and style. Html5 allows to write short, clean and readable code, organized way better. You want to write html yourself.</li>
<li>Their AJAX calls are not based on the REST api that you need. If you want a REST api, you may have to write that again. RPC is GWT's primary communication-technology and i am really concerned about that. But you can still make a REST api work with GWT if you like to.</li>
<li>They keep you away from the technology that you are actually producing. Tiny customizations can get hard or even impossible in the end. You are basically giving up control and limiting your possibilities. This might in many cases lead to dead ends, that are based on the framework, not the technology. GWT helps to overcome this problem offering JSNI.</li>
<li>They are never up to date. While browsers are evolving rapidly, new features have to be implemented in the Java-Wrapper before you can even use them, delaying your up-to-dateness.</li>
<li>I doubt that wrapping native front-end technology is a good idea, and i don't see a reason for doing it. One pro GWT argument might be: it's generating optimized JS code.</li>
</ul>
In the end they make it easier to build webapplications for former java.awt/swing developers, who have no to little knowhow on html/css/js.<br />
They defintively have their place right now and aren't a bad choice in some cases.<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com5tag:blogger.com,1999:blog-1178805312154210159.post-23295876821748870172013-06-13T21:06:00.001+02:002013-10-18T12:37:55.979+02:00What makes a great Developer<ul>
</ul>
<h3>
Passion</h3>
It's the taste of success that comes with every little task that you've mastered, and smart solutions you've found that turn out advantageous. Programming is not just a job, it's an Art - it's Poetry. With Passion comes Motivation and thus Progress. Software development is not only huge, but also evolving very fast. A good developer enjoy's keeping up-to-date, since he knows that there's always a better way to do something. Learning new ways, satisfies his hunger.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg67llLNktIwphMCprRvs6aqFxp9-mdp8OQqUH5WHOK5UImN771ynMPNKNwzVwwNLiQTBGdx0zNzQzPIJ_9nEU2MF-oHWoN93Oi2cou2wJdb2IvT4RnkXNou9Y1iTTCPeqfRpncYUFgmCw/s1600/computer-cartoon-happy-guy2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg67llLNktIwphMCprRvs6aqFxp9-mdp8OQqUH5WHOK5UImN771ynMPNKNwzVwwNLiQTBGdx0zNzQzPIJ_9nEU2MF-oHWoN93Oi2cou2wJdb2IvT4RnkXNou9Y1iTTCPeqfRpncYUFgmCw/s320/computer-cartoon-happy-guy2.gif" width="311" /></a></div>
<br />
<h3>
Curiosity</h3>
A Program is deterministic. There is no such thing as an accident in a computers world. Every effect has its cause. A great developer does not accept accidents. He'd rather search and debug the numerous layers of a Software and it's environment to find the very reason. He builds up deep knowledge by doing that, allowing him to better understand, read and interpret weird behaviour of an application. A good developer does not <a href="http://en.wikipedia.org/wiki/Programming_by_permutation">program by Accident</a>.<br />
<br />
“The important thing is not to stop questioning. Curiosity has its own reason for existing.” - Albert Einstein<br />
<br />
"The most likely way for the world to be destroyed, most experts
agree, is by accident. That's where we come in; we're computer
professionals. We cause accidents." -
<br />
Nathaniel Borenstein<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj39kvECtkHppzldA4ZZ5QD1m2GN67D3sBwN330QnddLIMUxGjXhS1u35dubmD8mlLuE9-GacHQZhODkNchNTjkSQl9g5ncpwo9y49QqysRhqzH9LFZHIQdf1NDvYvL6k_HZ1JhOHxYFnk/s1600/curiosity2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj39kvECtkHppzldA4ZZ5QD1m2GN67D3sBwN330QnddLIMUxGjXhS1u35dubmD8mlLuE9-GacHQZhODkNchNTjkSQl9g5ncpwo9y49QqysRhqzH9LFZHIQdf1NDvYvL6k_HZ1JhOHxYFnk/s1600/curiosity2.jpg" /></a></div>
<br />
<br />
<h3>
Cognition</h3>
Programming is the act of solving a problem. Problems can be factorized into multiple parts that work together as a whole. To find and reflect those in your mind, and imagine their interaction is a true skill. There is nothing more to say about that.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp9Q6aE7pX2jntHU3dYmhh96mo2ii76lBQLKv0Ft3Mj3pWlaUgEvqdMEV4sQwUps912j3UmhQ5rtCuMt65TRnRa7I9f0ksW0Fe1qh_GZ936bglBhz0hoeaGCNE3Z5ilvL3Z1KFMno9SGQ/s1600/image030.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp9Q6aE7pX2jntHU3dYmhh96mo2ii76lBQLKv0Ft3Mj3pWlaUgEvqdMEV4sQwUps912j3UmhQ5rtCuMt65TRnRa7I9f0ksW0Fe1qh_GZ936bglBhz0hoeaGCNE3Z5ilvL3Z1KFMno9SGQ/s320/image030.jpg" width="320" /></a></div>
<br />
<h3>
Meticulosity</h3>
Programming is full pitfalls that can be tracked down to the very microcosm of Software Development. The Devil is in the details, and even the smallest sluttery can easily tear a Project down. That's why perfection is so powerful, and important for high quality and success. If you accept a single flaw, you will most likely accept a second, ... and a third ... until you got a mess. A good developer cannot accept flaws and thus avoids many pitfalls increasing quality. There is an analogy to the <a href="http://en.wikipedia.org/wiki/Broken_windows_theory">Broken Windows Theory</a>, which basically says that a single broken window can easily lead to more serious deviance, crime, abandonment and demolishment of its house.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy1NY37SxH52rRdxL8RwjZAT85RvKwQLDBNOhzMK7WwOUgSCTUdRIwN_ean-w8R0brOXTY2dHI8Lx7JZrSMXtFBnH_1JUml5YPOAmQsZXSmm3Q0JQFQUNMwEoyMtk4Tp0GfY8hsqip__c/s1600/precision.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy1NY37SxH52rRdxL8RwjZAT85RvKwQLDBNOhzMK7WwOUgSCTUdRIwN_ean-w8R0brOXTY2dHI8Lx7JZrSMXtFBnH_1JUml5YPOAmQsZXSmm3Q0JQFQUNMwEoyMtk4Tp0GfY8hsqip__c/s1600/precision.jpg" /></a></div>
<br />
<h3>
Time</h3>
Greatness comes with experience. It's the iterations of improvement that have been lived through, that really matter. Yes, you can simply follow advices, patterns and best practice. But that has nothing to do with Wisdom, which evolves by doing mistakes and iterations.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPL0bBEp6MPOkL1to4ByJSHyq-3JpEemS19GUMw_cdncPfEhEZ0c1ESl3SIjxFOw4FtjjcPwVg6LuflNm4FDaxvCixULvoLrnXW-Ov1Fw2YwmJd62L6C4yjuw0P7c6eFMEeNPp9sJR5Qc/s1600/sheep-with-an-afro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPL0bBEp6MPOkL1to4ByJSHyq-3JpEemS19GUMw_cdncPfEhEZ0c1ESl3SIjxFOw4FtjjcPwVg6LuflNm4FDaxvCixULvoLrnXW-Ov1Fw2YwmJd62L6C4yjuw0P7c6eFMEeNPp9sJR5Qc/s400/sheep-with-an-afro.jpg" width="400" /></a></div>
<br />
<h3>
Humbleness</h3>
A great developer knows that he doesn't, and will never know everything. He knows, that there is always room for improvement, also in his own work. He admits his mistakes and accepts critisism.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9ZFKMPZ280HOIDcJIhwC3rrzltN_HBZWcwCU-jBX3XeRQlbgakHNRpLYgGXYiTmzX_eTAbQxzHxh1noFr8ztrUgWH-SxX4zK_sykCWVy4lXncx-Y4DvSyqrh5eggN3sbpwNBaI_uzMEY/s1600/vor-lastwagen-verneigen.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9ZFKMPZ280HOIDcJIhwC3rrzltN_HBZWcwCU-jBX3XeRQlbgakHNRpLYgGXYiTmzX_eTAbQxzHxh1noFr8ztrUgWH-SxX4zK_sykCWVy4lXncx-Y4DvSyqrh5eggN3sbpwNBaI_uzMEY/s320/vor-lastwagen-verneigen.jpg" width="320" /></a></div>
<br />
<h3>
Tenacity</h3>
A good developer declares war on every workaround. He will fight it even if he has to struggle hour after hour, through the night, until the sun rises. Even the greatest developer meets problems, that he might not consider solvable in the first place. But he takes it as a challenge, unless it's not an antipattern. "It won't work" is not an option. Hard-earned success evolves self-confidence.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpp4v8iWkf-qQ87UqcFhAAbvq6APxHJUDbk42XHYBnvU0qvdv2H39CwlNRIx-2qruC-GFdF8-8oZfMhpapoLYTeNr4UIs3WS-k1JwlgE4MPK6RzFVS_vF7VAbE1WTrh3Cv7Bxmjhb1AKw/s1600/never-give-up-frog-211x300.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpp4v8iWkf-qQ87UqcFhAAbvq6APxHJUDbk42XHYBnvU0qvdv2H39CwlNRIx-2qruC-GFdF8-8oZfMhpapoLYTeNr4UIs3WS-k1JwlgE4MPK6RzFVS_vF7VAbE1WTrh3Cv7Bxmjhb1AKw/s1600/never-give-up-frog-211x300.jpg" /></a></div>
<h2>
</h2>
<h3>
Vision</h3>
In Software development, it is common to work long times on small tasks. While beeing focused, it's easy to get lost and overlook the impact on the rest of the system. A good developer is skilled in keeping an eye on the bigger picture, foreseeing sideeffects of a current decision. Still he may intentionally choose to postpone their treatment going step-by-step.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE041MwjNGiuYYBBCUVCLnCy16GPOtKZflslCQKUqDDaEArv7Ufh-dmB65mVpBiXABM5IK5ExBlCrcjBwg4I8jXWTGIVFtem7KWggVu2Qc6SvoL91sc-VmF2vCJPy8i4t8md9MFmKqT9Y/s1600/1024px-Spyglass.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE041MwjNGiuYYBBCUVCLnCy16GPOtKZflslCQKUqDDaEArv7Ufh-dmB65mVpBiXABM5IK5ExBlCrcjBwg4I8jXWTGIVFtem7KWggVu2Qc6SvoL91sc-VmF2vCJPy8i4t8md9MFmKqT9Y/s320/1024px-Spyglass.jpg" width="320" /></a></div>
<br />
<h3>
Lazyness</h3>
This might sound stupid in the first place, but its not. Lazyness leads to a lot of improvements. The
probably most important thing it leads to is Automation. Everytime you
have successfully refused to do something manually by automating it, you
have already improved. Automation is the key to faultlessness,
efficiency and progress. Faultlessness, because ideally a computer
doesnt make any mistakes (which is not entirely true in every aspect),
but humans do real quick. Efficiency, because it's an investment saving
time in the long run. The earlier you automate something, the more you
get out of it. Progress, because every process that
does not demand mental resources anymore leaves room for something else.
What you don't have to think of doesn't hinder you, whereas software
development is actually completely blown up with barriers that you have
to think of all the time. <br />
<br />
A good developer is too lazy to<br />
<ul>
<li>write a complete API doc, he lets JavaDoc do the job.</li>
<li>format his code properly, he lets his IDE do the job.</li>
<li>test a functionality over and over again, so he automates it using xUnit. </li>
<li>read complicated methods, so he writes short readable methods with good names.</li>
<li>write the same lines of code all over again. He seeks for ways to
refactor to avoid such boilerplate code, since he is too lazy to repeat
himself. (<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>)</li>
<li>implement that functionality that nobody asked for. (<a href="http://en.wikipedia.org/wiki/YAGNI">YAGNI</a>)</li>
<li>use bitwise shifting for a subtraction, he keeps it simple stupid (<a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a>).</li>
<li>write code at all, he lets his colleague do it for him (<a href="http://en.wikipedia.org/wiki/Pair_programming">Pair Programming</a>). <br />Nah, i was just kidding on this one ;-) </li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI0L-mdEme_gtvruMeLDGSppVWPo5P-EjAtFDadjUaWuNmyulBimc5qJTpwRlfUZ5EkWLdy2qTCdAp-blF6r7Fd07SYZL5xPaai6ijqI8K2qd1YU08h-SXo04hHVo68EbMXGXipMR5bRg/s1600/garfield.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI0L-mdEme_gtvruMeLDGSppVWPo5P-EjAtFDadjUaWuNmyulBimc5qJTpwRlfUZ5EkWLdy2qTCdAp-blF6r7Fd07SYZL5xPaai6ijqI8K2qd1YU08h-SXo04hHVo68EbMXGXipMR5bRg/s1600/garfield.jpg" /></a></div>
<br />
<h3>
What do you think makes a great developer?</h3>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com7tag:blogger.com,1999:blog-1178805312154210159.post-31908040412329853652013-05-21T08:26:00.000+02:002013-05-21T08:26:19.975+02:00The Art of Naming<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3
4
5
6
7
8</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">Handler</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> String data<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String temp<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #303090; font-weight: bold;">int</span> <span style="color: #0060b0; font-weight: bold;">c</span><span style="color: #303030;">(</span><span style="color: #303090; font-weight: bold;">int</span> a<span style="color: #303030;">,</span> <span style="color: #303090; font-weight: bold;">int</span> a2<span style="color: #303030;">){</span>
<span style="color: #303090; font-weight: bold;">int</span> result <span style="color: #303030;">=</span> a<span style="color: #303030;">+</span>a2<span style="color: #303030;">;</span>
<span style="color: grey;">//...</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMLbFDlCXZpqSOKtJ14uezHIcuY0ZjHt2aIw6FVdGQefAwYWXMX203zTN0zOqNKaCzjVqtKCDrgN3qypoXStbue90aSC2TOwfAZVVXtAOcmuxsDqVrEaLTjjIcX6cBAwNM78hLhbl92TE/s1600/12178628141677313153AJ_Buddy_frightened.svg.hi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMLbFDlCXZpqSOKtJ14uezHIcuY0ZjHt2aIw6FVdGQefAwYWXMX203zTN0zOqNKaCzjVqtKCDrgN3qypoXStbue90aSC2TOwfAZVVXtAOcmuxsDqVrEaLTjjIcX6cBAwNM78hLhbl92TE/s200/12178628141677313153AJ_Buddy_frightened.svg.hi.png" width="180" /></a></div>
<br />
<h3>
Why is Naming so important?</h3>
Because its a matter of Quality.<br />
Naming = Readability = Understandability = Maintainability = Quality.<br />
Good Names make your code readable, which is an essential feature for every person that has to work on it, including yourself. Soon after written, you'll forget about the details. Getting into it and understanding again can be tough and frustrating. The right Names will redeem yourself and others from those barriers. You'll might think for yourself: "No!!! I don't have the time to make this all clean and perfect. I just have to get the thing done as fast as possible, and it's no problem because i won't have to deal with it after its finished anyways..." - That's just wishful thinking. Software never ever becomes completed. Thats part of its nature. In fact, the opposite is the truth: By choosing the right names carefully, you save a lot of time from the very first day on. You keep your mind free of needless noise that slows your progression down.<br />
<br />
<h3>
How to choose the right Names?</h3>
According to "<a href="http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code</a>", Names should:<br />
<ul>
<li>Be intention revealing</li>
<li>Avoid disinformation</li>
<li>Make meaningful distinctions</li>
<li>Be pronounceable</li>
<li>Be searchable</li>
</ul>
But i'll add one point<br />
<ul>
<li>be unmistakable (which might already be part of avoiding disinformation)</li>
</ul>
<br />
Be skeptical about a name in the first place, and dont accept it until every bit of skepticism has been eliminated. Complete Words are usually better than Acronyms, AND .... avoid redundancy!!<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">Book</span><span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">public</span> String<span style="color: #303030;">[]</span> <strike>book</strike>Page<span style="color: #303030;">;</span> <span style="color: grey;">// Don't repeat book since its given in the classname!</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
The art is to combine good names so that your code becomes a meaningful, selfdocumenting story.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">if</span><span style="color: #303030;">(</span>plant<span style="color: #303030;">.</span><span style="color: #0000c0;">needsWater</span><span style="color: #303030;">())</span> gardener<span style="color: #303030;">.</span><span style="color: #0000c0;">water</span><span style="color: #303030;">(</span>plant<span style="color: #303030;">)</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<h3>
Classes, Interfaces and Abstracts</h3>
Stay away from 'Manager', 'Handler' and the such. 'SomethingManager' doesn't mean anything specific and is clearly not unmistakable. Use Design Patterns in your Names. They are common knowledge and give a good information about what a Class is doing. Eg.: ShadowedBorderDecorator. Name Interfaces as what they are, and don't add Pre- / Suffixes to them (IFoo, BarInterface). Client-classes don't care if they work on Interfaces or Implementations. And it's not the Names job to indicate it's Type. You dont name a Variable intNumber either, do you? It's a violation of the DRY principle. Using Abstract in a Classname is debatable. While it's pretty common, it still violates the DRY principle. Decide for yourself.<br />
<br />
<h3>
Common Errors in Variablenaming</h3>
<br />
<b>Repeating Type in Variablenames:</b><br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3
4</pre>
</td><td><pre style="line-height: 125%; margin: 0;">Timestamp creationTime<span style="color: #303030;">;</span>
Date date<span style="color: #303030;">;</span>
String<span style="color: #303030;">[]</span> bookArray<span style="color: #303030;">;</span>
SomeType somethingObject
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<b>Adding "is" as a Prefix to booleans:</b><br />
isActive. So the getter becomes isIsActive() or what?<br />
<br />
<b>Consecutive numbers.</b><br />
There is nothing harder to read than a calculation using a1, a2 and a3 multiple times.<br />
<br />
<b>Generic names</b>:<br />
temp, data, other, object, result, value and so on<br />
<br />
<b>Inconsistency:</b><br />
Mixing multiple Naming Strategies, or choosing one without 100% sticking to it.<br />
E.g.: Mixing camelCase with under_scoredGregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com3tag:blogger.com,1999:blog-1178805312154210159.post-25797501187229939772013-05-08T21:19:00.000+02:002013-10-08T21:32:41.018+02:00Master the unpredictableHave you ever come to work on a Project that you cant quite overlook? Are Requirements not yet clear or changing fast? Here are some tips to get along.<br />
<br />
<h3>
Use Tracer Bullets</h3>
Don't specify your software to death. Just grab your best idea, and give it a shot. Tracer Bullets are similar to Prototypes with one very important difference. Prototypes are built to proove something, and then be thrown away. They are not intended for real production. Even some drawing on a paper could be a prototype. A Tracer Bullet might get thrown away, but it is not intended to in the first place. It is developed as stable, clean and complete as needed, to use it for real production. A Tracer Bullet that hits its target, becomes a trunk.<br />
<br />
<h3>
Develop Leaves first</h3>
What do i mean with a leaf? Leaves are small exchangable software components or modules, that can be written independently, tested in isolation, and sometimes even run autonomous. They only perform a very specific task, not more. Find the leaves in your Project, and start developing the leaf with the highest risk.<br />
<br />
<h3>
Dont Reinvent the Wheel</h3>
99% of the problems that you face in your project have already been solved. Solving these by yourself can easily become a waste of time. Even the most trivial seeming problems are not trivial at all. Underestimating those is the issue in the first place, nevertheless it happens all the time. Well, its just logical to understimate the unsolved as you cannot know all the details until you solved it yourself. Analysing the problemdomain, concepting and realizing a solution can be a great way to learn, but is not very beneficial. Its in fact a risk, since it can lead to misconception or become a timeconsuming task that exceed your resources. You might even have to throw away your first attempts. Also, your outcome would be buggy, whereas established opensource software is usually stable thanks to its brave communities.<br />
"Make or Buy" was a common phrase. I think it should be "Make or Find" by now, since opensource got really big. Rather invest your time into research opensource, and stay skeptical with what you find. When you compare 3rd party software, consider<br />
<ul>
<li><b>Stability</b>: Is it still beta, or did it have some stable releases yet? Who is the organization behind? Is the code clean and tested?</li>
<li><b>Activity</b>: Can you find out how many developers this software has? When was the last commit? How frequently do they release a new build?</li>
<li><b>Support</b>: Does it offer a good documentation? How about examples? Is there a public Issue Tracker? How many issues have been submitted yet and how many have been solved? Is there a Forum, literature, and a big community? Are there any big names that use this software?</li>
<li><b>Critisism</b>: Is there anything bad that you should know in the first place? Search for reliable critiques and comparisons.</li>
</ul>
<br />
<ul>
</ul>
<h3>
Estimation is a waste of time</h3>
Every hour that you invest in estimation, could also be invested in producing real outcome. Your estimation will be inaccurate anyway. When requirements change, you even have to change your estimations. If you have to estimate, because the business needs it, try to split your project into smaller independent parts first, and multiply your estimation with a risk factor (times two for example). In the end you`ll need it.<br />
<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com3tag:blogger.com,1999:blog-1178805312154210159.post-58473346336328948632013-04-26T21:14:00.001+02:002013-08-03T21:00:55.115+02:00Standalone Java Webapp made easy with Maven<h2>
Introduction </h2>
As you may already know, creating a war archive and deploying it on a preinstalled Servlet Container is not the only way running a Java webapp, since you can also embed the Web-Server in the application itself. Sometimes such artifacts are delivered as standalone executable programs that can be easily started and stopped in the commandline and even run as a service in the background. Maybe you should also consider producing your app this way and benefit from its huge advantages:<br />
<ul>
<li>No preinstalled Webserver/Servlet Container required that would take additional maintenance.</li>
<li>Easy Cross-Platform. Same artifact can of course be run on any System.</li>
<li>Complete Standalone Software </li>
</ul>
<a href="http://www.sonarsource.org/">Apache Sonar</a> is a great Example of such Software. It uses an embedded Jetty Server and creates an embedded H2 Database for persistence that can be replaced in configuration. As you can see <a href="http://svn.codehaus.org/sonar/trunk/sonar-application/src/main/assembly/bin/">here</a> they prepared startup scripts for any Platform that execute the actual <a href="http://svn.codehaus.org/sonar/trunk/sonar-application/src/main/java/org/sonar/application/StartServer.java">StartServer</a> class.<br />
<h2>
Embedded Tomcat</h2>
In my tutorial ill use an embedded Tomcat as a Servlet Container. So we want to add the Maven dependencies first.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: grey;"><!-- embedded Tomcat --></span>
<span style="color: #007000;"><dependency></span>
<span style="color: #007000;"><groupId></span>org.apache.tomcat.embed<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>tomcat-embed-core<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>7.0.37<span style="color: #007000;"></version></span>
<span style="color: #007000;"></dependency></span>
<span style="color: #007000;"><dependency></span>
<span style="color: #007000;"><groupId></span>org.apache.tomcat.embed<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>tomcat-embed-logging-log4j<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>7.0.37<span style="color: #007000;"></version></span>
<span style="color: #007000;"></dependency></span>
<span style="color: #007000;"><dependency></span>
<span style="color: #007000;"><groupId></span>org.apache.tomcat.embed<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>tomcat-embed-jasper<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>7.0.37<span style="color: #007000;"></version></span>
<span style="color: #007000;"></dependency></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
We can use them now to create a StartServer class<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">final</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">StartServer</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: #0060b0; font-weight: bold;">StartServer</span><span style="color: #303030;">()</span> <span style="color: #303030;">{</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #303090; font-weight: bold;">void</span> <span style="color: #0060b0; font-weight: bold;">main</span><span style="color: #303030;">(</span>String<span style="color: #303030;">[]</span> args<span style="color: #303030;">)</span> <span style="color: green; font-weight: bold;">throws</span> Exception <span style="color: #303030;">{</span>
<span style="color: grey;">// We will set the basedir Systemproperty accordingly when running the Program</span>
<span style="color: grey;">// Actually the mavenplugin appassembler will do this for us</span>
String basedir <span style="color: #303030;">=</span> System<span style="color: #303030;">.</span><span style="color: #0000c0;">getProperty</span><span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"basedir"</span><span style="color: #303030;">);</span>
String webappLocation <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">new</span> File<span style="color: #303030;">(</span>basedir <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">"/webapp"</span><span style="color: #303030;">).</span><span style="color: #0000c0;">getAbsolutePath</span><span style="color: #303030;">();</span>
<span style="color: #303090; font-weight: bold;">int</span> port <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">8080</span><span style="color: #303030;">;</span>
Tomcat tomcat <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">new</span> Tomcat<span style="color: #303030;">();</span>
tomcat<span style="color: #303030;">.</span><span style="color: #0000c0;">setPort</span><span style="color: #303030;">(</span>port<span style="color: #303030;">);</span>
tomcat<span style="color: #303030;">.</span><span style="color: #0000c0;">addWebapp</span><span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"/"</span><span style="color: #303030;">,</span> webappLocation<span style="color: #303030;">);</span>
tomcat<span style="color: #303030;">.</span><span style="color: #0000c0;">start</span><span style="color: #303030;">();</span>
tomcat<span style="color: #303030;">.</span><span style="color: #0000c0;">getServer</span><span style="color: #303030;">().</span><span style="color: #0000c0;">await</span><span style="color: #303030;">();</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<h2>
Exploded War</h2>
Now we need to make an exploded war in our "target" directory. I choose to create a folder inside "target" that holds the application as a whole including bin files, configuration and the webapp itself. This makes it easy to transport the complete app to another machine.<br />
<ul>
<li>src/... </li>
<li>target/myapp/bin</li>
<li>target/myapp/conf</li>
<li>target/myapp/webapp</li>
</ul>
Ill include the maven-war-plugin to create the exploded war.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><plugin></span>
<span style="color: #007000;"><groupId></span>org.apache.maven.plugins<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>maven-war-plugin<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>2.3<span style="color: #007000;"></version></span>
<span style="color: #007000;"><executions></span>
<span style="color: #007000;"><execution></span>
<span style="color: #007000;"><id></span>war-exploded<span style="color: #007000;"></id></span>
<span style="color: #007000;"><phase></span>package<span style="color: #007000;"></phase></span>
<span style="color: #007000;"><goals></span>
<span style="color: #007000;"><goal></span>exploded<span style="color: #007000;"></goal></span>
<span style="color: #007000;"></goals></span>
<span style="color: #007000;"><configuration></span>
<span style="color: #007000;"><webappDirectory></span>${project.build.directory}/myapp/webapp<span style="color: #007000;"></webappDirectory></span>
<span style="color: #007000;"><archiveClasses></span>true<span style="color: #007000;"></archiveClasses></span>
<span style="color: #007000;"></configuration></span>
<span style="color: #007000;"></execution></span>
<span style="color: #007000;"></executions></span>
<span style="color: #007000;"></plugin></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
If you run <i>mvn clean package</i> right now you should get your webapp compiled into <i>target/myapp/webapp</i><br />
<h2>
Startup Scripts</h2>
Finally we need startup Scripts to actually run our application. We need a shell script for unix Systems and a bat file for Windows. The <a href="http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/">Appassembler</a> maven plugin comes in handy here. It is a very thoughtout plugin that creates exactly what we need and even sets the basedir Systemproperty. I'll configure it to use our exploded webapp and StartServer class.<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 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</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><plugin></span>
<span style="color: #007000;"><groupId></span>org.codehaus.mojo<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>appassembler-maven-plugin<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>1.3<span style="color: #007000;"></version></span>
<span style="color: #007000;"><configuration></span>
<span style="color: #007000;"><assembleDirectory></span>${project.build.directory}/myapp<span style="color: #007000;"></assembleDirectory></span>
<span style="color: #007000;"><repositoryLayout></span>flat<span style="color: #007000;"></repositoryLayout></span>
<span style="color: #007000;"><repositoryName></span>webapp/WEB-INF/lib<span style="color: #007000;"></repositoryName></span>
<span style="color: #007000;"><generateRepository></span>false<span style="color: #007000;"></generateRepository></span>
<span style="color: #007000;"><copyConfigurationDirectory></span>true<span style="color: #007000;"></copyConfigurationDirectory></span>
<span style="color: #007000;"><configurationDirectory></span>conf<span style="color: #007000;"></configurationDirectory></span>
<span style="color: #007000;"><programs></span>
<span style="color: #007000;"><program></span>
<span style="color: #007000;"><mainClass></span>com.myapp.StartServer<span style="color: #007000;"></mainClass></span>
<span style="color: #007000;"><name></span>myapp<span style="color: #007000;"></name></span>
<span style="color: #007000;"></program></span>
<span style="color: #007000;"></programs></span>
<span style="color: #007000;"></configuration></span>
<span style="color: #007000;"><executions></span>
<span style="color: #007000;"><execution></span>
<span style="color: #007000;"><phase></span>package<span style="color: #007000;"></phase></span>
<span style="color: #007000;"><goals></span>
<span style="color: #007000;"><goal></span>assemble<span style="color: #007000;"></goal></span>
<span style="color: #007000;"></goals></span>
<span style="color: #007000;"></execution></span>
<span style="color: #007000;"></executions></span>
<span style="color: #007000;"></plugin></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Done. Appassembler now creates executable scripts for all platforms inside the <i>target/myapp/bin</i> directory. You could even put configuration files into <i>src/main/config</i> that would be copied into <i>target/myapp/conf</i> automatically by the plugin.<br />
<br />
<h2>
Result</h2>
<br />
If we run mvn clean package now we get a completely transportable standalone webapp in our <i>target</i> directory!<br />
<br />
<h2>
</h2>
<h2>
</h2>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com1tag:blogger.com,1999:blog-1178805312154210159.post-53763142308367651592013-04-10T20:17:00.001+02:002013-08-03T21:01:12.188+02:00I18n of JPA EntitiesSadly the support for i18n for Entities in JPA is actually very poor to non-existent. There's just basically no out of the box solution provided by Hibernate & Co, although i18n is a feature that could be considered mandatory for a powerful ORM Framework. If you take a look at PHP for example Doctrine supports i18n very well. So besides some really unpopular i18n extensions on forums/github you are basically on your own.<br />
<br />
<h3>
So how do you do it? </h3>
There isn't really a general solution to achieve i18n. There are many different ways and you have to choose which is actually best for you. If you do have a relatively small amount of data and ordering by translations is not necessary you can store "keys" in your tables that are being translated by Spring i18n for example. Spring i18n could store the translations in separate property files. Since you wont have to worry about performance, this is a very easy way to achieve i18n.<br />
<br />
But lets say you have lots of data, and you need to order it on the database side. With such requirements you are better off storing translations inside your database tables. While there are guides, and also an opensource framework on the internet that implement i18n with one centralized translation-table that holds all translations i highly recommend not to follow that idea. The problem with this solution is, that you will have to add one more join for every field that has to be translated, whereas multiple joins for a single table with lots of data can easily become a performanceissue.<br />
Its better to follow the approach to create a separate translation-table for every entity. This means that you would have one entity containing simple data, and another one containing only the fields that require translation. Like so:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvlU2wYYnyRrZ1RNayD0DViuXCo2VJxNQ1ZmaxxXx-tneL7rP6rwo9O25uCas6Nvg5T2Y9U0kC4sR7QEq86wzVYPcVhe03DQEehG4z1vUKJh_k7IyKCaykwzD_n0ECPSi_o1UG9AfCdzY/s1600/i18n_jpa.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvlU2wYYnyRrZ1RNayD0DViuXCo2VJxNQ1ZmaxxXx-tneL7rP6rwo9O25uCas6Nvg5T2Y9U0kC4sR7QEq86wzVYPcVhe03DQEehG4z1vUKJh_k7IyKCaykwzD_n0ECPSi_o1UG9AfCdzY/s320/i18n_jpa.png" width="320" /></a></div>
<br />
This schema is pretty normalized and you only have a single join on fetching an entity, while you can still order appropriate.<br />
<br />
Your entities would look like this:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #505050; font-weight: bold;">@Entity</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">Book</span> <span style="color: #303030;">{</span>
<span style="color: #505050; font-weight: bold;">@Id</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: #303090; font-weight: bold;">int</span> isbn<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String author<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> Date releaseDate<span style="color: #303030;">;</span>
<span style="color: #505050; font-weight: bold;">@OneToMany</span>
<span style="color: #505050; font-weight: bold;">@JoinColumn</span><span style="color: #303030;">(</span>name <span style="color: #303030;">=</span> <span style="background-color: #fff0f0;">"isbn"</span><span style="color: #303030;">)</span>
<span style="color: green; font-weight: bold;">private</span> List<span style="color: #303030;"><</span>BookTranslation<span style="color: #303030;">></span> translations<span style="color: #303030;">;</span>
<span style="color: grey;">// constructor, getters and setters -...</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
and that<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #505050; font-weight: bold;">@Entity</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookTranslation</span> <span style="color: green; font-weight: bold;">implements</span> Serializable <span style="color: #303030;">{</span>
<span style="color: #505050; font-weight: bold;">@Id</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: #303090; font-weight: bold;">int</span> isbn<span style="color: #303030;">;</span>
<span style="color: #505050; font-weight: bold;">@Id</span>
<span style="color: green; font-weight: bold;">private</span> String locale<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String title<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String description<span style="color: #303030;">;</span>
<span style="color: grey;">// constructor, getters and setters -...</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
You could then fetch a book with its translations with:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">select</span> b <span style="color: green; font-weight: bold;">from</span> Book b <span style="color: green; font-weight: bold;">join</span> <span style="color: green; font-weight: bold;">fetch</span> b.translations bt <span style="color: green; font-weight: bold;">where</span> bt.locale <span style="color: #303030;">=</span> <span style="background-color: #fff0f0;">'de'</span>;
</pre>
</div>
<br />
If you cannot accept your ServiceLayer to deliver two entities for every Book only because of translations, i suggest you to implement some <a href="http://en.wikipedia.org/wiki/Data_transfer_object">DTO</a> like this BookTO which holds all values.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookTO</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: #303090; font-weight: bold;">int</span> isbn<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String author<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> Date releaseDate<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String title<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> String description<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
You'd just need to map the values of Book and BookTranslation to BookTO within your ServiceLayer and also return BookTO instead of Book in your ServiceLayer.<br />
<br />
This solution might not always be the most appropriate, but it definitely comes in handy sometimes. Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com2tag:blogger.com,1999:blog-1178805312154210159.post-67963511904201119202013-03-24T15:01:00.001+01:002013-08-03T21:01:24.971+02:00Automatically generated Class Diagrams using Maven & UMLGraphDrawing 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.<br />
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.<br />
<br />
Since maven can run javadoc at build phase it's perfect. You just have to configurate the maven-javadoc-plugin to use UMLGraph.<br />
<br />
<h3>
Configurate Maven to use UMLGraph</h3>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><reporting></span>
<span style="color: #007000;"><plugins></span>
<span style="color: #007000;"><plugin></span>
<span style="color: #007000;"><groupId></span>org.apache.maven.plugins<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>maven-javadoc-plugin<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>2.9<span style="color: #007000;"></version></span>
<span style="color: #007000;"><configuration></span>
<span style="color: #007000;"><doclet></span>org.umlgraph.doclet.UmlGraphDoc<span style="color: #007000;"></doclet></span>
<span style="color: #007000;"><docletArtifact></span>
<span style="color: #007000;"><groupId></span>org.umlgraph<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>umlgraph<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>5.6<span style="color: #007000;"></version></span>
<span style="color: #007000;"></docletArtifact></span>
<span style="color: #007000;"><additionalparam></span>-views -all<span style="color: #007000;"></additionalparam></span>
<span style="color: #007000;"><useStandardDocletOptions></span>true<span style="color: #007000;"></useStandardDocletOptions></span>
<span style="color: #007000;"></configuration></span>
<span style="color: #007000;"></plugin></span>
<span style="color: #007000;"></plugins></span>
<span style="color: #007000;"></reporting></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<span style="color: red;">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 <a href="http://www.umlgraph.org/ver.html">version 5.5</a>.</span><br />
<br />
If we run <u>mvn site</u> right now, we will just get that error:<br />
<b><span class="postbody"><a class="api" href="http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html" target="_new" title="Java API">java.io.IOException</a>: Cannot run program "dot": <a class="api" href="http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html" target="_new" title="Java API">java.io.IOException</a>: error=2, No such file or directory </span></b><br />
<span class="postbody">This means that the program dot was not found which is a part of the graphviz library.</span><br />
<span class="postbody"> </span><b><span class="postbody"> </span></b><br />
<h3>
Install Graphviz</h3>
For UMLGraph to run you need <a href="http://www.graphviz.org/">graphviz</a> installed. Go to the Download Page, and choose your package. On linux you could even <i><b>sudo aptget install graphviz</b></i>. Beware that you might have to reboot or relogin to use graphviz, because the Systems Path is extended during installation.<br />
<br />
<h3>
First Result</h3>
Run <u>mvn site</u>, and open target/site/apidocs/index.html afterwards.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Ls57WB_vLj5FxXZ9USBmO5qhyphenhyphenNZirWDrbJWyXh8pY-F1lSAZOKel7gcnbcTDcxKLmBcFPZE30551CSamhKMwiYxbs2ZDhFG8tKWkyZMstZiX7-wJ53vCH6DTIS4L-pR7QvFxAHguuCw/s1600/umlgraph.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9Ls57WB_vLj5FxXZ9USBmO5qhyphenhyphenNZirWDrbJWyXh8pY-F1lSAZOKel7gcnbcTDcxKLmBcFPZE30551CSamhKMwiYxbs2ZDhFG8tKWkyZMstZiX7-wJ53vCH6DTIS4L-pR7QvFxAHguuCw/s1600/umlgraph.png" /></a></div>
<br />
As you can see its drawing beautiful and accurate UML Class Diagrams.<br />
<br />
<h3>
Custom Configuration</h3>
If you dont want attributes/methods or other extras you are totally free to configurate those graphs. See <a href="http://www.umlgraph.org/doc/cd-opt.html">Class Diagram Options</a>. Just add them to the <br />
<pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><additionalparam></span>-views -all<span style="color: #007000;"></additionalparam></span></pre>
tag in pom.xml
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com3tag:blogger.com,1999:blog-1178805312154210159.post-17729082986516834382013-03-16T15:39:00.000+01:002013-10-15T21:10:43.927+02:008 Things you should not be afraid of as a Developer<h3>
Change</h3>
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 <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> and <a href="http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it">YAGNI</a>. 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 <a href="http://en.wikipedia.org/wiki/Code_refactoring">Refactor</a>! 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.<br />
<blockquote class="tr_bq">
"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</blockquote>
<h3>
Removal of dead / commented out Code</h3>
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.<br />
<blockquote class="tr_bq">
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." - Antoine de Saint-Exupery</blockquote>
<h3>
Making Mistakes</h3>
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.<br />
<blockquote class="tr_bq">
"Anyone who has never made a mistake has never tried anything new." - Albert Einstein</blockquote>
<h3>
Showing your code to others</h3>
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.<br />
<br />
<h3>
Failure</h3>
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.<br />
<blockquote class="tr_bq">
"I have not failed. I've just found 10,000 ways that won't work." - Thomas A. Edison</blockquote>
<h3>
Your own codes stability</h3>
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.<br />
<br />
<h3>
New & Complex Technology</h3>
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. <a href="http://www.datamation.com/data-center/when-developers-are-afraid-to-try-something-new-1.html">This</a> is a great story about developers being afraid to try something new.<br />
<br />
<h3>
Fighting Time Pressure</h3>
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.<br />
<blockquote class="tr_bq">
"Programming is like sex: one mistake and you’re providing support for a lifetime." - Michael Sinz</blockquote>
Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com4tag:blogger.com,1999:blog-1178805312154210159.post-1833593152407884542013-03-09T17:20:00.001+01:002013-08-03T21:02:06.554+02:00Wanna Cache? Decorate!!<h2>
The Decorator Pattern</h2>
Class Diagram:
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGNaQHhoAG_Z_4YJXnBTN7Hbh50MwMHmtQeNyx3qWEA_-zRdsPtgNbMJwkFs9P51jV3V00ZpyL603NQDgofDUtQNk9IjG47a719D9xQrsuwov6dOMJCpyD8h_K73yKK4NIXHQFCLju6v0/s1600/decorator_pattern.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGNaQHhoAG_Z_4YJXnBTN7Hbh50MwMHmtQeNyx3qWEA_-zRdsPtgNbMJwkFs9P51jV3V00ZpyL603NQDgofDUtQNk9IjG47a719D9xQrsuwov6dOMJCpyD8h_K73yKK4NIXHQFCLju6v0/s1600/decorator_pattern.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
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.<br />
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:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSTE6bzoURaYNYE0yxq7-TIVEvZYpjpGCDQQO1xzxtL4G8nFW07KCn7Lw-SUhO2gkZJxTQB27_3m2iV1Sl1e5S0-AvX8SOlic5-AG3lvkC3BDB6EE3dhkubDG6-FYN8vfAudVUkEVnlgQ/s1600/cache_decorator_steps.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSTE6bzoURaYNYE0yxq7-TIVEvZYpjpGCDQQO1xzxtL4G8nFW07KCn7Lw-SUhO2gkZJxTQB27_3m2iV1Sl1e5S0-AvX8SOlic5-AG3lvkC3BDB6EE3dhkubDG6-FYN8vfAudVUkEVnlgQ/s1600/cache_decorator_steps.png" /></a></div>
Just follow the Steps:<br />
In the first example there is no Decorator. So SomeClass directly speaks to BookService<br />
In the second example there is a single Decorator. Therefore the following steps apply<br />
<ol>
<li>SomeClass calls SomeDecoratorA.</li>
<li>SomeDecoratorA delegates the call to the real BookService. The Decorator could even manipulate the call in this step.</li>
<li>BookService returns a result. SomeDecoratorA now holds the result, and may manipulate it.</li>
<li>Finally, SomeDecoratorA hands the result over to the original caller SomeClass.</li>
</ol>
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.<br />
<br />
<h3>
Usage Examples</h3>
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).<br />
<br />
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.<br />
<br />
<h3>
Applying Cache with Decorator Pattern</h3>
Class Diagram:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxAsZkyP5CvXSuU20jBVphpZ9jqeoLNzU2mYKY1MIZZhbq-_45hMqrnWnO8eYZhg2NbYow_aeEcdjS260O6lRCrme-y2kGIVhXDvN8capoWUOY1NvP_AKk3CqmvHq_B-IMX5cZGHi-t6A/s1600/decorator_cache.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxAsZkyP5CvXSuU20jBVphpZ9jqeoLNzU2mYKY1MIZZhbq-_45hMqrnWnO8eYZhg2NbYow_aeEcdjS260O6lRCrme-y2kGIVhXDvN8capoWUOY1NvP_AKk3CqmvHq_B-IMX5cZGHi-t6A/s1600/decorator_cache.png" /></a></div>
<br />
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.<br />
<br />
I start with the BookService Interface,<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">interface</span> <span style="color: #b00060; font-weight: bold;">BookService</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> findAll<span style="color: #303030;">();</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
and its prime implementation.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookServiceImpl</span> <span style="color: green; font-weight: bold;">implements</span> BookService <span style="color: #303030;">{</span>
<span style="color: #505050; font-weight: bold;">@Override</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> findAll<span style="color: #303030;">()</span> <span style="color: #303030;">{</span>
System<span style="color: #303030;">.</span><span style="color: #0000c0;">out</span><span style="color: #303030;">.</span><span style="color: #0000c0;">println</span><span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"load new data"</span><span style="color: #303030;">);</span>
List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> books <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">new</span> ArrayList<span style="color: #303030;"><</span>Book<span style="color: #303030;">>();</span>
books<span style="color: #303030;">.</span><span style="color: #0000c0;">add</span><span style="color: #303030;">(</span><span style="color: green; font-weight: bold;">new</span> Book<span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"BookA"</span><span style="color: #303030;">));</span>
books<span style="color: #303030;">.</span><span style="color: #0000c0;">add</span><span style="color: #303030;">(</span><span style="color: green; font-weight: bold;">new</span> Book<span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"BookB"</span><span style="color: #303030;">));</span>
books<span style="color: #303030;">.</span><span style="color: #0000c0;">add</span><span style="color: #303030;">(</span><span style="color: green; font-weight: bold;">new</span> Book<span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"BookC"</span><span style="color: #303030;">));</span>
<span style="color: green; font-weight: bold;">return</span> books<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Here is the Code of the Cache Class. In this example it's caching forever, but thats alright.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">Cache</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> storage<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #303090; font-weight: bold;">void</span> <span style="color: #0060b0; font-weight: bold;">save</span><span style="color: #303030;">(</span>List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> books<span style="color: #303030;">){</span>
<span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">storage</span> <span style="color: #303030;">=</span> books<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #303090; font-weight: bold;">boolean</span> <span style="color: #0060b0; font-weight: bold;">hasResult</span><span style="color: #303030;">(){</span>
<span style="color: green; font-weight: bold;">if</span><span style="color: #303030;">(</span>storage <span style="color: #303030;">!=</span> <span style="color: green; font-weight: bold;">null</span><span style="color: #303030;">){</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">true</span><span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">false</span><span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> load<span style="color: #303030;">(){</span>
System<span style="color: #303030;">.</span><span style="color: #0000c0;">out</span><span style="color: #303030;">.</span><span style="color: #0000c0;">println</span><span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"load from cache"</span><span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">return</span> storage<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Now lets continue with the Decorator Base Class. It has a preemtive Constructor to hand over the decorated Object.<br />
<br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3
4
5
6
7
8</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">abstract</span> <span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookServiceDecorator</span> <span style="color: green; font-weight: bold;">implements</span> BookService<span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">protected</span> BookService decorated<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #0060b0; font-weight: bold;">BookServiceDecorator</span><span style="color: #303030;">(</span>BookService decorated<span style="color: #303030;">){</span>
<span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">decorated</span> <span style="color: #303030;">=</span> decorated<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
And finally the CacheDecorator. It Checks the Cache before calling BookServiceImpl.<br />
<br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookServiceCacheDecorator</span> <span style="color: green; font-weight: bold;">extends</span> BookServiceDecorator <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> Cache cache<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #0060b0; font-weight: bold;">BookServiceCacheDecorator</span><span style="color: #303030;">(</span>BookService decorated<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">super</span><span style="color: #303030;">(</span>decorated<span style="color: #303030;">);</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #0060b0; font-weight: bold;">BookServiceCacheDecorator</span><span style="color: #303030;">(</span>BookService decorated<span style="color: #303030;">,</span> Cache cache<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">super</span><span style="color: #303030;">(</span>decorated<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">cache</span> <span style="color: #303030;">=</span> cache<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: #505050; font-weight: bold;">@Override</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> findAll<span style="color: #303030;">()</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">if</span><span style="color: #303030;">(</span>cache<span style="color: #303030;">.</span><span style="color: #0000c0;">hasResult</span><span style="color: #303030;">()){</span>
<span style="color: green; font-weight: bold;">return</span> cache<span style="color: #303030;">.</span><span style="color: #0000c0;">load</span><span style="color: #303030;">();</span>
<span style="color: #303030;">}</span>
List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> books <span style="color: #303030;">=</span> decorated<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span>
cache<span style="color: #303030;">.</span><span style="color: #0000c0;">save</span><span style="color: #303030;">(</span>books<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">return</span> books<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Now two different use cases. One without Decorator, and one with the Cache Decorator:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;">1
2
3
4
5
6
7
8
9</pre>
</td><td><pre style="line-height: 125%; margin: 0;">BookService bookService <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">new</span> BookServiceImpl<span style="color: #303030;">();</span>
bookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load new data</span>
bookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load new data</span>
bookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load new data</span>
BookService cachedBookService <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">new</span> BookServiceCacheDecorator<span style="color: #303030;">(</span><span style="color: green; font-weight: bold;">new</span> BookServiceImpl<span style="color: #303030;">(),</span> <span style="color: green; font-weight: bold;">new</span> Cache<span style="color: #303030;">());</span>
cachedBookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load new data</span>
cachedBookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load from cache</span>
cachedBookService<span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">();</span> <span style="color: grey;">// prints: load from cache</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
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.Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com2tag:blogger.com,1999:blog-1178805312154210159.post-2343518056609254062013-03-06T20:20:00.000+01:002013-08-03T21:01:49.617+02:00Avoid too many Parameters using the Builder PatternToday i want to show you another way to use the <a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder Pattern</a>. From what i<cite><b>'</b></cite>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 <a href="http://en.wikipedia.org/wiki/Fluent_interface">Fluent Interface</a>.<br />
<br />
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: <a href="http://www.amazon.com/dp/0132350882/?tag=stackoverfl08-20">Clean Code</a>. 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 <a href="http://www.martinfowler.com/eaaCatalog/queryObject.html">Query Object</a> to solve the problem.<br />
<br />
As we should always program against Interfaces to keep things modular, ill start with the Interface:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 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</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">interface</span> <span style="color: #b00060; font-weight: bold;">BookService</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">public</span> Book <span style="color: #0060b0; font-weight: bold;">create</span><span style="color: #303030;">(</span>Book book<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #303090; font-weight: bold;">void</span> <span style="color: #0060b0; font-weight: bold;">delete</span><span style="color: #303030;">(</span>String isbn<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">query</span><span style="color: #303030;">();</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">interface</span> <span style="color: #b00060; font-weight: bold;">Query</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">isName</span><span style="color: #303030;">(</span>String name<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">hasAuthor</span><span style="color: #303030;">(</span>String author<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">isCheaperThan</span><span style="color: #303030;">(</span>Float price<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">isIsbn</span><span style="color: #303030;">(</span>String isbn<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">hasMorePagesThan</span><span style="color: #303030;">(</span>Long pages<span style="color: #303030;">);</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">isAvailable</span><span style="color: #303030;">();</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> find<span style="color: #303030;">();</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
So the Interface looks pretty neat. It allows you to write something like: <br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">bookService<span style="color: #303030;">.</span><span style="color: #0000c0;">query</span><span style="color: #303030;">().</span><span style="color: #0000c0;">hasAuthor</span><span style="color: #303030;">(</span><span style="background-color: #fff0f0;">"Bob"</span><span style="color: #303030;">).</span><span style="color: #0000c0;">isCheaperThan</span><span style="color: #303030;">(</span><span style="color: #6000e0; font-weight: bold;">20.9</span><span style="color: #303030;">).</span><span style="color: #0000c0;">isAvailable</span><span style="color: #303030;">().</span><span style="color: #0000c0;">find</span><span style="color: #303030;">();</span>
</pre>
</div>
<br />
While the Query could be considered as an implementation of the <a href="http://www.martinfowler.com/eaaCatalog/queryObject.html">Query Object pattern</a> 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).<br />
<br />
To clear things up, i want to show you an implementation example using <a href="http://www.springsource.org/spring-data">Spring-Data</a>. 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. <br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 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</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #505050; font-weight: bold;">@Transactional</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">BookServiceImpl</span> <span style="color: green; font-weight: bold;">implements</span> BookService <span style="color: #303030;">{</span>
<span style="color: #505050; font-weight: bold;">@Autowired</span>
<span style="color: green; font-weight: bold;">private</span> BookRepository bookRepository<span style="color: #303030;">;</span>
<span style="color: grey;">// ...</span>
<span style="color: #505050; font-weight: bold;">@Override</span>
<span style="color: #505050; font-weight: bold;">@Transactional</span><span style="color: #303030;">(</span>readOnly<span style="color: #303030;">=</span><span style="color: green; font-weight: bold;">true</span><span style="color: #303030;">)</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">query</span><span style="color: #303030;">()</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">new</span> <span style="color: #0060b0; font-weight: bold;">QueryImpl</span><span style="color: #303030;">(</span><span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">bookRepository</span><span style="color: #303030;">);</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">QueryImpl</span> <span style="color: green; font-weight: bold;">implements</span> Query<span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">private</span> BookRepository bookRepository<span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">private</span> Specifications<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> filters <span style="color: #303030;">=</span> <span style="color: green; font-weight: bold;">null</span><span style="color: #303030;">;</span>
<span style="color: green; font-weight: bold;">public</span> <span style="color: #0060b0; font-weight: bold;">QueryImpl</span><span style="color: #303030;">(</span>BookRepository bookRepository<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">bookRepository</span> <span style="color: #303030;">=</span> bookRepository<span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: #303090; font-weight: bold;">void</span> <span style="color: #0060b0; font-weight: bold;">addFilter</span><span style="color: #303030;">(</span>Specification<span style="color: #303030;"><</span>FlowMessage<span style="color: #303030;">></span> filter<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
filters <span style="color: #303030;">=</span> <span style="color: #303030;">(</span>filters <span style="color: #303030;">==</span> <span style="color: green; font-weight: bold;">null</span><span style="color: #303030;">)</span> <span style="color: #303030;">?</span> where<span style="color: #303030;">(</span>filter<span style="color: #303030;">)</span> <span style="color: #303030;">:</span> filters<span style="color: #303030;">.</span><span style="color: #0000c0;">and</span><span style="color: #303030;">(</span>filter<span style="color: #303030;">);</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">isName</span><span style="color: #303030;">(</span>String name<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">if</span> <span style="color: #303030;">(</span>name <span style="color: #303030;">==</span> <span style="color: green; font-weight: bold;">null</span><span style="color: #303030;">)</span> <span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">;</span>
addFilter<span style="color: #303030;">(</span>BookSpecifications<span style="color: #303030;">.</span><span style="color: #0000c0;">isName</span><span style="color: #303030;">(</span>name<span style="color: #303030;">));</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: green; font-weight: bold;">public</span> Query <span style="color: #0060b0; font-weight: bold;">hasAuthor</span><span style="color: #303030;">(</span>String author<span style="color: #303030;">)</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">if</span> <span style="color: #303030;">(</span>author <span style="color: #303030;">==</span> <span style="color: green; font-weight: bold;">null</span><span style="color: #303030;">)</span> <span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">;</span>
addFilter<span style="color: #303030;">(</span>BookSpecifications<span style="color: #303030;">.</span><span style="color: #0000c0;">hasAuthor</span><span style="color: #303030;">(</span>author<span style="color: #303030;">));</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">;</span>
<span style="color: #303030;">}</span>
<span style="color: grey;">// other criterias ...</span>
<span style="color: green; font-weight: bold;">public</span> List<span style="color: #303030;"><</span>Book<span style="color: #303030;">></span> find<span style="color: #303030;">()</span> <span style="color: #303030;">{</span>
<span style="color: green; font-weight: bold;">return</span> <span style="color: green; font-weight: bold;">this</span><span style="color: #303030;">.</span><span style="color: #0000c0;">bookRepository</span><span style="color: #303030;">.</span><span style="color: #0000c0;">findAll</span><span style="color: #303030;">(</span>filters<span style="color: #303030;">);</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
<span style="color: #303030;">}</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
As you can see i am just joining filter <a href="http://www.objectdb.com/java/jpa/query/criteria">Criterias</a> together, and thats it. The implementation is really simple but also expandable. These filter Criterias are supported by my BookRepository (=<a href="http://de.wikipedia.org/wiki/Data_Access_Object">DAO</a>). I just have to define them in a helper class first. Check out <a href="http://blog.springsource.org/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/">this</a> and <a href="http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-four-jpa-criteria-queries/">that</a> for a deeper understanding how to combine spring-data with criteria queries.<br />
<br />
<br />
<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0tag:blogger.com,1999:blog-1178805312154210159.post-1463464528104184872013-03-02T12:10:00.001+01:002013-10-24T15:21:16.411+02:00Selenium Test Automation with MavenToday 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.<br />
<br />
<h3>
Precondition</h3>
<ul>
<li>I want plain HTML TestCases, created with Selenium-IDE. So that someone with little Programming skills can still create them.</li>
<li>I want these GUI Tests to be run automatically in my Build process, so my CI-Tool can notify me on errors.</li>
<li>I also want all TestCases under Versioncontrol in my Projects Repository since the Tests grow with the Source.</li>
<li>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.</li>
</ul>
<h3>
Solution</h3>
First of all i create a Folder in my Project for the Selenium-Tests.<br />
<br />
<b>Folder Structure </b><br />
<ol>
<li>
<label for="src">src</label>
<input checked="checked" id="src" type="checkbox" />
<ol>
<li>
<label for="main">main</label>
<input id="main" type="checkbox" />
</li>
<li>
<label for="test">test</label>
<input checked="checked" id="test" type="checkbox" />
<ol>
<li><label for="java">java</label>
<input checked="checked" id="java" type="checkbox" />
</li>
<li>
<label for="selenium">selenium</label>
<input checked="checked" id="selenium" type="checkbox" />
<ol>
<li class="file">TestSuite</li>
<li class="file">SomeTest1</li>
<li class="file">SomeTest2</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li class="file">pom.xml</li>
</ol>
<h3>
Example TestSuite</h3>
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #507090;"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color: #507090;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"></span>
<span style="color: #007000;"><html</span> <span style="color: #0000c0;">xmlns=</span><span style="background-color: #fff0f0;">"http://www.w3.org/1999/xhtml"</span> <span style="color: #0000c0;">xml:lang=</span><span style="background-color: #fff0f0;">"en"</span> <span style="color: #0000c0;">lang=</span><span style="background-color: #fff0f0;">"en"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><head></span>
<span style="color: #007000;"><meta</span> <span style="color: #0000c0;">content=</span><span style="background-color: #fff0f0;">"text/html; charset=UTF-8"</span> <span style="color: #0000c0;">http-equiv=</span><span style="background-color: #fff0f0;">"content-type"</span><span style="color: #007000;">/></span>
<span style="color: #007000;"><title></span>Test Suite<span style="color: #007000;"></title></span>
<span style="color: #007000;"></head></span>
<span style="color: #007000;"><body></span>
<span style="color: #007000;"><table</span> <span style="color: #0000c0;">id=</span><span style="background-color: #fff0f0;">"suiteTable"</span> <span style="color: #0000c0;">cellpadding=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">cellspacing=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">border=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">class=</span><span style="background-color: #fff0f0;">"selenium"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><tbody></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td><b></span>Test Suite<span style="color: #007000;"></b></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td><a</span> <span style="color: #0000c0;">href=</span><span style="background-color: #fff0f0;">"./SomeTest1.html"</span><span style="color: #007000;">></span>SomeTest1<span style="color: #007000;"></a></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td><a</span> <span style="color: #0000c0;">href=</span><span style="background-color: #fff0f0;">"./SomeTest2.html"</span><span style="color: #007000;">></span>SomeTest2<span style="color: #007000;"></a></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"></tbody></span>
<span style="color: #007000;"></table></span>
<span style="color: #007000;"></body></span>
<span style="color: #007000;"></html></span>
</pre>
</td></tr>
</tbody></table>
</div>
<h3>
</h3>
<h3>
Example Test</h3>
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 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</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #507090;"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color: #507090;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"></span>
<span style="color: #007000;"><html</span> <span style="color: #0000c0;">xmlns=</span><span style="background-color: #fff0f0;">"http://www.w3.org/1999/xhtml"</span> <span style="color: #0000c0;">xml:lang=</span><span style="background-color: #fff0f0;">"en"</span> <span style="color: #0000c0;">lang=</span><span style="background-color: #fff0f0;">"en"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><head</span> <span style="color: #0000c0;">profile=</span><span style="background-color: #fff0f0;">"http://selenium-ide.openqa.org/profiles/test-case"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><meta</span> <span style="color: #0000c0;">http-equiv=</span><span style="background-color: #fff0f0;">"Content-Type"</span> <span style="color: #0000c0;">content=</span><span style="background-color: #fff0f0;">"text/html; charset=UTF-8"</span><span style="color: #007000;">/></span>
<span style="color: #007000;"><link</span> <span style="color: #0000c0;">rel=</span><span style="background-color: #fff0f0;">"selenium.base"</span> <span style="color: #0000c0;">href=</span><span style="background-color: #fff0f0;">""</span><span style="color: #007000;">/></span>
<span style="color: #007000;"><title></span>SomeTest1.html<span style="color: #007000;"></title></span>
<span style="color: #007000;"></head></span>
<span style="color: #007000;"><body></span>
<span style="color: #007000;"><table</span> <span style="color: #0000c0;">cellpadding=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">cellspacing=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">border=</span><span style="background-color: #fff0f0;">"1"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><thead></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td</span> <span style="color: #0000c0;">rowspan=</span><span style="background-color: #fff0f0;">"1"</span> <span style="color: #0000c0;">colspan=</span><span style="background-color: #fff0f0;">"3"</span><span style="color: #007000;">></span>SomeTest1<span style="color: #007000;"></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"></thead></span>
<span style="color: #007000;"><tbody></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td></span>open<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></span>/<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td></span>waitForElementPresent<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></span>//div[@id='someId']<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td></span>click<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></span>css=button.create<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: grey;"><!-- Some Steps --></span>
<span style="color: #007000;"><tr></span>
<span style="color: #007000;"><td></span>assertText<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></span>
//div[@id='someId']
<span style="color: #007000;"></td></span>
<span style="color: #007000;"><td></span>${expectedText}<span style="color: #007000;"></td></span>
<span style="color: #007000;"></tr></span>
<span style="color: #007000;"></tbody></span>
<span style="color: #007000;"></table></span>
<span style="color: #007000;"></body></span>
<span style="color: #007000;"></html></span>
</pre>
</td></tr>
</tbody></table>
</div>
<h3>
</h3>
<h3>
Setup WebServer</h3>
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 <i>integration-test</i> Phase. If you want to learn more about the Maven Build Life-cycle and its phases check out <a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html">this</a>. So we need some kind of WebServer to run our WebApp, otherwise the tests wont work. The WebServer should be started before the <i>integration-test</i> phase, and be stopped afterwards. We could Use <a href="http://tomcat.apache.org/maven-plugin.html">Tomcat7</a> or <a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin">Jetty</a> for example. In this example i will use the tomcat7-maven-plugin. I configure my pom.xml to start Tomcat7 <i>pre-integration-test</i>.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 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</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><plugin></span>
<span style="color: #007000;"><groupId></span>org.apache.tomcat.maven<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>tomcat7-maven-plugin<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>2.0<span style="color: #007000;"></version></span>
<span style="color: #007000;"><executions></span>
<span style="color: #007000;"><execution></span>
<span style="color: #007000;"><id></span>tomcat-run<span style="color: #007000;"></id></span>
<span style="color: #007000;"><goals></span>
<span style="color: #007000;"><goal></span>run-war-only<span style="color: #007000;"></goal></span>
<span style="color: #007000;"></goals></span>
<span style="color: #007000;"><phase></span>pre-integration-test<span style="color: #007000;"></phase></span>
<span style="color: #007000;"><configuration></span>
<span style="color: #007000;"><port></span>8080<span style="color: #007000;"></port></span>
<span style="color: #007000;"><fork></span>true<span style="color: #007000;"></fork></span>
<span style="color: #007000;"></configuration></span>
<span style="color: #007000;"></execution></span>
<span style="color: #007000;"><execution></span>
<span style="color: #007000;"><id></span>tomcat-shutdown<span style="color: #007000;"></id></span>
<span style="color: #007000;"><goals></span>
<span style="color: #007000;"><goal></span>shutdown<span style="color: #007000;"></goal></span>
<span style="color: #007000;"></goals></span>
<span style="color: #007000;"><phase></span>post-integration-test<span style="color: #007000;"></phase></span>
<span style="color: #007000;"></execution></span>
<span style="color: #007000;"></executions></span>
<span style="color: #007000;"></plugin></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
If you are running multiple Projects on a CI-Server you might consider using a different Port-Number for each Project.<br />
<br />
<h3>
Finally: Run the Tests </h3>
Last but not least we need to run the tests. Luckily there is this <a href="http://selenium-maven-plugin/">selenium-maven-plugin</a> available that does the job.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #007000;"><plugin></span>
<span style="color: #007000;"><groupId></span>org.codehaus.mojo<span style="color: #007000;"></groupId></span>
<span style="color: #007000;"><artifactId></span>selenium-maven-plugin<span style="color: #007000;"></artifactId></span>
<span style="color: #007000;"><version></span>2.3<span style="color: #007000;"></version></span>
<span style="color: #007000;"><configuration></span>
<span style="color: #007000;"><browser></span>*firefox<span style="color: #007000;"></browser></span>
<span style="color: #007000;"><suite></span>src/test/selenium/TestSuite.html<span style="color: #007000;"></suite></span>
<span style="color: #007000;"><startURL></span>http://localhost:8080<span style="color: #007000;"></startURL></span>
<span style="color: #007000;"></configuration></span>
<span style="color: #007000;"><executions></span>
<span style="color: #007000;"><execution></span>
<span style="color: #007000;"><id></span>run-selenium-tests<span style="color: #007000;"></id></span>
<span style="color: #007000;"><phase></span>integration-test<span style="color: #007000;"></phase></span>
<span style="color: #007000;"><goals></span>
<span style="color: #007000;"><goal></span>selenese<span style="color: #007000;"></goal></span>
<span style="color: #007000;"></goals></span>
<span style="color: #007000;"></execution></span>
<span style="color: #007000;"></executions></span>
<span style="color: #007000;"></plugin></span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
Now, whenever we execute <u>mvn clean verify</u> or even <u>mvn clean install</u> in console, the Tests are run and reports are stored within the target directory. This will also be done by your CI-Tool.<br />
<br />
<h3>
Conclusion</h3>
We do have a complete and clean Setup.<br />
<ul>
<li>We have a place to store our Tests, </li>
<li>They are within the Sourcecode and Version control</li>
<li>They can be run automatically by CI-Tools</li>
<li>Even Non-developers can add new TestCases</li>
</ul>
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.<br />
I hope you enjoyed this Guide. Greetings.<br />
<br />Gregorhttp://www.blogger.com/profile/05434420957734303019noreply@blogger.com0