What a year!

Usually, this time of year, it’s time for looking back on the past months and reflect on what has been accomplished. Last year I didn’t even bother because I was simply too depressed. I spent a couple of weeks isolated in a chalet in Canada, I needed to regroup, I needed to flip a switch. And boy I did!

One year later, so many things have changed in my life it is scary to think about it… though energizing.

One of the biggest decisions I made during my cold retreat was to finally tackle the pain I’ve been struggling with ever since I was a child. I had started my first diet when I was 3 and struggled with my weight ever since. For the past three years, I have been working on the roots of this disease, of this malicious relationship I had with food. But it was time to face it head on and do something concrete about it. In January, I had my first appointment with a nutritionist at the Brussels Weight Loss Center, and it was the beginning of a long but inspiring journey. I was too far off to just go on another diet, the only durable solution for me was surgery, so I did what had to be done… and told the story of it (in French). The surgery happened in early July, and I’m very pleased to report that I have already lost 55 kilograms over the past 6 months… and counting. The goal is to go back to 100 and get out of medical obesity, so things are on track.

When I took the decision to have the surgery, I knew I needed some financial and professional stability, both to prepare myself and to recover properly. I couldn’t afford to live the stressful entrepreneur life anymore. So I accepted a new consultancy mission for a big bank. Sure it wasn’t fully aligned with my values and goals in life, but it paid the bills nicely and allowed me to focus some attention on my health. I started working there in early April this year and I learned a lot. Then a few months ago, a Belgian friend of mine who had moved to San Francisco and joined a promising startup there told me they might soon need some help on their technical team. It was not an immediate need, but I started dreaming of settling in this city that I love. Then a couple weeks ago he got back to me. That was it, they needed someone now! My relocation plans had changed a little (I’ll tell you how) but I really wanted to join them. I talked to him, I talked to the CEO, I met the backend developer… and the deal was sealed in enthusiasm. So starting in January, I’m back in the startup world, but not with my own company. I’m a developer for Instaply and I’m thrilled about it.

Last (not really), but not least, I told you my relocation plans have changed in the past few weeks. Here’s why. When I took the decision to have gastric bypass surgery, it was thanks to a lot of online resources and especially testimonials from other patients who told their story in videos from a few months before to a few years after the procedure. It really helped me ease my concerns about the surgery, its consequences, its challenges and the overall journey that was ahead of me. Lucky for me I understand English without too much trouble. But then it struck me that very few French-speaking patients dared to talk about it, which allowed a lot of false ideas to spread, and the surgery to be somewhat shameful in the French-speaking world. So I took it upon myself to create my own Youtube channel, my own community, my own blog, with a triple goal in mind:

  • Inspire patients
  • Educate their family and friends
  • Inform the general public

But there was one side effect I didn’t anticipate: those videos allowed me to find my special someone. I thought that after I would get back my self esteem as the result of getting back in my own driver seat, I would have a crazy “catch up” period, having fun, meeting a lot of people, getting out and not taking things seriously. But as often in life, surprises are even better. She had the same surgery I did, she watched my videos, she called me to ask questions and share her experience with me, and we quickly noticed we shared much more than an obesity journey. I used to find this concept very overrated, but now I can tell you with full certainty that I found my soulmate. She is everything I had never hoped for, she makes me feel more alive than ever, she makes me enjoy every moment of life, here and now, like I never could, and believe me when I tell you that’s quite a feat. Things went incredibly fast between us, but it was just obvious, and being far away from her became so painful, that I took the decision to move back to France, near where she lives, and be happy there. Now of course this relationship and decision to move come with greater responsibility too, because she has two kids who are going to be part of my life too. But even though I’m fully aware of the challenges ahead of me, I’m not scared. It’s fair! And this move is fully compatible with me working remotely from home for Instaply, so everything is just perfect.

