<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>www.jillesvangurp.com</title>
	<atom:link href="http://www.jillesvangurp.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jillesvangurp.com</link>
	<description>Yet another blog</description>
	<lastBuildDate>Thu, 19 Apr 2012 18:43:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Lumia 800</title>
		<link>http://www.jillesvangurp.com/2012/03/29/lumia-800/</link>
		<comments>http://www.jillesvangurp.com/2012/03/29/lumia-800/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 21:29:03 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=954</guid>
		<description><![CDATA[I got my Lumia 800 a few weeks before Christmas. Since then, I&#8217;ve used it on a daily basis. I just realized I never actually got around to doing a review. Since I work for Nokia, it is always a &#8230; <a href="http://www.jillesvangurp.com/2012/03/29/lumia-800/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I got my Lumia 800 a few weeks before Christmas. Since then, I&#8217;ve used it on a daily basis. I just realized I never actually got around to doing a review. Since I work for Nokia, it is always a bit awkward doing reviews since I can&#8217;t basically do a negative review without upsetting some of my peers in Nokia. So, disclaimer: I work for Nokia, any opinions you read here are my own and do not necessarily represent any official Nokia position.</p>
<p>My general solution to this problem has been to simply not do a review of any Nokia product unless I actually like it and won&#8217;t have to lie to you. So yes, I&#8217;m biased and definitely not objective but at the same time I don&#8217;t work for marketing, and definitely would feel bad about propagating lies.</p>
<p>I had no problems doing an N900 review a while back or reviewing the N8. So, now it is the Lumia 800&#8242;s turn. The good news is, I like this phone. In fact, like it so much I&#8217;d recommend this phone and its little brother the 710 to anyone, including close friends and family whom I definitely would not want to burden with a bad product. To be clear, I don&#8217;t take this type of recommendation lightly because if I&#8217;m wrong, I basically have to deal with the consequences of people complaining about embarrassing short comings, etc.</p>
<p><span id="more-954"></span>Much has been said in the press already about the Lumia line of phones. The general mood seems to be that reviewers like the phone but with some reservations. Some of the criticism that is repeated a lot by different reviewers are mostly non issues in my view. I&#8217;ll try to cover the essentials here and try to counter some of the criticism or at least put it in perspective:</p>
<ol>
<li>The <strong>windows phone market place</strong> is far smaller than the iphone and android stores. This is a big one, almost every review repeats it. It&#8217;s the single most important argument against windows phone in general and the Lumia in particular. And it is true, the long tail of useless fart applications, rss feeds for obscure websites, pointless applications, etc. is a lot shorter in the market place. But guess what, almost nobody installs those anyway. What matters are the handful of important applications that are actually popular. And while there are some things missing, most of the important functionality seems to be covered in the market place and there seem to be lots of developers filling in the gaps quickly. Additionally, the phone actually has a lot of well integrated support for social networks that removes a lot of the need for third party apps. So, even though facebook and twitter apps exist, I actually don&#8217;t really use them because the people hub handles things just fine for me and I can upload photos straight from the photo application. Having apps is nice. Not needing them because the phone does it out of the box is better. Finally, the mobile browser is pretty decent and allows you to run a lot of mobile web sites just fine: why have an app if a bookmark can do the job? Also, you can pin websites to the home screen. I&#8217;ve got Google News and Google Reader for touch screen phones there (google.com/reader/i). The boundary between app and web app is pretty blurry on this phone. In any case, I have about 50 apps and games installed on this phone, several of which I use regularly. See below for a list of my favorites.</li>
<li><strong>Battery life</strong> is not great. This is partially due to the small capacity of the battery but also due to a range of software issues that are being patched. Just today I installed an update that seems to be extending battery life for me quite a bit. Normally my phone would need charging somewhere during the night and would be well below 30-40% in the evening (i.e. now). Current battery level is 70%. Even before this patch, I&#8217;ve rarely run out of power. I charge at night normally and this provides me enough juice to last me a day of admittedly generally not so heavy usage.</li>
<li><strong>Multi tasking</strong> is limited. This is true, but it helps keeping the phone alive. The important things do work in the background though: I can play music or online radio in the background; email and social networks update themselves and if you are like the constant distraction of being IMed from various IM networks, that works fine as well. Apple does this as well: full blown multi tasking is actually not a great idea on a mobile phone with limited CPU and RAM. Android has unrestricted multi tasking and a whole lot of battery and performance issues that I don&#8217;t think are worth the trouble.</li>
<li>The <strong>hardware</strong> is limited. I would say, windows phone performs great on modest hardware. The phone has a single core, 1.4 Ghz CPU with 512MB of RAM. Especially the ram size is very modest. The CPU is actually plenty fast and since there is little need for multi tasking, why bother with a second CPU core? Technicalities aside, this phone is lag free, blazing fast and responsive, all the time. I&#8217;ve not seen this phone freeze or lag in the three months I&#8217;ve been using it. I think few Android phone owners can claim that and even Apple&#8217;s iphone has had its fair share of issues.</li>
<li>The <strong>lid on the top</strong> that covers the usb port is fragile. This is true but the way it is designed this is only an issue if it is open. Most of the time it will be closed when you are handling the phone and while it opens easily it never does so accidentally. Which is the reason that most Lumia 800&#8242;s I&#8217;ve seen at work (and there is a pretty large number of them) are undamaged in that respect. I&#8217;ve seen exactly one phone where it broke off so far.</li>
</ol>
<p>So, now on to the rest of this review which is mainly about outlining why I like this phone so much.</p>
<p>First of all, world + dog seems to agree this is a really nicely designed phone. No argument there. It is a nicely sized phone that fits in my pocket and doesn&#8217;t make me look like I&#8217;m happy to see everyone. Also it gets along with the key ring that I keep in that pocket just fine. So far I have not managed to scratch or damage this phone in any significant way, which is impressive. You should see some of my other phones, not pretty.</p>
<p>The screen is great. It&#8217;s a nice Oled screen with very good contrast and blacks that are virtually indistinguishable from the phone cover, which is also black. Nice crisp colors too and usable in the desert and on the beach as I found out in Australia recently. It&#8217;s great for viewing photos and watching movies.</p>
<p>Speaking of photos and movies, shooting those delivers very nice results with the 5mp camera. With 720p you get a pretty nice quality and the sound is pretty decent too. This is a very decent camera phone.</p>
<p>But the real reason I like this phone is the software. Prior to windows phone I did not believe that windows on a phone would be any good. I stand corrected. It works really well and Microsoft did not just level the playing field here, they raised the bar for everyone else. It&#8217;s that good: expect to see a lot of imitation from other vendors in the next year or so.</p>
<p>The metro UI is very nice to use and basically obsoletes the notion of having screens full of static icons. Instead, metro is centered around tiles. Tiles basically act like a combination of widgets and icons. Tapping one opens an application. Tiles update themselves with useful information (like the weather, a photo somebody posted, etc.) so they are useful even if you don&#8217;t tap them. For example I have separate tiles for messaging, calendar, and various mail accounts that allow me to see whether I need to tap them with a quick glance at the screen. All tiles are the same size and this makes navigating them easy. Instead of having multiple screens, there is just one endless screen that you can flick up and down as you please. You can long tap to drag and drop tiles to rearrange things and I basically have all the important ones listed at the top and the ones I care less about at the bottom where they are still only a quick flick with my finger away. Clearly a lot of consideration and design went into this UI and it works really well for me.</p>
<p>What is especially nice is the level of integration between applications. Few reviews highlight this enough but the people hub is a really nice piece of software that completely revolutionizes what used to be a boring phone book full of faceless people and phone numbers. I can tweet from it, I can read other people&#8217;s updates, view photos from several networks, see a contact details that are enriched with stuff from several profiles on twitter, linkedin, facebook, gmail, outlook, hotmail, and more. Also, it&#8217;s smart enough to identify duplicates and suggesting contacts that could be merged. Few other phones get this right. Additionally, you can group people and have tiles for those groups both for quick access but also as a way of filtering their status updates. For example, I have a friends and a family tile on my home screen, in addition to the main people hub tile.</p>
<p>There is a special me tile that allows you to review your own contributions and do status updates. The same accounts I have in the people hub are also available for photo sharing in the photo application. You can share a photo right after taking it or from the album.</p>
<p>The other thing that surprised me in a positive way is the browser, which is a mobile version of internet explorer 9. I&#8217;ve been a long time firefox user and have basically hated internet explorer on the desktop with a passion for years, version 9 included. However, on mobile it works surprisingly well. Version 9 brought support for a meaningful enough subset of html 5 that most sites are usable. Sites load relatively quick compared to other browsers and zooming and navigating pages works fine as well. Compared to mobile versions of firefox on the N900 and the symbian webkit based browser as well as opera for symbian, this is a really nice browser that offers both the performance and usability needed to be useful.</p>
<p>Some apps that I like and use include:</p>
<ul>
<li>Nokia Transport, Nokia Maps, Nokia Drive. All made by my colleagues here in Berlin and powered by my own work on the back end software. But still, these are fine applications that are useful now in their first version for WP 7 and are going to get even better very soon as we deliver more of the feature work.</li>
<li>Nokia Creative Studio. A very decent photo editing application that was released recently. Pretty neat and the live view is a great way to take photos.</li>
<li>Kindle for windows phone is great. I also have a normal kindle and the two sync nicely via whispersync.</li>
<li>I have two weather applications: AccuWeather and a Microsoft &#8220;Weather&#8221; application. Both are location aware and have live tiles and do a decent job of telling you the weather now and in the near future.</li>
<li>The youtube mobile website works really well. I can basically view my subscriptions and movies play back very nicely full screen on the fantastic screen.</li>
<li>Tunein Radio offers an extensive selection of most relevant radio channels world wide.</li>
<li>IMDB has a nice application that is location aware and updates with news and reviews for movies that are playing nearby as well as the schedules for those movies.</li>
<li>Foursquare has a pretty decent application with live tiles.</li>
<li>Connectivity short cuts gives you tiles for quick access to bluetooth, wifi, and cellular, and airplane settings.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2012/03/29/lumia-800/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Scrum: Agile madness</title>
		<link>http://www.jillesvangurp.com/2011/12/03/scrum-agile-madness/</link>
		<comments>http://www.jillesvangurp.com/2011/12/03/scrum-agile-madness/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 13:37:16 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=938</guid>
		<description><![CDATA[Like most in our industry I&#8217;ve been exposed to agile, scrum and related hypes over the past decade. Unlike most in our industry, I have a little bit of background in software engineering research as well. During my Ph. D., &#8230; <a href="http://www.jillesvangurp.com/2011/12/03/scrum-agile-madness/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Like most in our industry I&#8217;ve been exposed to agile, scrum and related hypes over the past decade. Unlike most in our industry, I have a little bit of background in software engineering research as well. During my Ph. D., which was in the early days of agile when Kent Beck published his book on extreme programming and I was writing my thesis on software architecture, I had the privilege of seeing a lot of different companies from the inside and talked to tech leads, architects and other leaders across a nice range of companies doing software product development. Ultimately after wrapping up my thesis, I decided that I lacked the experience to speak authoritatively on the subject of software development and moved over to the software industry to get some experience.</p>
<p><span id="more-938"></span></p>
<p>In recent years I&#8217;ve observed people making outrageous claims about the supposed benefits of things like scrum or kanban while in fact they were actively making things less agile. I&#8217;ve experienced first hand some botched roll outs of scrum. And the software engineering researcher inside of me has been itching for a while to write up my perspective on the whole thing. So, here it goes.</p>
<p>The word <a href="http://www.merriam-webster.com/dictionary/agile">agile</a> itself is a bit of a misnomer in the context of software development. It intends to communicate a intent to deliver software fast and efficiently. This requires that people do things in a systematic and appropriate way. That&#8217;s where the madness begins because most people will equate this to a dogmatic application of whatever software development methodology they favor. Dogmatic is in my book a synonym for stupid: you switch off your brain and blindly do whatever the dogma dictates. This is what is going on with agile software development. People go to conferences, hear opinions and sales pitches and accept them as fact. Then they go back to work and do a lot of damage.</p>
<p>If you read up on agile methodologies, you will find that their lead proponents (e.g. Kent Beck, Martin Fowler, Alistair Cockburn, etc.) are generally a bit more pragmatic and rather anti dogmatic than their followers and fan boys. The same goes for the proponents of scrum, including Ken Schwaber. I have great respect for these people and the fine work they have done moving the field forward.</p>
<p>These people are successful veteran software developers or project managers with a lot of successful projects behind them. That in my view is the main problem here: you can&#8217;t substitute experience with process and that is exactly what agile followers end up doing. Take away the experienced people and you have a lot of people executing the rituals of scrum, kanban, or whatever without really understanding what they are doing. The assumption that that will work at all is naive at best and actually rather delusional. In this article, I&#8217;ll focus mostly on scrum because that is the dominant agile methodology currently and I&#8217;ve had some first hand experience with it in my current job.</p>
<p>A good software organization will have key people that keep things together technically and organizationally and a larger group of people with various skills and qualities that do stuff that they&#8217;ve been told to do but are not necessarily capable of doing this unsupervised. With a good mix of those people working together, you can achieve great things fast. A bad scrum implementation will empower the latter group while taking power away from the former group. I say bad scrum implementation because in theory there are good implementations as well. It&#8217;s just I haven&#8217;t seen too many of those (i.e. none) and way too many bad ones. I believe this has a lot to do with the fact that often scrum is introduced to fix what is already a dysfunctional organization.</p>
<p>In the scrum world you have a product owner representing the business side who negotiates with the software development team about features and a self organized team delivering &#8216;business value&#8217; as fast as they can with a scrum master that acts as a facilitator. In this happy utopia everybody is happy and productive. This works well under the following assumptions:</p>
<ol>
<li>The product owner has a firm grasp on domain and the technology.</li>
<li>The team can self organize and there is a balance between team empowerment and product owner power.</li>
<li>Everybody involved understands what they are supposed to do in their scrum role</li>
<li>The amount of work is small enough to be handled by one team</li>
</ol>
<p>Actually, if all of the above is true, you will have little need for process. If that isn&#8217;t the case, no amount of process is going to fix things magically. In my experience, all of these assumptions are generally broken in scrum organizations. The reality is that product owners are rather well aligned with management and whatever they say ends up being an executive order. It&#8217;s elementary corporate picking order. Additionally, big organizations have many teams and consequently many product owners. Scrum in combination with a full blown corporate rat race like that is going to have some very obvious consequences. Including management not agreeing amongst themselves what needs to be done and fighting over the heads of individual teams about features, products, vision and direction. Ultimately this results in mediocre products and failure in the market.</p>
<p>Teams self organize to do whatever the hell they are told to do by the product owners, who with the best intentions are probably demanding the wrong things to be built on unrealistically short notice due to a fundamental lack of a grasp on either the domain, the technology, and the basics of software project management. The scrum masters basically get the shitty job of keeping it together and getting the teams to &#8216;democratically&#8217; agree on stuff while not actually having any decision power to make them do the right thing. Generally the scrum master should be one of the more senior team members that would in a traditional organization have been either a project manager (with full power) or a tech lead/architect with decision powers.</p>
<p>I&#8217;ve seen some spectacularly mediocre software delivered this way. It&#8217;s not pretty. The problem is usually a lack of experience that gets amplified by the process. A two day pep talk about scrum is apparently all the training you need to become a product manager or scrum master. I know because I&#8217;m a certified scrum master (not practicing it though) and I know how hollow that phrase is.I congratulate Ken Schwaber on his well oiled business of scrum training large parts of the industry (me included) but I believe that he doesn&#8217;t honestly believe a two day training is enough either.</p>
<p>The role of product owner is generally a first step up the corporate ladder. In other words, there are a lot of inexperienced people who get promoted to be a product owner or worse start their first or second job being one. Likewise, the scrum master role is not considered a job very high on the corporate ladder either. Think developers with a few years of experience who suddenly find themselves moving post its around on walls rather than doing the stuff they were trained to do (i.e. software development). How can you expect inexperienced people like this to succeed?</p>
<p>Well you can&#8217;t and that is why scrum isn&#8217;t working. You can&#8217;t fix a dysfunctional software organization by rolling out scrum and mass promoting people to be product managers or scrum masters. It doesn&#8217;t work this way but yet this is exactly what happens when big companies change process. It works as follows: you spend a gazillion of dollars on training and consultancy to force the organization in a particular direction. Naturally, you want results fast so you cut some corners. And before you know it the walls of your offices are plastered with colorful post-its and the meeting rooms are full of busy looking people doing retrospectives, sprint plannings, estimation sessions, etc. Reports on velocity and story points get exchanged and proud product owners brag about their products. It&#8217;s no wonder executives love scrum: they get the illusion of progress.</p>
<p>The problem is that all you have at this point is a lot of people going through the moves of a process without actually delivering any coherent results whatsoever. Getting one team to deliver something is relatively easy. Getting 50 teams to deliver something coherent together is a different matter. The natural reflex in big organizations is to organize hierarchically and in a scrum context this means that product managers report to super product managers who report to department managers who report to VPs who report to the CEO who wants results yesterday. So when problems happen, they are escalated up and translated into executive orders that travel down. When it comes to solving technical problems, having a lot of non technical people involved doesn&#8217;t necessarily make things easier. So, the organization becomes a bottleneck for doing things the right way. Technical issues are solved relatively easy if you stick the engineers involved in one room. But that doesn&#8217;t happen if you add layers of management with conflicting interests that need to approve, be involved, escalate, etc. Even getting them to understand the problem is hard.</p>
<p>Another problem is that teams have dependencies. Team A needs the stuff of team B who needs the stuff of team C, etc. Any good software architect knows how to manage dependencies between components. But your average scrum product owner is not an architect. So, you get organizational complexity (think circular dependencies between teams) and organization driven architecture where teams raise fences (APIs, separate deployment processes, etc.) to shield them from neighboring teams. To make things worse, scrum is all about leaving teams alone during their sprints so you have a lot of teams delivering stuff every sprint and throwing it over the fence to other teams at the end. Orchestrating the development of a few dozen scrum teams is a hard problem and I&#8217;m pretty sure very few organizations have actually solved this problem. Meanwhile all the scrum training seems to be geared towards teams operating in isolation.</p>
<p>Is there a happy ending here? Sure, eventually inexperienced people become experienced people. Experienced people tend to do things that they know have worked for them in the past and challenge things that they know to be flawed. This includes taking control, leading and doing things in a way they believe will deliver results rather than in a way that somebody else claims will deliver results. The fallacy of scrum and agile is that initially you have a lot of people in the latter group and very few in the former.</p>
<p>Over the past seven years, I&#8217;ve seen scrum penetrate the minds of senior executives who then pushed for corporate wide rollout of this great new process (a well known anti pattern for scrum that Ken Schwaber warns for in his courses) that would magically fix things. Lots of product owners and scrum masters were hired/trained/promoted and then the obvious things started happening: large amounts of teams delivering the wrong software too late and not aligning and synchronizing with each other at all.</p>
<p>But then other things started to happen. We got some veteran, experienced software developers in some key positions in the company. They started fixing things; they started removing bureaucratic obstacles, dealing with the technical debt, and they started emphasizing good practices such as accountability, technical skill, and favoring pragmatism over dogmatism. I would say by this point, scrum is definitely on the way out. We still have floors where the walls are still plastered in post its. But we also have other floors where the walls are now empty but are still bearing the traces of what used to be scrum boards and where engineers work on delivering great software without too much interference from random management. That&#8217;s fine. Choosing and tuning the way in which you work is more important than having everybody mindlessly follow the same process.</p>
<p>The story of Nokia (where I work), which is often cited as an early adopter of scrum, has been well publicized and clearly, we&#8217;ve had a huge software problem over the past years. After a few bad years, Nokia is now delivering good, solid products again. The recent product announcements like the Lumia phones and Nokia Drive are good examples of a software development organization delivering results fast (i.e. truly agile). Few people appreciate how little time has actually passed between the initial announcements early this year and us delivering the goods this summer. Getting any organization this large too deliver that fast is kind of impressive. I&#8217;m afraid I wouldn&#8217;t give scrum much credit for it.</p>
<p>In the end what matters is having a good mix of people with experience, skills and vision. Inexperienced people learn quick in such an environment and good people get rewarded for good work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/12/03/scrum-agile-madness/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Git and feature branches effectively</title>
		<link>http://www.jillesvangurp.com/2011/07/16/using-git-and-feature-branches-effectively/</link>
		<comments>http://www.jillesvangurp.com/2011/07/16/using-git-and-feature-branches-effectively/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 10:19:49 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=927</guid>
		<description><![CDATA[There is a bit of a debate raging in the last few weeks that started when somebody commented on a few things that Martin Fowler wrote about git and using feature branches and feature toggles. Martin Fowler makes a few &#8230; <a href="http://www.jillesvangurp.com/2011/07/16/using-git-and-feature-branches-effectively/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There is a bit of a <a href="http://sarahtaraporewalla.com/design/experience-report-branch-by-feature/">debate</a> raging in the last few weeks that started when somebody commented on a few things that Martin Fowler wrote about git and using <a href="http://martinfowler.com/bliki/FeatureBranch.html">feature branches</a> and <a href="http://martinfowler.com/bliki/FeatureToggle.html">feature toggles</a>. Martin Fowler makes a few very good points about how feature branches can cause a lot of testing and integration headaches and lot of people seemed to have picked up on this one and there seems to be a bit of an anti-feature branch movement emerging. </p>
<p>The main problem I have with this is that these people are confusing problems and causes here and effectively blaming a solution they have for causing a problem they have. Roughly the argument goes as follows: feature branches cause people to accumulate change that then becomes very disruptive when it lands on the main branch. There will be CI breakage and lots of problems for people on other feature branches that are suddenly faced with merge issues. I think Martin Fowler actually gets it but some of his followers seem to be confused. By all means, feature toggles are a great way to get changes in early and have them exposed. It&#8217;s a powerful tool that you can use to get changes out earlier. Early is good: use it. However, it is not the case that if you use feature branches there has to be a lot of pain for everybody. In other words, feature branches are not inherently evil and don&#8217;t have to be problematic.</p>
<p>It’s not the practice of feature branching that is the problem but the fact that testing and continuous integration are not decentralized in a lot of organizations. In other words until your changes land on the central branch, you are not doing the due diligence of testing. Even worse, you are not making sure you have tested your changes before you add them to the main branch.</p>
<p>You can’t do decentralized versioning unless you also decentralize your testing and integration. Git has value when used as a SVN replacement. Git has more value when used as a DVCS. There is no good reason why you can’t do decentralized testing and integration with git. Rather the opposite: it has been designed with exactly this in mind. The whole point of git is divide and conquer. Break the changes up: decentralize the testing and integration work and solve the vast majority of problems before change is pushed upstream. If you push your problems along with your changes you are doing it wrong. Decentralized integration is a very clever strategy that is based on the notion that the effort involved with testing and integration scales exponentially rather than linearly with the amount of change. By decentralizing you have many people working on smaller sets of changes that are much easier to deal with: the collaborative effort on testing decreases and when it all comes together you have a much smaller set of problems to deal with. </p>
<p>This is how the linux kernel manages to remain stable, despite the fact that the amount of change there is measured in thousands of LOC/day. If you need proof that thousands of people can work collaboratively on millions of lines of code using git branches: look at the linux kernel. The amount of change, integration and testing effort, etc. in whatever you are working on probably pales in comparison with that: your problems are easy.</p>
<p>Here’s a few simple practices that will address most of the issues:</p>
<ol>
<li>No change that will break CI on the main branch is allowed on the main branch. Zero tolerance on this one. In git terms: rebase against main, run ci test on the feature branch, fix any problems, push. You can automate this even: jenkins pretty much supports this out of the box. If main breaks ever, somebody doesn’t get the basics: educate them with a big clue bat. Rationale, it is vital to keep main stable at all times. That way everybody on a feature branch will know it is safe to rebase.</li>
<li>Rebase against main frequently, especially if you do big changes. Rationale: you are doing the changes, it is you that will take the pain of doing the integration work when things go wrong, not everybody else. The earlier you know about problems, the easier it is to fix. Feature branches are not about stopping rebases. If your feature branch is way behind, you have done something very wrong. Don’t ever do that without good reason. If it is on the central branch, you will have to deal with it at some point: so get it over with ASAP.</li>
<li>Commit frequently, keep commits as small as you can. Rationale: smaller commits are easier to analyze and fix when you have conflicts. Also, Git is really good at applying commits one by one. If you isolate the merge problems to a handful of commits, rebasing is pretty much painless.</li>
<li>Push as early as you can. If the CI builds are green on your branch and you are confident things are fine, push and don’t wait. Don’t accumulate integration work for others. Feature branches are not about hiding change but about isolating change. There’s a difference. One is a communication problem and the other is a proven strategy of divide and conquer. If appropriate, feature toggles are indeed a great way to land experimental changes. I believe this was the main point Martin Fowler was trying to make.</li>
<li>Communicate clearly around big code restructurings. Rationale, everybody rebasing against your changes will experience some pain. You are causing people to have to do work, so tell them it is going to happen. I always ask people to push their changes before I push my big changes. That way, I can fix the integration issues on my side before I push.</li>
<li>Collaborate with people by pushing changes back and forth without involving the main branch. Git format-patch is your friend: you can do this by email. If somebody needs a change before you land it, you can give it to them.</li>
<li>Be aware of the cost of things. Any time people spend on things like resolving merge conflicts, doing rebases, etc. costs you. Inevitably when you branch you accept that there is going to be some cost. Keeping a branch alive means you add cost. Don&#8217;t do it needlessly. So, branch and do what you have to do and then rebase, push and delete the branch. And again, not committing is effectively the same as branching in git. It has the same cost and risk attached to it.</li>
<li>Don&#8217;t push branches to origin unless they are going to be long lived and need to be worked on by multiple people. For simple work, keep the branches local to your machine. If you are going to be doing all of the commits and integration work, the only valid reason for pushing it upstream would be backups. There are alternatives to backing this way.</li>
<li>Beyond a certain team size, the stable branch needs to be protected. Pull change rather than pushing it (this is a severely underused git feature). Junior on the third floor says his patch is ready: pull it, have a look at it and give him feedback but don&#8217;t allow him to push and bypass checks and balances. Push only works in small teams. Pull forces people to communicate.</li>
</ol>
<p>When will (feature) branches get you in trouble? Antipatterns:</p>
<ul>
<li>You are working on a big change. You haven&#8217;t updated for days. Do I need to spell it out? That is just wrong. Update!</li>
<li>You are pushing a big change, all the CI builds go red. Oops, test before you push you dumb idiot. You deserve all the angry looks you are going to get. If this happens a lot, consider setting up your CI environment for having a stable branch for tested commits and an unstable branch for incoming commits that need to be tested. Jenkins supports this and it will keep unstable change out of stable.</li>
<li>You are doing a big change, somebody else is also doing a big change. You find out about that when you rebase and spend hours dealing with merge conflicts. Seriously: communicate before you do anything drastic and give people an opportunity to get their changes in before you ruin their day. Pushing massive changes that you know are going to cause problems when people rebase is a very egocentric thing to do. Be a team player.</li>
<li>You are working on a big change. You haven&#8217;t updated or committed anything for several days on your local branch. You are effectively using your local branch as a feature branch: everybody who is not pushing change is effectively on a feature branch. Not committing is NOT a strategy to avoid using feature branches. Also, you are not committing? Why???? What&#8217;s your excuse for not committing to your own local branch? Seriously, consider using version management and stop treating git as a file server for code backups.</li>
<li>You are working on a branch for an extended period of time but your CI builds only run on the central branch. Congratulations, you have just tossed out CI as a good practice. Fix it. Either have the discipline to run the CI tests manually on every commit to the branch or set up a CI build for it. Either way, don&#8217;t break the feedback loop you get with CI.</li>
</ul>
<p>Now at this point I have to admit something: I don&#8217;t use feature branches a lot but I do tend to accumulate a few commits locally before I push them. Also. we haven&#8217;t set up stable and unstable branches in jenkins (yet, planning to). We have the occasional breakage of our CI builds. I&#8217;m actually guilty of breaking some of the builds myself. The reason/weak excuse is: I&#8217;m having a hard time changing people&#8217;s way of working. You turn your back and people stop committing and continue treating git like they are using cvs. But I&#8217;m at least aware what the real problem is here: not the fact that I have branches but the fact that our testing needs to be decentralized.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/07/16/using-git-and-feature-branches-effectively/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress 3.2 &amp; new theme</title>
		<link>http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/</link>
		<comments>http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 07:11:32 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=913</guid>
		<description><![CDATA[If you are a regular, you may have noticed that I switched theme. I was using the excellent fusion theme that I found on this site, which like the theme seems to be no longer maintained. So when I upgraded &#8230; <a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you are a regular, you may have noticed that I switched theme. I was using the excellent fusion theme that I found on <a href="http://digitalnature.ro/">this</a> site, which like the theme seems to be no longer maintained. So when I upgraded to wordpress 3.2 this morning, I noticed there is a new default theme in there that I kind of like.</p>
<p>The best feature is support for multiple header photos. So I&#8217;ve cropped and uploaded a few photos from my collection and the site will now randomly pick one of the photos listed below. So simple, but so nice to have. Otherwise the theme is pretty basic, which I think is appropriate for a blog. Also it does microformats (which was a major annoyance with the old theme). Finally, it just looks nice and it is likely to be maintained for a while (with it shipping with wordpress and all).</p>
<p><a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/wp_sunset_reykjavik-jpg/" rel="attachment wp-att-907"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/07/wp_sunset_reykjavik.jpg" alt="" title="wp_sunset_reykjavik.jpg" width="1000" height="288" class="aligncenter size-full wp-image-907" /></a></p>
<p><a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/wp_iceland_waterfall-jpg/" rel="attachment wp-att-908"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/07/wp_iceland_waterfall.jpg" alt="" title="wp_iceland_waterfall.jpg" width="1000" height="288" class="aligncenter size-full wp-image-908" /></a></p>
<p><a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/wp_lisbon_station-jpg/" rel="attachment wp-att-909"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/07/wp_lisbon_station.jpg" alt="" title="wp_lisbon_station.jpg" width="1000" height="288" class="aligncenter size-full wp-image-909" /></a></p>
<p><a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/wp_porto_bench-jpg/" rel="attachment wp-att-911"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/07/wp_porto_bench.jpg" alt="" title="wp_porto_bench.jpg" width="1000" height="288" class="aligncenter size-full wp-image-911" /></a></p>
<p><a href="http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/wp_galway-jpg/" rel="attachment wp-att-912"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/07/wp_galway.jpg" alt="" title="wp_galway.jpg" width="1000" height="288" class="aligncenter size-full wp-image-912" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/07/05/wordpress-3-2-new-theme/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Disqus</title>
		<link>http://www.jillesvangurp.com/2011/06/19/disqus/</link>
		<comments>http://www.jillesvangurp.com/2011/06/19/disqus/#comments</comments>
		<pubDate>Sun, 19 Jun 2011 10:02:14 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=897</guid>
		<description><![CDATA[After increased link spam activity (somebody found a way around the captcha) I decided to migrate the commenting system on this site to disqus.com. Along with (hopefully) a more spam resistant site, also come some cool features such as Facebook &#8230; <a href="http://www.jillesvangurp.com/2011/06/19/disqus/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After increased link spam activity (somebody found a way around the captcha) I decided to migrate the commenting system on this site to <a href="http://www.disqus.com">disqus.com</a>. Along with (hopefully) a more spam resistant site, also come some cool features such as Facebook and Twitter login and a few other things. Installation was surprisingly easy. Sign up, install plugin, configure, export comments, done. I should have done this ages ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/06/19/disqus/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jsonj: a new library for working with JSon in Java</title>
		<link>http://www.jillesvangurp.com/2011/05/31/jsonj/</link>
		<comments>http://www.jillesvangurp.com/2011/05/31/jsonj/#comments</comments>
		<pubDate>Mon, 30 May 2011 22:53:04 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=873</guid>
		<description><![CDATA[Update 11 July 2011: I&#8217;ve done several commits on github since announcing the project here. New features have been added; bugs have been fixed; you can find jsonj on maven central now as well; etc. In short, head over to &#8230; <a href="http://www.jillesvangurp.com/2011/05/31/jsonj/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update 11 July 2011</strong>: <em>I&#8217;ve done several commits on github since announcing the project here. New features have been added; bugs have been fixed; you can find jsonj on maven central now as well; etc. In short, head over to <a href=" https://github.com/jillesvangurp/jsonj">github</a> for the latest on this.</em></p>
<p>I&#8217;ve just uploaded a weekend project to github. So, here it is, <a href=" https://github.com/jillesvangurp/jsonj">jsonj</a>. Enjoy.</p>
<p>If you read my post on <a href="http://www.jillesvangurp.com/2011/04/02/on-java-json-and-complexity/">json</a> a few weeks ago, you may have guessed that I&#8217;m not entirely happy with the state of json in Java relative to other languages that come with native support for json. I can&#8217;t fix that entirely but I felt I could do a better job than most other frameworks I&#8217;ve been exposed to.</p>
<p>So, I sat down on Sunday and started pushing this idea of just taking the Collections framework and combining that with the design of the Json classes in GSon, which I use at work currently, and throwing in some useful ideas that I&#8217;ve applied at work. The result is a nice, compact little framework that does most of what I need it to do. I will probably add a few more features to it and expand some of the existing ones. I use some static methods at work that I can probably do in a much nicer way in this framework. </p>
<p><span id="more-873"></span></p>
<p>Here is some example usage (note, this will likely not stay in sync with the code in github, check there for latest version):</p>
<p><strong>Updated to version 0.3, check <a href="https://github.com/jillesvangurp/jsonj/blob/master/src/test/java/com/github/jsonj/ShowOffTheFramework.java">here</a> for latest version</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Copyright (c) 2011, Jilles van Gurp
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the &quot;Software&quot;), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */</span>
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">org.jsonj</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonBuilder</span>.<span style="color: #006633;">array</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonBuilder</span>.<span style="color: #006633;">nullValue</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonBuilder</span>.<span style="color: #006633;">object</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonBuilder</span>.<span style="color: #006633;">primitive</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonSerializer</span>.<span style="color: #006633;">serialize</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">jsonj</span>.<span style="color: #006633;">tools</span>.<span style="color: #006633;">JsonSerializer</span>.<span style="color: #006633;">write</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">testng</span>.<span style="color: #000000; font-weight: bold;">Assert</span>.<span style="color: #006633;">assertTrue</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.LinkedHashMap</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.LinkedList</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.jsonj.tools.JsonParser</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.testng.annotations.Test</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Not really a test but a nice place to show off some how to use this.
 */</span>
@Test
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ShowOffTheFramework <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** this could be a singleton or a spring injected object, threadsafe of course. */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> JsonParser jsonParser <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsonParser<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> whatCanThisBabyDo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
		JsonObject object <span style="color: #339933;">=</span> object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;its&quot;</span>, <span style="color: #0000ff;">&quot;just a hash map&quot;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;and&quot;</span>, array<span style="color: #009900;">&#40;</span>
				primitive<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;adding&quot;</span><span style="color: #009900;">&#41;</span>,
				primitive<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;stuff&quot;</span><span style="color: #009900;">&#41;</span>,
				object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;is&quot;</span>, <span style="color: #0000ff;">&quot;easy&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,
				array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;another array&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;numbers&quot;</span>, <span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;including_this_one&quot;</span>, <span style="color: #cc66cc;">42.0</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;booleanstoo&quot;</span>, <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;nulls_if_you_insist&quot;</span>, nullValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>, object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;b&quot;</span>, object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;c&quot;</span>, <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;d&quot;</span>, <span style="color: #cc66cc;">42</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;e&quot;</span>, <span style="color: #0000ff;">&quot;hi!&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;array&quot;</span>,
				array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1&quot;</span>, <span style="color: #0000ff;">&quot;2&quot;</span>, <span style="color: #0000ff;">&quot;etc&quot;</span>, <span style="color: #0000ff;">&quot;varargs are nice&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		assertTrue<span style="color: #009900;">&#40;</span>object <span style="color: #000000; font-weight: bold;">instanceof</span> LinkedHashMap, <span style="color: #0000ff;">&quot;JsonObject actually extends LinkedHashMap&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// get with varargs, a natural evolution for Map</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span>,<span style="color: #0000ff;">&quot;c&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">asPrimitive</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">asBoolean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;extract stuff from a nested object&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getBoolean</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span>,<span style="color: #0000ff;">&quot;c&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;or like this&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getInt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span>,<span style="color: #0000ff;">&quot;d&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">42</span>, <span style="color: #0000ff;">&quot;or an integer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span>,<span style="color: #0000ff;">&quot;e&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;hi!&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;or a string&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getArray</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;array&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;works for arrays as well&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;and objects&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// builders are nice, but still feels kind of repetitive</span>
		JsonObject anotherObject <span style="color: #339933;">=</span> object.<span style="color: #006633;">getOrCreateObject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1&quot;</span>,<span style="color: #0000ff;">&quot;2&quot;</span>,<span style="color: #0000ff;">&quot;3&quot;</span>,<span style="color: #0000ff;">&quot;4&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		anotherObject.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;5&quot;</span>, <span style="color: #0000ff;">&quot;xxx&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1&quot;</span>,<span style="color: #0000ff;">&quot;2&quot;</span>,<span style="color: #0000ff;">&quot;3&quot;</span>,<span style="color: #0000ff;">&quot;4&quot;</span>,<span style="color: #0000ff;">&quot;5&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;xxx&quot;</span><span style="color: #009900;">&#41;</span>,<span style="color: #0000ff;">&quot;yep, we just added a string value 5 levels deep&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		JsonArray anotherArray <span style="color: #339933;">=</span> object.<span style="color: #006633;">getOrCreateArray</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;5&quot;</span>,<span style="color: #0000ff;">&quot;4&quot;</span>,<span style="color: #0000ff;">&quot;3&quot;</span>,<span style="color: #0000ff;">&quot;2&quot;</span>,<span style="color: #0000ff;">&quot;1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		anotherArray.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;xxx&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">getArray</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;5&quot;</span>,<span style="color: #0000ff;">&quot;4&quot;</span>,<span style="color: #0000ff;">&quot;3&quot;</span>,<span style="color: #0000ff;">&quot;2&quot;</span>,<span style="color: #0000ff;">&quot;1&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;xxx&quot;</span><span style="color: #009900;">&#41;</span>,<span style="color: #0000ff;">&quot;naturally works for arrays too&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Lets do some other stuff</span>
		assertTrue<span style="color: #009900;">&#40;</span>object.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>object<span style="color: #009900;">&#41;</span>,
			<span style="color: #0000ff;">&quot;equals is implemented as a deep equals&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>, <span style="color: #0000ff;">&quot;b&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;b&quot;</span>, <span style="color: #0000ff;">&quot;a&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
			<span style="color: #0000ff;">&quot;mostly you shouldn't care about the order of stuff in json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>
			object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;b&quot;</span>, <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>
				object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;b&quot;</span>, <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a&quot;</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
			<span style="color: #0000ff;">&quot;true for objects as well&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Arrays are lists</span>
		JsonArray array <span style="color: #339933;">=</span> array<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span>, <span style="color: #0000ff;">&quot;bar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>array <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">LinkedList</span>, <span style="color: #0000ff;">&quot;JsonArray extends LinkedList&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>array.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> array.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bar&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;returns the same object&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>array.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;obviously&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		assertTrue<span style="color: #009900;">&#40;</span>array.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>primitive<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;but this works as well&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// serialize like this</span>
		<span style="color: #003399;">String</span> serialized <span style="color: #339933;">=</span> serialize<span style="color: #009900;">&#40;</span>object<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// parse it</span>
		JsonElement json <span style="color: #339933;">=</span> jsonParser.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>serialized<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// and write it straight to some stream</span>
		write<span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>, json, <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// or pretty print it like this</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">+</span> serialize<span style="color: #009900;">&#40;</span>json, <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/05/31/jsonj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Panorama of Lisbon</title>
		<link>http://www.jillesvangurp.com/2011/04/06/panorama-of-lisbon/</link>
		<comments>http://www.jillesvangurp.com/2011/04/06/panorama-of-lisbon/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 07:14:05 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=850</guid>
		<description><![CDATA[Click to see the slightly larger version. Here&#8217;s a nice Panorama of Lisbon that I shot a few weeks ago using my new Canon 550D. It consists 10 individual 18 mega pixel photos at full focal length (135mm) to zoom &#8230; <a href="http://www.jillesvangurp.com/2011/04/06/panorama-of-lisbon/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jillesvangurp.com/wp-content/uploads/2011/04/lisbon.jpg"><img src="http://www.jillesvangurp.com/wp-content/uploads/2011/04/lisbon_thumbnail.jpg" alt="Lisbon" title="Panorama  photo of Lisbon" class="aligncenter size-full wp-image-851" style="width: 100%;" /></a></p>
<p>Click to see the slightly larger version.</p>
<p>Here&#8217;s a nice Panorama of Lisbon that I shot a few weeks ago using my new Canon 550D. It consists 10 individual 18 mega pixel photos at full focal length (135mm) to zoom in across the Tejo river (around 1500m) that were stitched together using the ever amazing <a href="http://hugin.sourceforge.net/">Hugin</a>. The latest version of this is quite amazing at basically figuring out everything by itself. It&#8217;s like here&#8217;s a bunch of pictures, make a panorama out of that. And then it goes off and finds common points in the photos, arranges them in a grid that makes sense. Adjusts for lens characteristics, rotates, translates and distorts the photos until they overlap perfectly, adjusts tonality of the photos to match, blends the photos seamlessly and finally spits out a big whopping tif file. There are other tools that do some of these things but this one is the best by far. If you are willing to tweak the tool, it can do some pretty funky things like HDR panoramas (i.e. stitch together overlapping photos with multiple exposures), do panoramas where the photos have different exposures and tonality, use different projections for the panorama, drag around the stitched panorama inside whichever projection you chose to influence how things look, manually identify overlapping points, plugin experimental tools and algorithms for the various steps of creating a panorama, etc. </p>
<p>Unfortunately, you have to down-size this kind of images for the web and apply lots of jpeg compression. The final image is  10032&#215;1024 pixels, downsized from 21896&#215;2235 to save some precious bandwidth. The tif weighs in at a bit over 100MB. The lowests size jpeg I managed to get out of the full image was around 2.5 MB, but at that size compression artifacts are very noticeable. So I instead re-sized to something that might fit on an over sized display (vertically at least) so that people will have to scroll in only one dimension and got the size down to 1.1 MB with a respectable compression rate of around 30%, which preserves a lot of detail.</p>
<p>I was positioned in front of <a href="http://en.wikipedia.org/wiki/Cristo-Rei">the big Jesus statue that is visible from Lisbon</a>. I later went up as well and shot some more photos, some of which you can admire <a href="https://picasaweb.google.com/jillesvangurp/Portugal2011">here</a> (along with the rest of my photos from that trip). There is one photo there with the <a href="https://picasaweb.google.com/jillesvangurp/Portugal2011#5590316002456901138">same view in a single photo</a> from up on the statue that gives you a nice impression of the zoom range of this camera. It looks like a panorama photo but it is really just a zoomed out photo that I cropped a little.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/04/06/panorama-of-lisbon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comments should be working again</title>
		<link>http://www.jillesvangurp.com/2011/04/05/comments-should-be-working-again/</link>
		<comments>http://www.jillesvangurp.com/2011/04/05/comments-should-be-working-again/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 17:51:18 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=844</guid>
		<description><![CDATA[I had a captcha plugin that was failing. Since I myself hate captcha&#8217;s, I&#8217;ve removed it for now and adjusted the comment settings to require moderation the first time you comment. Moderation + akismet should take care of most of &#8230; <a href="http://www.jillesvangurp.com/2011/04/05/comments-should-be-working-again/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I had a captcha plugin that was failing. Since I myself hate captcha&#8217;s, I&#8217;ve removed it for now and adjusted the comment settings to require moderation the first time you comment. Moderation + akismet should take care of most of the spam (hopefully). You can also still sign in using OpenId if you prefer, although the openid login on wordpress remains quite underwhelming (compared to what should be possible by now).</p>
<p>Anyway, happy commenting and thanks @eelkefolmer for pointing out my site was broken.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/04/05/comments-should-be-working-again/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>On Java, Json, and complexity</title>
		<link>http://www.jillesvangurp.com/2011/04/02/on-java-json-and-complexity/</link>
		<comments>http://www.jillesvangurp.com/2011/04/02/on-java-json-and-complexity/#comments</comments>
		<pubDate>Sat, 02 Apr 2011 11:21:26 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=818</guid>
		<description><![CDATA[Time for a long overdue Saturday morning blog post. Lately, I&#8217;ve been involved in some interesting new development at work that is all about key value stores, Json, Solr and a few other technologies I might have mentioned a few &#8230; <a href="http://www.jillesvangurp.com/2011/04/02/on-java-json-and-complexity/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Time for a long overdue Saturday morning blog post.</p>
<p>Lately, I&#8217;ve been involved in some interesting new development at work that is all about key value stores, <a href="http://www.json.org/">Json</a>, <a href="http://lucene.apache.org/solr/">Solr</a> and a few other technologies I might have mentioned a few times. In other words, I&#8217;m having loads of fun at work doing stuff I really like. We&#8217;ve effectively tossed out XML and SQL and are now all about Json blobs that live in KVs and are indexed in Solr. Nothing revolutionary, except it is if you have been exposed to the wonderfully bloated and complicated world of Java Enterprise Edition and associated technologies. I&#8217;ve found that there is a bunch of knee-jerk reflexes that causes Java developers to be biased to be doing all the wrong things here. This is symptomatic of the growing gap between the enterprise Java people on one side and the cool hip kids wielding cool new languages and tools on the other hand.</p>
<p><span id="more-818"></span></p>
<p><strong>The problem with Json in Java</strong></p>
<p>One of the things I&#8217;ve been struggling with recently is Json. Json and the java world is not a perfect marriage. The whole point of Json is that it is valid Javascript, Python, and Ruby. That doesn&#8217;t mean that you should go off and execute it but it does mean that after parsing (or rather unmarshalling), you end up with dictionaries, lists, and native types that each of those languages supports. This means you can have light weight data structures that you can just serialize to and from Json at will. In Python, classes are just dictionaries of attributes and dictionaries and lists are native types. That means that Json is a very natural serialization of any Python object structure. Javascript doesn&#8217;t have classes since it is a prototype based language, but of course lists and dictionaries are native types there as well and objects are of course dictionaries. I&#8217;m not a ruby-ist but I know enough of it that it is similar to Python and Javascript in this respect as well.</p>
<p>Sadly, this not the case in the Java world. Dictionaries and Lists are not native types and instead people use the Collections framework (or alternatives such as Google collections). The classes in those frameworks are of course generic these days and classes bear very little resemblance to dictionaries in Java. That means Json is not a very natural serialisation for a Java based object structure. Frameworks exist to address this through mappings, which can be convenient. Except, it reduces the Json approach to yet another way to serialise Java objects rather than a beautifully simple and elegant solution to modeling your data. And that&#8217;s where the problem lies.</p>
<p>My main problem with doing things using mapping is that it&#8217;s not exactly lightweight anymore. Suddenly you need to worry about instantiating classes, stuffing the right bits of data in the right setters and constructors. Then inevitably you start doing some hashCode and equals methods and of course generics creeps in somewhere along the way (or even worse, inheritance). Then you generalize and add some interfaces, annotations, etc. Congratulations: your easy to read 50 line Json file representing a simple dictionary with some very simple, uncomplicated Json magically turned into a framework with dozens of classes and thousands of lines of code that does nothing else than represent what any javascript, python, or ruby programmer would trivially accomplish with a few lines of code. That&#8217;s some serious bloat. It&#8217;s the reason countless of software engineers have been fleeing the java enterprise world in favor of more sane worlds such as Python Django, Ruby on Rails, or even <a href="http://nodejs.org/">Node.js</a>. It makes me want to flee as well.</p>
<p><strong>The solution: do what others do and use Json</strong></p>
<p>I&#8217;ve been fighting this bloat &#038; complexity over the past few months and have been stubbornly reducing the number of model classes we have to 0. Instead I simply use the classes provided by the <a href="http://code.google.com/p/google-gson/">GSon</a> framework (which is one of the popular options in the Java world for dealing with Json) to represent the core Json objects, I.e. JsonObject and JsonArray + the four primitive types (int, double, string, boolean). Where in the past I would have been constructing model classes and instantiating those, I instead do a &#8220;new JsonObject()&#8221; and start modifying it through its primitives for adding JsonObjects, JsonArrays, or one of the four JsonPrimitives. This is different than what most Json frameworks in Java try to achieve, which is providing convient ways to map to and from Json and your model classes. What I want is to get rid of model classes.</p>
<p>You can lose some serious amounts of source code this way. People seem terribly concerned with hiding Json from the Java programmer by adding layers of indirection to hide it. What they don&#8217;t realize is that there is a direct correlation between lines of code and complexity on one hand and maintenance cost on the other hand. Json world: you are adding string &#8220;foo&#8221; to a dictionary. Java world, you are creating an instance of class Foo&lt;String&gt; and another of FooHolder&lt;Foo&lt;String&gt;&gt;. Then you add your instance of Foo to the FooHolder and then you serialize it to Json. I&#8217;m exaggerating of course but I&#8217;ve seen people write code that essentially boiled down to setting a few properties on a dictionary and yet somehow required 10+ classes and an afternoon of coding to accomplish. That feels very wrong to me.</p>
<p><strong>Problems with the Java language</strong></p>
<p>The problem is actually quite subtle and strongly related to a few areas where Java is lacking relative to more modern languages:</p>
<ul>
<li>Java distinguishes between native types and classes (which are a native type with a shallow non native wrapper Class, but you can&#8217;t &#8216;instantiate&#8217; a new class). That means for example that a class is not a dictionary and lists and dictionaries are not native types. This causes all sorts of issues with reflection and advanced typing (like generics) or the introduction of <a href="http://blogs.sun.com/jag/entry/closures">closures</a> to the language. This is a problem more modern object oriented languages don&#8217;t suffer from since in those languages everything is natively an object, including a class.</li>
<li>Static typing is nice but often dynamic typing is good enough. As can be seen see with <a href="http://www.scala-lang.org/">Scala</a>, or <a href="http://www.mirah.org/">Mirah</a> (a natively compilable Ruby dialect), it doesn&#8217;t have to be so black and white. Fact: the Java type system represents the state of the art in the early eighties and does not incorporate many of the advances since then. Modern languages can be far more expressive and less verbose without much sacrifice.</li>
<li>Java has no good way of representing multi typed dictionaries because of its rigid type system. You cannot easily express a dictionary where key &#8220;foo&#8221; maps to an integer and key &#8220;bar&#8221; maps to another dictionary. In other words, Java lacks the language capability to express the contents of a Json dictionary elegantly. The &#8216;workaround&#8217; is to use Object as the type, which then leads to a lot of casting elsewhere. Generics don&#8217;t quite address this. This is a fundamental and critical flaw that has given rise to an enormous amount of complexity in the Java enterprise world. Any time you hear Java developers talk about mappings and frameworks, they are working around this problem. Massive amounts of code are involved with working around this problem.</li>
<li>The lack of proper typing and closures leads Java coders to believe they need to model the world in terms of classes and objects. This is a very serious problem because it naturally leads to complex frameworks for even the simplest of domains. If you&#8217;ve been exposed to a decent amount of functional programming, you will feel dirty after a day of work with any of the big Java frameworks. They&#8217;re big, clumsy, and tedious. And they generally don&#8217;t play nice together and fuse data and functionality together in a way that actually prevents reuse.</li>
<li>Java has no first class properties and instead relies on the <a href="http://en.wikipedia.org/wiki/JavaBean">JavaBeans</a> convention of having lots of setters and getters. So where in a decent language you would go object.attribute.attribute2.attribute3 = foo, you get in Java several lines of code with setter and getter calls as well as null checks just to stuff foo in the right place in the object graph.</li>
</ul>
<p><strong>Principles I stick to</strong></p>
<p>So, does that mean I&#8217;d love to switch languages to something more modern? Absolutely, I&#8217;m bored out my mind with Java! But sadly, that&#8217;s not likely to be happening on any of the projects I&#8217;m currently involved with and I have to work with what I have. So, instead I&#8217;ve started to resist the traditional Java way since I believe a lot of these practices to be outdated and counter productive. I have started to incorporate and borrow patterns and idioms from elsewhere. </p>
<ul>
<li><strong>Json is the primary way to represent data.</strong> Any data that goes in or out of the system via the API is represented as Json. That makes Json the primary representation of the data. That also means any representation other than Json is a secondary concern and as such a waste of time and resources. That includes any kind of Java class or object hierarchy intended to represent the data that is in the Json. That is a reverse of principle for a traditional Java programmer who will consider Java his most important way of expressing things and will consider json a secondary concern.</li>
<li><strong>Use a dedicated set of classes to represent Json in Java.</strong> Because of several of the before mentioned language issues, the Java collections framework is not very suitable for representing Json in Java. I tend to prefer the way it is done in the before mentioned GSon framework. So I use JsonArray, JsonObject, JsonElement, JsonPrimitive (and its four subclasses).</li>
<li><strong>Use a key value store.</strong> A key value store is nothing but a persistent dictionary. So, Key Value stores are the natural way to deal with persistence. Listen carefully, I just wiped an entire layer from the traditional enterprise architecture. That&#8217;s good. No more object relational mappings. Json is what goes into your system and it is what goes out into the storage layer.</li>
<li><strong>Resist secondary representations and stick to the primary representation: Json.</strong> Don&#8217;t do secondary representations and associated mappings, translations, frameworks, etc. because every time the primary representation (i.e. Json structure) evolves, it triggers a ripple effect of code changes related to secondary code artifacts. Avoid this unnecessary cost by not having those.</li>
<li><strong>Don&#8217;t expose your internals.</strong> Business logic natively manipulates Json objects because business logic is a primary concern. Any usage of non Json objects is disallowed in public facing APIs. So, never return List, Maps, etc. but instead return and accept JsonArray and  JsonObject instances (or Java native types). Don&#8217;t force your API users into using your internal data representation. Every time you violate this rule, you are leaking internals through your API. Don&#8217;t do that, it&#8217;s bad design.</li>
<li><strong>Everything may become external some day.</strong> Of course what is internal and external is somewhat a blurry distinction. So, it follows that you must use Json internally as well since it may one day become external.</li>
<li><strong>No needless abstractions.</strong> All <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">abstractions are leaky</a>. This is particularly true of domain models. What seems like a good abstraction now may prove to be a horribly poor idea a few years down the road. The world is full of frameworks and domain models that don&#8217;t play nice with each other and are poorly aligned (you likely are guilty of inventing several of them). Your Json input and output is the one and only representation of the data so don&#8217;t even try to abstract from it.</li>
<li><strong><a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> and <a href="http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it">YAGNI</a>.</strong> Keeping things small and simple removes much of the need for complexity. Each extra class is complexity, each extra method is complexity, each extra mapping is complexity, each extra layer is complexity. If your data is simple, your code should be simple as well. Don&#8217;t add complexity you don&#8217;t need because you aint gonna need it. For example, the <a href="http://geojson.org/geojson-spec.html">GeoJson</a> representation of a coordinate is an array of two doubles. I&#8217;d hate to see the equivalent of GeoJson as a Java framework. I shudder just thinking of all those tedious little classes to represent points, polygons, etc. that are of course completely incompatible with similar classes you&#8217;d find in Java2D, OpenGl, or other graphics frameworks. Don&#8217;t do it. Array of two doubles is good enough.</li>
<li><strong>Respect the <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">law of Demeter</a>.</strong> Json is inherently weakly typed, so don&#8217;t assume to much about its structure and dig out that JsonObject from your main Json document and then work directly on that object rather than indirectly by passing around references to the main JsonObject. This is simply applying the law of Demeter, which requires you to use no needless levels of indirection when accessing members of an object. So bad: String s = root.foo.bar.foobar.bar, right: s = foobar.bar embedded in some code that is parametrised with whatever happens to contain foobar. Modularise your code around small, uncomplicated Json objects rather than big, deeply nested ones. Separate the assumptions about which objects go where from the assumptions of what is inside those objects because both are likely to change and because those objects might start to appear in different places.</li>
<li><strong>Design your Json for more capable languages.</strong> You are not merely serialising data, you are creating a Json document that others are going to use from e.g. javascript. It is worth spending some time considering their needs and requirements. Read: they don&#8217;t like big, complicated Json that is hard to read.</li>
</ul>
<p>It&#8217;s not all good of course and there are downsides to rebelling against the Java way:</p>
<ul>
<li>Refactoring becomes a bit more tedious. I tend to use constants for my attribute names, which partially addresses this. But forget about manipulating the Json structure with the refactoring tooling in your IDE. This is particularly annoying for business logic depending on that structure. A work around here is to keep things simple.</li>
<li>Extracting data from Json structures can be tedious and may involve a lot of null checks. We work around this with a few static helper methods. <a href="http://download.oracle.com/javase/1.5.0/docs/guide/language/varargs.html">Varargs</a> is your friend here. e.g. extract(object, attr1, attr2, attr3) would return either null or the value of object.attr1.attr2.attr3. Mind you, you have exactly the same issue with many Java object graphs and this is a likely cause for any NullPointerException you&#8217;ve ever encountered.</li>
<li>You will at points miss the convenience of model classes. This is the price you pay for the Java type system. Keep dreaming of a better world where you don&#8217;t have to use it anymore. The alternative of using model classes in Java is a fallacy though. It&#8217;s entirely true that you would end up using model classes in Python though. However, Python classes are dictionaries and as such need no translation work whatsoever. Java classes are not dictionaries and do require translation work.</li>
<li>Like all good frameworks, the Json classes in GSon are final so you can&#8217;t sneak in model classes by extending JsonObject. However, you might consider using wrapper objects that have a delegate JsonObject as the single field. I&#8217;m not strongly against this but it still feels like bloat to me and I prefer to avoid this pattern because of KISS and YAGNI.</li>
<li>There is a lot of code out there that assumes you are doing things the Java way, reusing that just got a little harder. But I again refer you to the principle on KISS and YAGNI.</li>
</ul>
<p><strong>Why this is important</strong></p>
<p>I&#8217;ve been refactoring quite a bit of code using the above principles and I can report to have shed many lines of code along the way while improving readability, reducing complexity, and gaining flexibility. My background as a software engineering researcher tells me this is a good thing (TM) because <a href="http://www.dwheeler.com/sloc/">lines of code directly correlate to software development cost, complexity, and maintenance cost</a>. Therefore, less lines of code and complexity is almost always the right thing to aim for unless you can convert the investment in cost into added value. More lines of code is not necessarily the same as adding value. If it is not adding value, it is in fact <a href="http://www.martinfowler.com/bliki/TechnicalDebt.html">technical debt</a>.</p>
<p>I&#8217;ve seen a lot of Java projects lately that are needlessly complicated and hard to maintain while trying to achieve seemingly simple goals that involve accepting some data, stuffing it in a data store, retrieving it and and returning it via some API.  CRUD in other words. CRUD is simple but not if it has to go to several layers of indirection that involve mapping xml to data transfer objects and then to model objects, and then to SQL tables and back again. The system we are replacing with a new system based on the principles outlined here does this. Its business logic amounts to take in data, validate it, store it, mash it together in an interesting way and retrieve it. Its business logic should also include a bunch of other things that we never got around to because we got bogged down in non value adding activities related to mapping data in different ways and dealing with over engineered &#038; bloated technologies that got abused in a terrible way by some junior engineers who thought they were in a candy store. In other words, I&#8217;ve gone through months of head shaking,  swearing a lot, silently cursing misc. individuals no longer on the team, and mostly deleting code to replace it with small amounts of new code. In other words, I&#8217;ve taken a system that pretty much A** rapes the listed principles and am working hard on building a replacement that doesn&#8217;t do that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/04/02/on-java-json-and-complexity/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Internationalization fail</title>
		<link>http://www.jillesvangurp.com/2011/02/12/internationalization-fail/</link>
		<comments>http://www.jillesvangurp.com/2011/02/12/internationalization-fail/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 15:27:56 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=811</guid>
		<description><![CDATA[I just visited the Adobe online store and eventually left in disgust because apparently it is unable to service me. This is not the first time something like this has happened to me so I decided to spell it out &#8230; <a href="http://www.jillesvangurp.com/2011/02/12/internationalization-fail/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just visited the Adobe online store and eventually left in disgust because apparently it is unable to service me. This is not the first time something like this has happened to me so I decided to spell it out a little.</p>
<p>Once upon a time, I signed up on the Adobe site to use the online version of photoshop. I probably was still in Finland at the time so naturally, I used their English localized web site. Fast forward to today and I am interested in downloading the trial version of Adobe Lightroom to play with it and possibly buy it. </p>
<p>To do that you need to log in. So I log in. Then it asks me for my address. Fine. Except, I don&#8217;t live in the US and there is no country switching thingy in the form. Apparently it hardwired the country choice (which really was a language preference) into my account. Fail #1.</p>
<p>It gets worse. They do have a country switcher on the front page and in the store. So I set that to Germany. Now it addresses me in German. Fail #2</p>
<p>Of course there is no language switcher. It is assumed (wrongly) that I must be a native speaker and therefore want to be addressed in German. Always. Fail #3</p>
<p>So by this point I decide to be pragmatic and select some region they haven&#8217;t localized for to get the site in English. So I select Eastern Europe, which is apparently a region not worth breaking up into countries and technically I live in the former DDR, which used to be eastern Europe. So I once again go to the store. Prices in euros this time. Great! Although effectively the price just went up 80 euros since 300$ is ~220 Euro and not 300 Euro! Then I get to the point I need to enter my address, it still insists on a US address. Fail #4. If people select a region, it&#8217;s probably because they live there. </p>
<p>Underlying this problem is a common failure of online retailers to grasp the basics of internationalization and demographics that is causing them to lose the business of millions of potential customers who have a language/region combination that they can&#8217;t support. This is especially silly when the language is English and the online retailer is US based. English is a great language. World wide, there must be many more non native speakers of it than native speakers. Especially migrants (like) me tend to rely heavily on English.</p>
<p>So, I am not going to be an Adobe customer. </p>
<p>I&#8217;m not an iTunes user either for the same reason and for the reason that I&#8217;m not big into German dubbed movies and schlagers, which is pretty much what they tried to sell me on the few times I tried to use it. Also, I declined to accept the terms of use when I was living in Finland because they were in Finnish, which is something I don&#8217;t speak and I tend not to agree with official looking text that I can&#8217;t read.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2011/02/12/internationalization-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>N8</title>
		<link>http://www.jillesvangurp.com/2010/11/18/n8/</link>
		<comments>http://www.jillesvangurp.com/2010/11/18/n8/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 04:06:28 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=801</guid>
		<description><![CDATA[I&#8217;ve had the nokia N8 for a few weeks now and since I like it, I thought I&#8217;d do a little review. Does it have rough edges? Sadly, yes there are some. But no major show stoppers. It&#8217;s stable. The &#8230; <a href="http://www.jillesvangurp.com/2010/11/18/n8/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had the nokia N8 for a few weeks now and since I like it, I thought I&#8217;d do a little review.</p>
<p>Does it have rough edges? Sadly, yes there are some. But no major show stoppers. It&#8217;s stable. The camera is awesome. The video playback is great. You can play most movies without re-encoding them. I managed to not run out of battery during a trans atlantic flight, watching movies non stop, and the oled screen is fantastic.</p>
<p>I&#8217;m particularly happy with how maps is improving with each version. </p>
<p>It went from something that barely worked a few years ago to being arguably one of the best mobile maps experiences around. It&#8217;s certainly very competitive when it comes to map quality, navigation, and offline usage.Disclaimer, I work on the backend services for this application <img src='http://www.jillesvangurp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>I&#8217;ve used two ovi store applications to write this post. One is called swype and it replaces the touchscreen keyboard with a version that allows you to &#8216;draw&#8217; across the keyboard and it figures out the words with great accuracy and speed.</p>
<p>The other is the official wordpress client, which I&#8217;m trying for the first time, and of course that&#8217;s the real reason for writing all this <img src='http://www.jillesvangurp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . </p>
<p>So far so good. I managed to write a good chunk of text with swype and the wordpress app seems to do everything I need it to do.</p>
<p>All together this is a pretty good phone and it is getting even better with upcoming software releases. I think the recent focus of nokia on software quality and end user experience is starting to pay off. It&#8217;s not without flaws of course and it&#8217;s definitely to early to call the battle with our competitors over but it is progress and I think we&#8217;re getting there.</p>
<p>A final note here. I work for Nokia and am of course slightly biased. That being said, I rarely review stuff we produce and as a rule only when I really like it, without reservations. I loved the n900, which I reviewed a few months ago, but I&#8217;ve had several nokia phones that I chose not to review as well for this reason.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2010/11/18/n8/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Updated my publications page &#8230;</title>
		<link>http://www.jillesvangurp.com/2010/11/11/updated-my-publications-page/</link>
		<comments>http://www.jillesvangurp.com/2010/11/11/updated-my-publications-page/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 18:51:35 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>
		<category><![CDATA[Academic]]></category>
		<category><![CDATA[New publication]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=789</guid>
		<description><![CDATA[It&#8217;s been a while, but now that the last two big journal articles I had in the pipeline for ages are printed, I finally updated my publications page with proper references and pdfs. For those who got to know me &#8230; <a href="http://www.jillesvangurp.com/2010/11/11/updated-my-publications-page/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while, but now that the last two big journal articles I had in the pipeline for ages are printed, I finally updated my <a href="http://www.jillesvangurp.com/publications/">publications</a> page with proper references and pdfs. </p>
<p>For those who got to know me more recently (or don&#8217;t know me at all). I have been moving back and forth between academic jobs and non academic jobs for about twelve years. The last two years I&#8217;ve been employed in a strictly non-academic role, which I enjoy very much. Before that I was working (and publishing) at the Nokia Research Center. In that job, I squeezed out several not so important workshop articles and book chapters as well as two major, big journal articles (which in the academic world is all that counts). Those articles took a long time to write and even longer to get reviewed, edited, re-reviewed, re-edited, accepted, re-edited, approved, edited by a professional editor, approved, pre-published, and finally printed. </p>
<p><strong>Practical Web-Based Smart Spaces</strong><br />
Abstract:</p>
<blockquote><p>Mobile devices are evolving into hubs of content and context information. Many research projects have shown the potential for new pervasive computing applications. This article shows how Web and resource-based smart spaces can support pervasive applications in a wide variety of devices. A framework that employs a resource-based HTTP style for pervasive services called Representational State Transfer (REST) can enable easy mashup of applications. This framework has several important features. First, a flexible access control mechanism on top of the OpenID and OAuth protocols provides security and access control in heterogeneous, dynamic environments. Second, a search engine can collaborate with existing service and network discovery mechanisms to find resources on the basis of their indoor location. Finally, an emerging W3C standard, Delivery Context: Client Interfaces (DCCI), facilitates sharing information within a device in an interoperable fashion.</p></blockquote>
<p>The first article, we decided to write in 2008 as a way to promote the fine research we had been doing in Nokia Research. You can&#8217;t get better marketing for your research than an article in a high profile magazine with a wide distribution in the research community. The magazine we selected for this was Pervasive Computing, and I&#8217;m very proud and happy we got our article in. Since this is a magazine and not a journal, the article is comparatively limited in size, which means that it posed some interesting challenges on what to keep in it and what to omit. </p>
<p><strong>Comparing Practices for Reuse in Integration-oriented Software Product Lines and Large Open Source Software Projects</strong><br />
Abstract:</p>
<blockquote><p>This paper compares organization and practices for software reuse in integration- oriented software product lines and open source software projects. The main observation is that both approaches are successful regarding large variability and reuse, but differ widely in practices and organization. To capture practices in large open source projects, we describe an open compositional model, which reflects their more decentralized organization of software development. We capture key practices and organizational forms for this and validate these by comparing four case studies to this model. Two of these studies are based on published software product line case studies, for the other two we analyze the practices in two large and successful open source projects based on their published developer documentation. Our analysis highlights key differences between the practices in the two open source organizations and the more integrational practices used in the other two cases. Finally, we discuss which practices are successful in which environment and how current practices can move towards more open, widely scoped and distributed software development.</p></blockquote>
<p>I started writing the second article,  already in 2006. The first drafts were not very satisfying and we put it on ice for quite some time until deciding to finally get it published in 2008, which meant a more or less full rewrite of what we had until then. From there it took until September 2010 to get it printed. Most of those 2+ years were spent waiting and very occasionally doing major revisions of the article in response to some reviews and editor comments.  </p>
<p>This last article (for now) has some continuity from my earlier work on software variability, software product lines, and software design erosion that I covered in my Ph. D thesis in 2003 (and several related publications). We present a model for large scale software development that we reconstructed from observing &#8220;how it&#8217;s done&#8221; in several case studies published by others as well as in the open source community as well as our own experience studying various systems and companies, as well as getting our own hands dirty with actual software engineering. Two years of subsequent practicing real software development in Nokia has only strengthened my belief in the vision presented in the paper, which is that the only proper way to scale software development to a software eco system (i.e. a thriving community of many developers across many organizations working with and on the software) is to decentralize management of the development process. If you are interested in this and want to read more, co-author <a href="http://www.janbosch.com">Jan Bosch</a>, my former Ph. D. supervisor who now works at Intuit, has been publicizing this view as well in his frequent talks and keynotes at various conferences. This  <a href="http://www.software-ecosystems.com/Software_Ecosystems/Ecosystems.html">website</a> is dedicated to this topic.</p>
<p>Now with both articles out of the way, the question is &#8220;what&#8217;s next?&#8221;. The answer to that, for now, is nothing because I haven&#8217;t started writing any new articles in the last two years. And frankly I&#8217;m not likely to start writing one soon since I lack the time and I&#8217;m appalled by the snail pace at which the publication process progresses. Both articles have turned out very nice but would have had much greater impact if we had been able to get them written and published in the same year instead of (nearly) 3 to 5 years apart. Sadly, this is the reality of academic life. You write your stuff, you move on, and some day stuff actually gets printed on dead trees. There are more reasons, which I won&#8217;t rant about here but it is a big factor in me not being interested in publishing any more, for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2010/11/11/updated-my-publications-page/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deutsche bank</title>
		<link>http://www.jillesvangurp.com/2010/11/01/deutsche-bank/</link>
		<comments>http://www.jillesvangurp.com/2010/11/01/deutsche-bank/#comments</comments>
		<pubDate>Mon, 01 Nov 2010 22:47:30 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=780</guid>
		<description><![CDATA[Right now I&#8217;m pretty angry with my bank. I&#8217;m currently traveling and to my great surprise I couldn&#8217;t get any cash from any ATM in Boston when I arrived there on Saturday evening. Kind of inconvenient to be without cash &#8230; <a href="http://www.jillesvangurp.com/2010/11/01/deutsche-bank/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Right now I&#8217;m pretty angry with my bank. I&#8217;m currently traveling and to my great surprise I couldn&#8217;t get any cash from any ATM in Boston when I arrived there on Saturday evening. Kind of inconvenient to be without cash if you are traveling. Luckily my credit card still worked so I managed to get into my hotel and get some food (one of the nice things in the US is that you can use your credit card everywhere). Also, some colleagues were kind enough to borrow me some money.</p>
<p>Anyway what pissed me off was the following:</p>
<p>On Sunday morning/night (jet lag), I called the phone number listed on my bank card to find out what the hell is going on.</p>
<p>This lands you in the standard useless menu where some very tedious computer voice slowly guides you to your destination repeating every choice you make and asking whether that was really what you wanted. This one was particularly annoying because they insisted on my full account number (they had speech recognition though) and branch number of my local bank office, which is apparently very important in Germany. Naturally, the first questions I got when I finally got a human to talk to me were what my branch and account number were.</p>
<p>Then the misery started, nobody on the other side of the line could do anything useful for me. Lady #1 who luckily spoke English connected me to Lady #2 who didn&#8217;t and quite rudely told me to go away (in German). So, I had to go through the above mentioned menu again to talk to Guy #1. I then asked him &#8220;do you speak English&#8221; and he said yes but added &#8220;I&#8217;m not allowed to speak to customers in English&#8221;. Eh right. He clearly detected my anger/amazement and then proceeded in English anyway, for which I&#8217;m grateful, I guess. He then figured out that I probably wanted to talk to someone in my branch office. So he gave me a number for Lady #3 who of course would not be reachable until Monday. So, I was stuck for another 24 hours without cash on me and I still had no clue why my card was not working (e.g. somebody might have skimmed my card and is emptying my account).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2010/11/01/deutsche-bank/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git svn voodoo</title>
		<link>http://www.jillesvangurp.com/2010/10/04/git-svn-voodoo/</link>
		<comments>http://www.jillesvangurp.com/2010/10/04/git-svn-voodoo/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 21:53:40 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=769</guid>
		<description><![CDATA[As discussed earlier on this site, I recently started using git in our svn centric organization. Since I&#8217;m trying to convince some co-workers to do the same, I would like to share a bit of git voodoo for working with &#8230; <a href="http://www.jillesvangurp.com/2010/10/04/git-svn-voodoo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As discussed earlier on this site, I recently started using git in our svn centric organization. Since I&#8217;m trying to convince some co-workers to do the same, I would like to share a bit of git voodoo for working with multiple git repositories and a central svn repository. Most git tutorials don&#8217;t really show how to do this, even though it is quite easy. The approach below gives you all the flexibility with git that you need while allowing you to inter-operate seamlessly with your svn using colleagues.</p>
<p><span id="more-769"></span></p>
<p>Before getting started, make sure you have both git-core and git-svn installed (ubuntu) or that you have done a &#8220;sudo port install git-core +svn +bash_completion&#8221; if you have a mac. Also, you probably want to <a href="http://www.arthurkoziel.com/2008/05/02/git-configuration/">configure git properly</a>. Google is your friend, there are plenty of tutorials on the basics of git and svn that you might want to run through first.</p>
<p>Both git and svn use urls to identify repositories. For the sake of simplicity, I will use a very basic example involving three local repositories on my file system with file:// based urls but of course you can use http:// ssh+svn:// or git:// type urls just the same:</p>
<ul>
<li>file:///Users/jilles/test/svnrepo &#8211; A little svn repository. Generally this will be your central svn repo with years of work inside it.</li>
<li>file:///Users/jilles/test/git1 &#8211; A git repository that we&#8217;ll create using git svn.</li>
<li>file:///Users/jilles/test/git2 &#8211; Another git repository that we will create using git clone.</li>
</ul>
<p>Lets start by creating a simple svn repo, checking out a svn work copy, and committing some stuff using svn:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">svnadmin</span> create svnrepo
<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>svnrepo svnwc
<span style="color: #7a0874; font-weight: bold;">cd</span> svnwc
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;hello&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> hi.txt
<span style="color: #c20cb9; font-weight: bold;">svn</span> add hi.txt
<span style="color: #c20cb9; font-weight: bold;">svn</span> commit <span style="color: #660033;">-m</span><span style="color: #ff0000;">'hi.txt added'</span>
<span style="color: #c20cb9; font-weight: bold;">svn</span> up</pre></div></div>

<p>Ok, we now have a svn repo with some stuff in it. In the git world, you always work on a local repository. You don&#8217;t check out from a remote repository, instead you clone it. So, lets git svn clone it to a local git repository and make some changes there and then commit it back to the svn repo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #666666; font-style: italic;"># clone the svn repository to a git repository using git-svn ...</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> clone <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>svnrepo git1
<span style="color: #7a0874; font-weight: bold;">cd</span> git1
<span style="color: #666666; font-style: italic;"># observe there is a hi.txt and a .git directory. here</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot; World&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> hi.txt
<span style="color: #666666; font-style: italic;"># stage a change. </span>
<span style="color: #c20cb9; font-weight: bold;">git</span> add hi.txt
<span style="color: #666666; font-style: italic;"># now commit the change to your local git repository (i.e. your .git directory contains it)</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> commit <span style="color: #660033;">-m</span><span style="color: #ff0000;">&quot;say hi to the world&quot;</span>
<span style="color: #666666; font-style: italic;"># and finally push the local change back to svn</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> dcommit</pre></div></div>

<p>Now lets check on the svn side if it worked &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>svnwc
<span style="color: #c20cb9; font-weight: bold;">svn</span> up</pre></div></div>

<p>Yup, our change is there.</p>
<p>Now imagine a co-worker comes along, who wants to work on his own git repository: git2. To get started, he clones the existing git1 repository and right away makes some changes.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span>
<span style="color: #666666; font-style: italic;"># lets not use git svn and instead do a regular git clone, either way would be fine btw.</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git1 git2
<span style="color: #7a0874; font-weight: bold;">cd</span> git2
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'!'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> hi.txt
<span style="color: #c20cb9; font-weight: bold;">git</span> add hi.txt
<span style="color: #666666; font-style: italic;"># commit the change to the local git2 repository</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> commit <span style="color: #660033;">-m</span><span style="color: #ff0000;">&quot;finishing touch&quot;</span></pre></div></div>

<p>Back to git1, who is of course interested in the change made in git2:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git1
<span style="color: #666666; font-style: italic;"># add git2 as a remote. </span>
<span style="color: #c20cb9; font-weight: bold;">git</span> remote add git2 <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git2
<span style="color: #666666; font-style: italic;"># fetch tags and branches known on git2</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> fetch git2
<span style="color: #666666; font-style: italic;"># pull the change made on git2 into the master branch (on git1)</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> pull git2 master</pre></div></div>

<p>Git1 and Git2 now have the same change but it is not in svn yet. Git2 can&#8217;t commit to svn yet. So, lets fix that. Open /Users/jilles/test/git2/.git/config in an editor and append the following section:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>svn-remote <span style="color: #ff0000;">&quot;svn&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
        url = <span style="color: #c20cb9; font-weight: bold;">file</span>:<span style="color: #000000; font-weight: bold;">///</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>svnrepo
        fetch = :refs<span style="color: #000000; font-weight: bold;">/</span>remotes<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">git-svn</span></pre></div></div>

<p>Save the file and:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git2
<span style="color: #666666; font-style: italic;"># fetch the svn branch and tag information</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> fetch
<span style="color: #666666; font-style: italic;"># make sure we have all the latest changes on svn by &quot;rebasing&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> rebase
<span style="color: #666666; font-style: italic;"># now we are ready to dcommit the change we made in git2 back to svn</span>
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> dcommit</pre></div></div>

<p>Good, the change is now back in svn. Lets verify and modify some more in the svn world:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>svnwc
<span style="color: #666666; font-style: italic;"># get the latest changes from the svn repo</span>
<span style="color: #c20cb9; font-weight: bold;">svn</span> up
<span style="color: #666666; font-style: italic;"># fix the file once more ...</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'hello world!'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> hi.txt
<span style="color: #666666; font-style: italic;"># and commit it</span>
<span style="color: #c20cb9; font-weight: bold;">svn</span> commit <span style="color: #660033;">-m</span><span style="color: #ff0000;">&quot;stupid newlines&quot;</span></pre></div></div>

<p>And lets rebase git1 and git2 against svn:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git1
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> rebase
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>jilles<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>git2
<span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">svn</span> rebase</pre></div></div>

<p>Now git1, git2, and svn are in sync and have the same history. If you examine the history with git log on git1 and git2, you will notice that all the commits have the same hashes. This is no coincidence, commits have globally unique sha1 hashes that are based on their content. The same changes will yield the same hashes no matter where you make them. This is the reason git works so well. It doesn&#8217;t matter where the change came from, as long as the hashes line up, everything will be fine. </p>
<p>I&#8217;ve demonstrated that git1 and git2 can pull changes from each other and that you can rebase and dcommit against the central svn repository. You needn&#8217;t be afraid of double commits or lost commits. Git all sorts it out. From git&#8217;s point of view, a central svn is just another repository. Git is decentralized and throwing svn in the mix doesn&#8217;t make much of a difference. It just integrates more or less seamlessly. So, you and your git using co-workers can go off and do all the cool stuff git users do, while all staying in sync with the central svn repository.</p>
<p>Random things you probably want to play with next:</p>
<ul>
<li>git svn clone your svn repository; or git clone it from one of your git using colleagues and manually add the svn remote</li>
<li>use git daemon to set up a network daemon that your colleagues can pull changes from remotely</li>
<li>create a local branch and integrate changes from your colleagues there before merging back to your git master and dcommitting the change to svn</li>
<li>allow others to pull your experimental branch</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2010/10/04/git-svn-voodoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some reflections on a future of software engineering</title>
		<link>http://www.jillesvangurp.com/2010/09/09/some-reflections-on-a-future-of-software-engineering/</link>
		<comments>http://www.jillesvangurp.com/2010/09/09/some-reflections-on-a-future-of-software-engineering/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 07:02:47 +0000</pubDate>
		<dc:creator>Jilles</dc:creator>
				<category><![CDATA[Blog Posts]]></category>

		<guid isPermaLink="false">http://www.jillesvangurp.com/?p=759</guid>
		<description><![CDATA[Update. I accidentally published an early draft of this  long (for a blog post) article by clicking the wrong button in wordpress. If you read this early draft, the article is now in its finished form and I&#8217;ve added a &#8230; <a href="http://www.jillesvangurp.com/2010/09/09/some-reflections-on-a-future-of-software-engineering/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>. I accidentally published an early draft of this  long (for a blog post) article by clicking the wrong button in wordpress. If you read this early draft, the article is now in its finished form and I&#8217;ve added a couple of links, edited the earlier text, and added loads of links.</p>
<p>I have over the past year been a bit less active blogging and posting in forums. I make an exception on things related to build processes, distributed version management and Java and you may find a couple of fine rants on my website and across various blogs on this topic.</p>
<p>This post is intended to pull all of it together in a bit more grand vision and reflect a bit on what a post revolution software engineering world might look like. I don&#8217;t like or believe much in revolutions but I do recognize that getting from where we are to where I think we need to be amounts to one. The more likely outcome is an evolutionary development where the bits and pieces where I was not completely and utterly wrong might actually happen. At some point. Maybe.</p>
<p><span id="more-759"></span><strong>The Problem: Files<br />
</strong></p>
<p>Software engineering practice is stuck in abstractions and concepts dating back decades. Because it is stuck, it is not really moving forward as fast as it could be towards being more capable of dealing with scale in numbers of people, amount of software, and amount of evolutionary change per time unit. This annoys me and has done so for years. It is the main motivation for writing this article.</p>
<p>The core abstraction I strongly believe is very wrong is the <strong>file</strong>. A file is a binary or text blob that lives on a file system that has some name. It has some content of some type that is generally associated with a  suffix in the name (e.g. *.java).</p>
<p>Software engineers mistakenly believe their output consists of software artifacts that are stored as files. It doesn&#8217;t. Their output consists of software that happens to be stored in files. If you were born in the fifties, you&#8217;d be serializing your software from your head onto paper and manually flip switches to de-serialize. This was tedious but it worked. People like Ada Lovelace were writing software long before there were machines capable of even executing the software (other than the human brain, which is not very good at running our own software). The sixties made IO quite a bit easier with consoles, punch cards and tapes. People would transfer programs to and from RAM buffers by streaming them from tape or by feeding piles of cards to a computer. Somewhere in this era the notion of transforming these software data blobs using other software blobs also became popular: I&#8217;m talking about editors, compilers and interpreters. Finally somewhere in the seventies floppies and hard disks started to be used and everybody started putting their data blobs in files. Sadly this is where evolution stops.</p>
<p>At least when it comes to storing computer programs. For other types of data we have gotten a lot smarter. We have graph databases, object databases, tuple stores, relational databases, document stores, etc. None of these are commonly used to store computer programs.</p>
<p>This is weird and in my view it is holding software engineering practice back. A big reason is that we have built a huge sand castle of technology around the notion of files as the primary means of storing computer programs. For example we have version control systems that store different versions of files. We have built tools that consume and produce files. We have source code analyzers that expect to be working on files. We have IDEs that offer us convenient ways to edit files. Once we stop putting software in files, that technology needs to start changing as well.</p>
<p><strong>Smalltalk and Eclipse</strong></p>
<p>Actually it is not strictly true that evolution stopped with the file. Smalltalk and its descendants have a very interesting approach where the entire software system is stored in one big image file. Effectively smalltalk is using a database concept. This allowed for some interesting innovations, like meta programming and software transformations (aka refactoring) that require some readily available in memory representation of the software that is generally very rich and graph like (i.e. an abstract syntax tree) and can be introspected. Smalltalk developers realized that it didn&#8217;t make much sense to fragment bits and pieces of the software over multiple files. You might as well just use a single file.</p>
<p>This inspired IBM to create a nice IDE for Java at some point: Visual Age. Visual Age was very much a reborn small talk style IDE and crucially stored its Java code not in files but in the form of a database that effectively was a serialization of the abstract syntax tree of the entire software system. It needed that tree in order to be able to power important features like refactoring, code browsers, etc. Later it became Eclipse and they dropped the notion of storing the serialized AST opting instead for a combination of on the fly construction of an in memory AST, on the fly compilation and analysis, and reading to and from files the good old fashioned way.</p>
<p><strong>Failed experiment: intentional programming?</strong></p>
<p>Some late nineties papers by <a href="http://en.wikipedia.org/wiki/Charles_Simonyi">Charles Simonyi</a> on <a href="http://en.wikipedia.org/wiki/Intentional_programming">Intentional Programming</a> and persistent rumors about him actually being very close to launching related products was about taking the whole smalltalk/visual age thing to the next level. It&#8217;s too early to call this a failed experiment because Simonyi never really delivered the goods. His company (<a href="http://intentsoft.com/">Intentional Software</a>) is still hyping intentional programming but has yet to ship a product. Seriously, this has been in the making longer than Duke Nukem Forever. In a nutshell Simonyi&#8217;s very brilliant idea is that creating software is about coming up with abstractions that are represented in the form of abstract syntax trees that can be translated into other, more general abstractions in multiple iterations until you end up with a syntax tree that can simply be serialized to executable code. His core idea was to treat the transformations and not the abstractions as the first class entities. In a intentional programming world you start with really simple abstractions that you can translate into executable code and you build increasingly more complex and specialized abstractions that can be used for specialist or domain specific things. The traditional notion of compiling is very similar except it is a bit limited in the number of transformations and the abstractness of the abstractions involved. Basically most languages go to roughly 2 or 3 transformations: source code to abstract syntax tree to assembly to executable bits and bytes. There are lots of variations here but it is essentially a pipe line. Intentional software&#8217;s product works differently. The user manipulates the AST of whatever abstractions he&#8217;s working with in some rich editing environment that presents appropriate views on the AST and tools to edit the AST. Applicable transformations and optimizations kick in on the fly to keep the executable code up to date. It probably does a bit of serialization here and there but probably not in a format that is very notepad friendly.</p>
<p><strong>Another failed experiment: Model Driven Architecture (MDA)<br />
</strong></p>
<p>Readers of the previous may be tempted to sweep this in the same bucket as <a href="http://www.martinfowler.com/bliki/ModelDrivenArchitecture.html">Model Driven Architecture</a> (MDA). MDA was something that emerged out of the lovely world of UML. In MDA one defines systems using a standardized meta language, generally inside a dedicated tool (e.g. Rational Rose). The idea is on the surface very similar to intentional programming except it is more artifact centric. The weak spot of MDA has always been that the transformations from models to software is kind of a hacky process that is generally locked up in some proprietary tool. Basically there is the meta language and the UML language (of course defined in the meta language) and UML models. Where the whole thing becomes messy is the transformation to actual software. This bit is more or less completely proprietary and your mileage may vary though apparently some tools are quite good at this. Early MDA environments were monstrous tools with loads of J2EE, application server madness and a rich sauce of UML and XML spread on top. It&#8217;s sort of a lot of not so great things stuck together and people have wasted enormous amounts of cash on making sense of the whole thing, which continues to feed hordes of very expensive consultants. MDA never really dragged itself outside the domain of finance and banking applications.</p>
<p>There is a lot of hype currently around language benchmarks and similar technologies that is partly fueled by <a href="http://martinfowler.com/">Martin Fowler</a> who is about to <a href="http://martinfowler.com/books.html#dsl">publish a book</a> on this and other topics related to Domain Specific Languages. He also has several articles worth reading on his website on this topic.</p>
<p><strong>The point about ASTs</strong></p>
<p>The whole point about bringing up MDA and ASTs is that software is made out of abstractions. The serialization of abstractions to and from source code in e.g. C or Java is lossy in the sense that some of these abstractions are no longer explicit when the serialization is complete. For example you might have a nice program that implements the visitor pattern, which is an abstraction many OO programmers would understand. This might be obvious to the reader of the source code and it might have been documented in some comment but it is no longer explicit whereas when the developer had the design in his head, or on a white board, or possibly even in a UML diagram, it was explicit. Intentional programming and MDA are about giving developers the option to keep those abstractions around and to define their systems in terms of richer abstractions than are found in typical programming languages.</p>
<p><strong>The point about files</strong></p>
<p>A useful representation of the abstractions is the abstract syntax tree,  which is an internal data structure used by compilers, IDEs, source  code analyzers, etc. There are of course many interesting ways to serialize tree like data structures like ASTs. For example, XML is pretty popular (though not for its readability or editability). And of course source code is nothing more than the serialization of an AST that conforms to a particular grammar. The point about files however is that they are used as containers of abstractions. Generally you need multiple such containers to get a working system. They might be of different types even (your average J2EE architecture comes with dozens of them). Finally, the notion of a file as the boundary on a container of abstractions is rather arbitrary. In some languages you put a single class in a file. In others files are called modules and can contain multiple classes, functions, procedures, etc. Additionally files live in directories, which are containers of files. In many languages directories have semantics as well. For example Java uses nested directories that must match the package structure (which is also nested).</p>
<p>I&#8217;d argue that files and directories are poorly suited for modularizing your system. Also as a boundary of abstraction between modules, they are both too arbitrary and too coarse grained. For example when you consider versioning, you are stuck with files and directories even though many version systems don&#8217;t even have a first class representation for directories (git) or have trouble keeping track of name changes to files (cvs).</p>
<p><strong>Development is a collaborative process</strong></p>
<p>Development is essentially a collaborative process. Except for very small systems, most software needs to be developed together with other people that may even be spread all over the world in some cases. It is no surprise that there is a huge amount of technology available to facilitate collaborative development. I already touched on version control systems. In addition to that there are bug management systems; collaborative editors; source code review systems; tools to examine differences between files. If development is a collaborative process, why can&#8217;t we version, review, triage bugs, exchange, communicate, etc. via the internet. Why do I have to bother serializing and deserializing trees (aka. saving and opening) ASTs in order to do stuff?</p>
<p><strong>To the point &#8230;</strong></p>
<p>This brings me to the point, finally. Files don&#8217;t make sense at all in many ways, as I&#8217;ve argued so far. So, lets not use files then. Lets look at a possible alternative instead:</p>
<p>(Disclaimer: very likely some people have implemented bits and pieces of what I&#8217;m about to outline. I&#8217;m aware of this but still want to provide a bigger picture here.)</p>
<ul>
<li><strong>Cloud storage</strong>. Software is a data structure, not a file. Data structures should of course live somewhere. These days the appropriate place for data to live would be the cloud. By cloud I mean that programmers should be accessing their ASTs via tools that are connected to the network and that automatically sync back and forth. The tool could be browser based or it could be some native UI. It might even resemble a code editor.</li>
<li><strong>Versioning and other content management features</strong>. Versioning is not a feature that is limited to version control systems. For example, many content management systems do a decent job of versioning the objects they manage, which in the case of systems like Drupal are actually trees of objects. Versioning is just one of the many useful features you can find in content management systems. Others include auditing, security features, syndication of updates, workflows, etc. There is no reason why a cloud based software store should not have these features. In fact, they might prove to be highly useful. So, naturally our cloud based AST store should come with all these features.</li>
<li><strong>Collaborative editing</strong>. Collaborative text editors have been around forever but somehow never really caught on in the software world. Also browser based office tools like Google docs and the recently discontinued Google wave have some really interesting collaborative editing features. I still think Wave could have been a really nice eclipse replacement. Naturally we want collaborative editing tools for our cloud based ASTs.</li>
<li><strong>Offline &amp; synchronization</strong>. Being connected to the cloud is of course nice but sometimes people need to be offline (e.g. a plane) or there are disruptions in the network. In a cloud based world that could end up being highly disruptive for developers. However, there exist several good technical solutions. One of the trendy nosql solutions out there, <a href="http://couchdb.apache.org/">couchdb</a>, is all about storing stuff in a decentralized way and syncing over http. Ubuntu is essentially the worlds largest data store where each of its users has a private couchdb instance that (optionally) syncs with an Ubuntu provided central couchdb store. Yesterday a company called <a href="http://www.couch.io/">couchio</a> announced a couchdb based product, CoucheOne, that is specifically designed to address data synchronization on mobile phones. The point being here that even though software needs to live in the cloud, it should be possible to go offline and sync back to the cloud later.</li>
<li><strong>Integrated artifact generation and workflow management</strong>. Much of the development process follows pretty strict workflows that are commonly automated using continuous integration servers and build tools such as ant, rake, or maven. Most of the build tools are just trying to hide excessive amounts of pushing around of files, which we are trying to get rid off here. But the notion of automatically generating artifacts at various points in well defined work flows is of course something that is worthwhile keeping. Artifact generation could be plugin based or even similar to intentional programming style transformations.</li>
<li><strong>Distribution</strong>. When I say the cloud, I don&#8217;t mean that there should be some big monster repository of software. I&#8217;m thinking more of a REST style architecture of resources on the internet that are linked to each other. Also I like the notion of Git/Mercurial style distributed repositories of stuff. The cloud should very much be a distributed thing as opposed to some monolithic monstrous content management system.</li>
</ul>
<p><strong>What does all this mean in practical terms?</strong></p>
<p>Having everything in the cloud like outlined above allows for the elimination of a lot of cruft and overhead in the current software engineering practice. A few examples of activities that will work in a very different way:</p>
<ul>
<li><strong>Checking out code and committing changes</strong>. This is no longer needed. Since you are working with a cloud based system, all your edits go straight to the cloud. You might still want to annotate some milestones with a &#8220;commit message&#8221; of course.</li>
<li><strong>Branching and tagging</strong>. Everybody working on the same software sounds nice of course but sometimes you want to isolate changes on a branch or take a snapshot of a particular revision of the software. There&#8217;s no good reason why a cloud based system could not do this. Additionally, this removes the need for having local work copies that are &#8216;dirty&#8217; instead you could just save to a private branch.</li>
<li><strong>Changes</strong>. Like in git, the cloud stores chains of incremental changes to the AST (rather than to files).</li>
<li><strong>Merging</strong>. If you have branches, there will be the need to merge changes back and forth. Since we are now all cloud based, this no longer requires pushing around vast amounts of data. Instead since all branches are just chains of changes, the process could be very similar to what git does when merging and rebasing.</li>
<li><strong>Compilation</strong>. Compiling code is the process of generating artifacts from ASTs. Since the ASTs live in the cloud and compiling is just a special case of transforming one AST to another (see intentional programming), this should pretty much be an on the fly kind of thing where the right artifacts are simply generated on the fly when they are needed. This could be an intentional programming like extensible system, which would be really nice of course. However, a plain old compiler might do the trick as well for many.</li>
<li><strong>Running tests</strong>. Running tests is an essential part of the work flow in any decent software engineering practice. Since we now have a cloud based system with explicit support for common CMS features like work flows, it is probably a good idea for the cloud to automatically run tests at the appropriate moment in a work flow (e.g. when merging from one branch to another). Some developers already use elaborate continuous integration setups involving build servers, SCM triggers, cron jobs, etc. This just takes it to the next level.</li>
<li><strong>Dependencies and relations between different systems</strong>. Software does not exist in isolation but it depends on other software. In the conventional world, dependencies need to be managed and artifacts need to be dowloaded locally. A dependency is nothing more than a special case of a relation between two nodes in an AST. The cloud is full of relations. You might know them as URLs. So, in the cloud, a dependency is just a link. Relations like this may be dependencies but there may be many types of useful relations like for example, this class node here contains tests for that class there. Links are a much more powerful construct than textual references in some file.</li>
<li><strong>Sharing software</strong>. This one is easy: you send somebody a link. That&#8217;s it, we all connect to the same cloud. The rest is just credentials, access rights, etc.</li>
<li><strong>Releasing artifacts</strong>. Since the generation of artifacts (aka. compiling) is happening on the fly, a release is nothing but the act of publishing, which in turn is a step in a workflow. Probably you will want to release related artifacts such as change logs, documentation, upgrade guides as well. These of course also live in the cloud.</li>
<li><strong>Filing bugs</strong>. Bugs are just a special case of a particular artifact that can be represented as an AST. In other words, it can be part of the cloud and be accessed and managed in the same way. There is no need for integtation of legacy bug tracking systems. Having both code and issue tracking in the same cloud of course allows for some nice workflow enhancements. Think <a href="http://www.eclipse.org/mylyn/">Mylyn</a> style workflows.</li>
<li><strong>Writing documentation</strong>. Documentation is just another example of an artifact. That too can live in the cloud and leverage the ability to have links to and from the documentation and the documented artifact(s).</li>
</ul>
<p><strong>Conclusion</strong></p>
<p>This concludes what may seem like a pretty random collection of thoughts but is in fact something that has been brewing in my mind for about ten years in various forms.</p>
<p>In summary, what I&#8217;m trying to propose here is a cloud based system that has lots of fancy features like you would find in content management systems, collaborative editing tools, and can be used online and offline. For me this is not science fiction since all the bits and pieces exist already. It&#8217;s just that in the software tools used today we are stuck with nineteen seventies technology and elaborate workarounds to compensate for some of the bigger problems.</p>
<p>I believe that if properly implemented, this cloud based software development environment would be vastly superior to the loosely connected collection of tools, systems, and technologies that dominate the current practice. It would stimulate more effective collaboration, would vastly cut down on the tedious bureaucracy associated with software development (waiting for builds, checking out code, dealing with conflicts when synchronizing changes, etc.) and would lead to more productive development where developers are able to focus on the process of creation more than is the case now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jillesvangurp.com/2010/09/09/some-reflections-on-a-future-of-software-engineering/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