So… new body… new job… new girl… and kids. What did I forget? Oh yeah! Back in October we went to TechCrunch Disrupt in Berlin with the PeerTrust team. PeerTrust is this side project we had been working on for 18 months, trying to find a solution to this trust problem that made Kodesk (my first startup) fail. And PeerTrust failed to raise the enthusiasm that was necessary to keep us on track. So we decided to stop working on it. But on the other hand, it was obvious that we enjoyed working together very much, and none of us wanted to be a consultant for big companies our entire lives. That’s when it struck us: why not create our own agency, work for customers we chose, with our own tools and more importantly with our preferred team. Hence was born ZeTeam! I won’t go too much in detail about it yet, because things are still in their infancy, but suffice it to say that if you or someone you know is looking for innovative and pragmatic software solutions for their business, feel free to contact us or keep in touch. I’ll definitely keep you updated here in the coming weeks.

So there we go. 2013 is soon coming to an end. I’m on my way to enjoy the best holidays of my life, then 2 months between 2 jobs, finishing my mission for the bank and ramping up on my Instaply work, and then moving back to France with my sweetheart in March. Things are very exciting. So have a merry christmas, a happy new year, and don’t forget your destiny lies in your own hands. Be happy, and you will be even happier.

 

And you’re wondering why Europe sucks for innovative startups?

I’m experimenting with a new collaborative consumption business idea at the moment and I’m trying to set up a payment processing infrastructure. I contacted Paymill, the European clone of Stripe but they seem to be stalling on activating my merchant account. So I got in touch with Braintree Payments, since they opened their services for merchants in Europe last year and they are the payment provider of AirBnB, THE pioneer of collaborative consumption. But this morning, I got the following email:

We would love to have you as a business partner, but unfortunately we cannot move forward with your application. Your payment model is something called Third Party Payment Aggregation.  This means you are accepting payment on behalf of someone else, and then passing on payment to them at a later time. TPPA is the highest risk business model there is in payment processing. Unfortunately we do not have a European sponsoring bank willing to underwrite applications for companies with this payment model at the present time.

And they add a link to a post on their blog, explaining what TPPA is and why it is risky.

Now I understand the risk but then it got me thinking. Isn’t it a bank’s job to manage the risk and be paid for it? And what does it mean for the future of collaborative consumption in Europe? Given that collaborative consumption is on its way to replace ad-supported free services as the leading business model family, and that the go-to option for collaborative consumption revenue stream is commission on transactions, how can we do that without a bank supporting this model?

So the next step is to see how existing collaborative consumption businesses in Europe are doing. Let’s try first for 9flats, the European clone of AirBnB (they’re based in Germany). Unfortunately, their terms and conditions do indicate that they process the transactions themselves (“9flats undertakes to pay to the host as the purchase price for the receivable the amount of the accommodation price minus a commission (receivable price)”) but they don’t mention what payment processing service they’re using. Now let’s look at BlaBlaCar, one of the leading ride-sharing services in Europe. Here is what they say in article 2.3 of their Terms and Conditions: “it is the Driver’s responsibility to collect payment from the Passenger at the time of the Trip”. Woops! There seems to be a pattern of avoidance here. I posted a message on OuiShare‘s Facebook group and I got the reference of Leetchi. Going to their website, they say they are using Payline to process payments, which I had never heard about and will investigate (it seems they have the French subsidiary of BlaBlaCar as a customer too). But the smaller the operator, the less likely it is they will support modern API’s enabling mobile payments for example (which both Braintree and Paymill do).

This is going to be harder than I thought. But I guess the point of this post is this: if you are thinking of establishing a business in Europe whose business model relies on taking commissions on transactions, be prepared to fight… or flight! The US of A are so appealing to me right now…

Top 5 reasons why you should consider Groovy and Grails for your enterprise software architecture right now

I’m so amazed when I see how so few companies are using Groovy and Grails right now, and are still using old stuff like Spring and Hibernate, that I thought I would jump in and do my share of educating. And why not give in to the fashion of top lists while I’m at it? So here it goes: if you are an enterprise software architect and you have a lot of Java in your world, you might want to read carefully what follows.

Continue reading

Book publishing is dying? No kidding!

It’s been a while since I posted my last article here. But tonight I just can’t help it. For a few weeks I’ve been reading MongoDB in Action, from Manning, as an eBook on my iPad. And for a few days, since I started diving into the more complex parts of it, I’m struggling with errors all over the place. And I’m not just talking about typos here, I’m talking about massive errors that completely change the meaning of code samples and leave you wondering about your own sanity and stupidity. Here are a few examples coming from their Errata page:

Page 81, First code snippet

First off, how the hell am I supposed to match there erratas with my eBook? An eBook has no such pages, it depends on what you’re reading it on, the size of the font, etc. Now I know these erratas are designed for paper books originally. But these are technical books we’re talking about. How many technical people are still reading ink on dead trees around here?

Replace

category = db.categories.findOne({'slug': 'outdoors'})
siblings = db.categories.find({'parent_id': category['_id']})
products = db.products.find({'category_id': category['_id']}).
                            skip((page_number - 1) * 12).
                            limit(12).
                            sort({helpful_votes: -1})

with

category = db.categories.findOne({'slug': 'outdoors'})
siblings = db.categories.find({'parent_id': category['parent_id']})
products = db.products.find({'category_id': category['_id']}).
                            skip((page_number - 1) * 12).
                            limit(12).
                            sort({average_review: -1})

In the paragraph before this code sample, you can read that we’re looking for siblings of the current category, and then in the original code sample above, you see the code is looking for children, not siblings. So you start hitting your head agains the wall, reading the same sample over and over again, trying to make sense of it, and then you locate the errata and you see THIS!

But we’re not done yet, there’s more, there’s worse!

From the same errata page:

The line reading:

emit(shipping_month, {order_total: this.sub_total, items_total: 0});

should read:

emit(shipping_month, {order_total: this.sub_total, items_total: 0});

You can read it again… and again… no, there’s no difference between the original and the correction. It’s exactly the same fricking line! The worst part is that you can feel there’s something wrong with this line. It’s obvious that it seems odd to start a map-reduce with different starting points, but which one is the right one? Not so easy to figure out when you’re encountering your first map-reduce. So what, is there an errata page for the errata page somewhere?

But my favorite is definitely the next one:

The lines reading:

var tmpTotal = 0;
var tmpItems = 0;

tmpTotal += doc.order_total;
tmpItems += doc.items_total;

return ( {order_total: tmpTotal, items_total: tmpItems} );

should read:

var tmpTotal = 0;
var tmpItems = 0;

values.forEach(function(doc) {
  tmpTotal += doc.order_total;
  tmpItems += doc.items_total;
});

return ( {order_total: tmpTotal, items_total: tmpItems} );

Ah! So that’s where this “doc” variable comes from! How the hell could two entire lines be removed by mistake? And then I noticed something odd. The last line of what’s supposed to be the original is wrong. What I’m actually reading in my version of the book is:

return ( {total: tmpTotal, items: tmpItems} );

And not:

return ( {order_total: tmpTotal, items_total: tmpItems} );

So same question again… Errata for this errata?

So to sum it up: Manning is a technical editor, they publish technical books for technical readers. They release draft versions in advance for the community to review them on the cheap. Then they sell you eBooks for 30$ a pop, the final version is still littered with massive errors. And then they can’t figure out how to patch your book so they write an errata page that is simply unusable because A- you can’t match page numbers with an eBook and B- the errata page itself is full of errors.

And they wonder why their industry is on the decline? Seriously? I’ll tell you what, next time I’ll save a few tens of bucks and I’ll find “another source”…

And in the meantime, I just found out about Sigil. So I’ll see if I can patch the book and republish it, just as a provocation.

Why I switched back from Heroku to CloudBees

I used to have several grails applications deployed on CloudBees. I liked the fact that they were Java all along, I liked the smooth integration between Jenkins CI and the deployment environment. I really liked the fact that you could hide an application behind a username and password during testing. I just hated their design (seriously guys, hire a good designer) and I was not thrilled by their catalog of third-party services. So when Heroku announced that they supported Java applications, and then Grails applications, it was not long before I migrated all my apps over to their servers.

But more recently, I’ve had issues with a more plugin-rich application. And tonight, after several weeks of fighting, I migrated this app to CloudBees for one general reason: Heroku was really designed with RoR in mind, and even though they made a new stack for java apps, the old rules still apply:

  • if an application takes more than 60 seconds to boot, it is crashed. There is no way to adjust this timeout, and we all know that it can be pretty common for a java app to take a little more than that.
  • another consequence of this slow boot intolerance is that an application is automatically put in sleep mode after several minutes of not being used. Consequence: when someone comes to the site after such a period, say, in the morning, the app is rebooted out of sleep mode… and sometimes it crashes again. Terrible for availability. And apparently, even if you pay, there is no way to prevent that sleep behavior and to keep your app alive all the time. Actually to be fair, there is a way to disable idling: once you scale up to 2 dynos, idling is disabled.
  • since your app can be sleeping, implementing long-running background processes is very complicated too. You have to use their worker processes, but there is no documentation on how to do that in a java application, let alone in a grails app.
  • last but not least, even though I tried to limit the amount of memory of my app, it kept going over 512MB, which is the absolute limit. Once again no way to change that. It doesn’t crash my app, but it clutters my log with plenty of annoying warning messages.

That plus the fact that they refused to answer my last support request about memory consumption and marked it as solved when it got hard. The fact that they don’t have an easy continuous integration feature was not a deal breaker, but it adds to the rest.

Now I don’t know if CloudBees will be better on all these points, but it looks good on paper. Unfortunately, we java devs don’t have a lot of choice when it comes to cloud deployment. CloudFoundry is way too low-level, AppFog is still in private beta, and Amazon Elastic Beanstalk is awful for deployment (40MB take a long time to upload). What other options do we have that I’ve never heard of?

 

New Adventures

It’s been a while since I posted my last article on this blog, but what is really weird is that I have not mentioned yet what has been bothering my days and nights for the past 8 months.

In January this year, the first Startup Weekend was organized in Betagroup Coworking, Brussels. At first I didn’t want to attend, because I thought it was silly to hope you could do anything meaningful in merely 2 days. But Leo insisted, and 2 days before the event, I finally made up my mind. I was working on HuddleKit back then but I wanted to propose a simple idea for the event, something powerful and effective enough to be quick to implement. I had discovered AirBnB a few weeks before, and the whole collaborative consumption trend with it. Around a lunch at Vivansa‘s HQ, Said started thinking out loud about how difficult it was for small companies to adapt their office size as they grow, and how companies could mutualize their office space. We started dreaming about what a concept like AirBnB’s would mean applied to office space, how it could enrich business relationships. And then it struck me: 2 years ago, I published a post entitled “Let’s Solve Problems“, that ended like this.

Now I don’t know how or when, but this could very well become a major breakthrough in my personal and professional life somehow.

Well, guess what. The same day, I registered kodesk.com, and four days later, Kodesk won the grand prize of the jury and the leanest startup prize of the first Startup Weekend Brussels. After that, it was pretty obvious to me: I stopped working on HuddleKit and all my other pet projects, I progressively decreased my involvement with Vivansa and I started working almost full-time on Kodesk. In May this year, Frederic joined me in this adventure and we invested our own money in it. In late May, we released the first version of Kodesk and let’s just say that beyond visibility and publicity, the first results are not all as satisfactory as we expected. Now I’m certainly not complaining: we know that we are on the right track, our vision is crystal clear, we have a lot of support and it’s very rare for startups to get it right the first time. It’s even more rare for ventures that try to change common beliefs and evolve an entire culture.

But today it becomes obvious that building the right product and finding a profitable business model is going to take some time. And until we do, it’s going to be very hard to raise any external investment. Now we don’t want this financial constraint to remove all the fun from the adventure of creating our dream business from scratch, so today I am making a new move.

I love technology. I’m a geek and I am proud of it. My friends find it very useful and my passion for technology has allowed me to develop quite a reputation. Now it is time to earn some money with this passion and reputation, and to use that money to fund this groundbreaking business I’m building. So starting today, I am going to provide businesses of all sizes with three main services: technology watch, training and iPhone/iPad development, because those are the three things I love the most and I am really good at.  If you want more information, I created this page to promote my services. And if you know any company or individual who could be interested in my services, please feel free to pass my information along.

Grails, Vaadin and Spring Security Core

I got kind of bored with Flex and all the complexity it introduces by forcing you to switch between ActionScript and whatever you are using for the backend (Groovy in my case). I also got bored with having to regenerate my data service stubs on each server-side change, and having to handle the asynchronous remoting. So I started to have a look at Vaadin.

Vaadin offers the same richness of components as Flex, but I can code my UI with Groovy and it completely removes the need to bother about remoting and all that stuff. It’s really like my old Swing days and I love it.

Last week-end, I tried their AddressBook tutorial, and I adapted it to Grails using the Grails-Vaadin plugin. Then I modified the sample so that it uses GORM to store contacts. And finally I installed spring-security-core plugin to secure my business services with @Secured annotations. And it worked absolutely great.

I just released a new version of the Grails-Vaadin plugin with Vaadin upgraded to 6.5.1 (the latest version at this point), and I uploaded my version of addressbook to GitHub.

For me, the most interesting part is how I got security to work. All I had to do was to install spring-security-core plugin into grails and then define a simple SecurityService like the following:

package org.epseelon.addressbook.business

import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken

class SecurityService {

static transactional = true

def springSecurityService
def authenticationManager

void signIn(String username, String password) {
try {
def authentication = new UsernamePasswordAuthenticationToken(username, password)
SCH.context.authentication = authenticationManager.authenticate(authentication)
} catch (BadCredentialsException e) {
throw new SecurityException("Invalid username/password")
}
}

void signOut(){
SCH.context.authentication = null
}

boolean isSignedIn(){
return springSecurityService.isLoggedIn()
}
}

Then I injected this SecurityService into my AddressBookApplication and used it:

class AddressBookApplication extends Application {
private SecurityService security = (SecurityService)getBean(SecurityService)

[...]

boolean login(String username, String password) {
try {
security.signIn(username, password)
refreshToolbar()
return true
} catch (SecurityServiceException e) {
getMainWindow().showNotification(e.message, Notification.TYPE_ERROR_MESSAGE);
return false
}
}
}

Then whenever I try to call a @Secured method:

package org.epseelon.addressbook.business

import org.epseelon.addressbook.dto.PersonListItem
import org.epseelon.addressbook.domain.Person
import grails.plugins.springsecurity.Secured

class PersonService {

static transactional = true

[...]

@Secured(["ROLE_USER"])
PersonListItem updatePerson(PersonListItem item) {
Person p = Person.get(item.id)
if(p){
p.firstName = item.firstName
p.lastName = item.lastName
p.email = item.email
p.phoneNumber = item.phoneNumber
p.streetAddress = item.streetAddress
p.postalCode = item.postalCode
p.city = item.city
p.save()

return new PersonListItem(
firstName: p.firstName,
lastName: p.lastName,
email: p.email,
phoneNumber: p.phoneNumber,
streetAddress: p.streetAddress,
postalCode: p.postalCode,
city: p.city
)
}
return null
}
}

If I’m not logged in as a user, I get an “access denied” exception:

package org.epseelon.addressbook.presentation.data

import com.vaadin.data.util.BeanItemContainer
import org.epseelon.addressbook.dto.PersonListItem
import org.epseelon.addressbook.business.PersonService
import com.vaadin.data.util.BeanItem
import com.vaadin.ui.Window.Notification
import org.epseelon.addressbook.presentation.AddressBookApplication

/**
*
* @author sarbogast
* @version 19/02/11, 11:12
*/
class PersonContainer extends BeanItemContainer<PersonListItem> implements Serializable {
[...]
boolean updateItem(Object itemId) {
try {
personService.updatePerson((PersonListItem) itemId)
return true
} catch (Exception e) {
AddressBookApplication.application.getMainWindow().showNotification(
e.message,
Notification.TYPE_ERROR_MESSAGE
);
return false
}
}
}

To see what it looks like, all you have to do is to download the code from GitHub, and run “grails run-app” at the root of it.
If you try to create a new contact of edit an existing one and save it without being logged in, you get an “access denied” message. But if you login as ramon/password, it works.

Note that this project uses Grails 1.3.6 but the plugin supports any version of Grails above 3.2 included. As always, your feedback is more than welcome.