Nov 21, 2008

Benefits of working from home - Part IX- Infrastructure

In this post I described how using my computer in my home office was the first time that I'm getting a direct return on my investment.

In this post I'll take a look in the other side of the coin: the investment in infrastructure.

When my home computer used to be only that, i.e, my home computer, I had no hard requirements to keep it up to date. I could simply update it each 5 years or more if I wanted to; also, my internet connection need not to be very fast; the same applies for my desk; it could be very ordinary as I didn't spent a lot of time in my computer.

Of course, being a computer/programmer addicted as I am, shortened my computer's update cycle for something between 2 ~ 3 years, and 

internet connection, you know: you never get enough bandwidth ;)

By the other hand, using my computer to work pushes it to its limits... and of course, each minute I spend looking at the hour glass represents a minute less with my family (or my Wii :) so I want to wait the lesser amount of time possible in front of it.

Just to put some numbers, the first time I run db4o build on my machine it took more or less 1 hour to run to completion (mostly running tests). I just couldn't believe that. My machine was not a top one but it was not so old/slow either. After a lot of tweaking I managed to get the build running in 15 minutes but that required some $$$ (nowadays, even with a new machine tests take 20 ~ 25 minutes to run due to lots of new tests).

Also, I never considered (or had the requirement to) run 2 VMs, 2 Visual Studio (one in one VM and another in the host OS), Eclipse and some other apps at the same time. So now, 2Gb of memory doesn't look that much anymore.

Another important aspect that will have great impact on your productivity/health is the
overall quality of your office furniture: remember when you used to complain about your boss not willing to spend a few extra dollars on a good chair for you? I certainly remember myself complaining with mine :( Of course you don't need to go out and get the best chair in the world, but make sure you'll not get a "not so good" one only to save a few extra bucks either (If you are going to spend more than 4 hours seated I do recommend you to get a very good one - for instance, this one).

Well, that's not the end yet; telecommuting meant also that I became my own IT department ;). Not that I have any problem fixing my computer, installing software or whatsoever; the really big point is that all these maintenance work takes time (and time is money) and also that the burden to keep everything working is on me (to be fair, I'd rather be the one in charge for this task than to let someone else doing it

Last, but not least, consider having "hardware" backup; I mean, what are you going to do if next morning when you turn your computer on it don't actually turns on? Of course you do have backups of your important data (don't you?), but what about your hardware? How long it will take to be fixed? Are you willing to spend time on fixing it? Or do you have another computer that can be used so you can continue to work while someone else fixes it for you.

In the end of the day, you'll need to put some money on your office / infrastructure, so don't forget to take this into account.

That's it.

Bear with me ! We are approaching the end :)

See you


Nov 17, 2008

Changes in Db4o configuration.....


If you take a look in our svn repository you'll see that lots of changes were applied to configuration code (starting with version 7.7). Take it easy, we kept the "old" configuration interface in place; we just deprecated it, so update your code to use the new interfaces if you have the chance ;)

In this post I'd like to discuss some of these changes.

New, specific, factory classes

Do you remember Db4oFactory OpenFile(), OpenServer() and OpenClient() methods? We decided to move them to more specific factory classes:
  • Db4oClientServer
  • Db4oEmbedded
This way the boilerplate code used to open an embedded database changed from:

IObjectContainer db = Db4oFactory.OpenFile("MyData.odb");


IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), "MyData.odb");

As an additional benefit now we use the same class in both platforms (Java/.Net) (Remember, we used to have Db4o.openXXXX() for Java and  Db4oFactory.OpenXXX()for .Net).

Configuration interface split in File / Network / Common

We are applying Interface Segregation principle to configuration, so, now related configuration options are close together in specific interfaces.

For instance, all embedded related configuration lives in IEmbeddedConfiguration. But we didn't stopped there. We went a step further and broke common functionality in more coarse grained interfaces. For instance, there are configurations that do apply to both embedded and client server modes. So we introduced the concept of Configuration Providers which sole purpose is to help to aggregate configuration into specific interfaces, so it's easier (at least in our opinion :) to identify which configuration applies to each db4o mode and also make it more clear which aspect of db4o are being affected by that configuration.For instance:

IEmbeddedConfig config = Db4oEnbedded.NewConfiguration();
config.File.ReadOnly = true;

In this sample there's no space for doubts that ReadOnly configuration relates to a file system aspect of an embedded database.

That said, we basically partitioned configuration into four categories:
  • Embedded
  • Server
  • Client
  • Common

No more "default" configuration;

Suppose your application, at some point, requires a Db4o database with an activation depth configured to the highest possible value (in most scenarios this is not recommended) so you use some code like this:

IConfiguration globalConfig = Db4oFactory.Configure();

using(IObjectContainer db = Db4oFactory.OpenFile("test.yap"))
/* Use the database */

So far, so good. Now, in a completely different point in your application you need to open another Db4o database and so you just type:

using(IObjectContainer anotherDb = Db4oFactory.OpenFile("test1.yap"))
/* Use the database */

This new database ends up configured to fully activate objects! Even knowing that you should avoid configuring activation depth this way (you did your homework, right?) it's possible to do it by accident.

The problem is that it is relatively easy to mess with configuration.

That's the reason that now, all OpenXXXX() methods (in the new factories) requires a configuration to be passed through!

We are considering reintroducing the original signature methods but with different semantics; instead of return a clone of the global configuration we can return a fresh configuration object populated with default values so developers can be sure about what configuration they get!

To wrap up the session on configuration I'd like to present a short "cheat sheet":

Emdedded Old
Db4oFactory.OpenServer("dbfile", port);

ExceptionsOnNotStorable is turned on by default

That's (IMHO) really nice. I don't like to just pretend that classes are storable on Db4o and let customers struggling trying to figure out why their applications doesn't work when we could follow fail fast principles and let they know that one or more classes may have problems as it is.

Use of properties in .Net

That's mean more natural code style for .Net developers :). Now, instead of saying:


you will write:

config.OutStream = Console.Out;

We are aware that there other places where using properties instead of methods (or even using a different approach) would make more sense (on .Net of course) but we just don't have the time to improve them now. But you may be sure we'll do our best to keep improving both .Net/Java developers experience.

That's it!

See you.

Nov 5, 2008

Are you a C# developer?

If so, you should go and grab a copy (for free) of CodeRush Xpress for Visual Studio!

(I already own a copy of another addin, but I'll give it a try anyway :)


Nov 2, 2008

PDC 2008 Videos - For free!! :)


Are you a Windows developer? Or simple a Windows enthusiast? So you probably is aware of Microsoft PDC 2008. 

I'd love attend it but I couldn't  :(

At least we can grab (all?) Microsoft PDC 2008 Videos.

Have fun!


Benefits of working from home - Part VII - Alone in the office

With this post I'll stop talking about the advantages of working from home and start to discuss some of the drawbacks related to this way of work.

(sorry for the subject, I just couldn't resist :)

Note that some points that I first took as an advantage may appear again, but this time, with a focus on possible disadvantages; this doesn't mean I've changed my mind (what I would say is perfectly normal); its just
the other side of the same coin.

I'll start with the most problematic one (at least in my case), working from home meant to loose almost all contact with my friends and coworkers. I remember it perfectly when I was being interviewed (through skype) and I was asked how I felt about working alone, 8 hours per day; honestly, at that moment I did think it would not be an issue, but sometimes it is a little bit lonely.

Since I was not bound to an office anymore, after 4 months we (I and my wife) decided that the time to move to a quieter, safer, less violent place had come, so we moved from São Paulo to Londrina; you see, most of my friends still live in São Paulo and even having some (good) old friends (and my wife's parent) here in Londrina I somewhat miss personal contact.

Another important aspect of working from home is that all discussions (at least in my case) are done through some IM software (be it skype/msn/etc) and this is considerably harder to do than when you are engaged in a face-to-face talking.

It's enough for the first "not so good" series... let me play a little bit of "Star Wars" on my Wii ;)

See you.


Oct 30, 2008

Benefits of working from home - VI - Mange my time


Have you ever needed to ask (embarrassed) your boss to let you leave early so you could go to the doctor or to address some personal issue?

Well, not have to do this is another benefit of working from home :) as (usually) you are in charge of managing your own time!

Of course this is not an "all or nothing situation". Even when I had a "traditional" job my bosses were kind (or intelligent) enough (I bet they were both :) to let me deal with my personal issues during my working time if that were necessary.

My point is that nowadays all I have to do is to get organized so I don't miss any meeting, pair session and/or a dead line and everything is fine :). It's even better as I can choose the best time (a time in which I'll get less traffic, that is not to hot, etc.) to do my personal stuff.

Thats it! Even though being far from a comprehensive list of the advantages of working from home, I finally reached the last (but not least) advantage I wanted to blog about. In the next posts I'll talk about some drawbacks.

Do you have any other advantages in mind? Please, share with us!



PDC Talk: The future of C#


A very interesting PDC talk (by Anders Hejlsberg) about the future of C#.

As a teaser, just some subjects covered in the this talk:

  • More dynamic constructs
  • Optional / Named arguments
  • Concurrency
If you work with C#/.Net you can't miss this one!


Oct 22, 2008

Never give up

At least this seems to be the main approach of hackers.

In the last couple weeks I received at least 7 messages from the same sender, with the exact same contents:

It's in portuguese (at least) and says something like: "Hey dude, here are the photos!".

What photos? I don't remember asking any friend called "gabriel" to send me any photo ;) even more with supposedly annexed photos linked to files like "" on a very suspicious server (at least the guy wrote my name correctly)! No thanks !!!

In this same time range I got other "phishing" emails like:

Another email in Portuguese, pretending to be from hotmail trying to foolish me to get in panic and click on a link. 

This one (also in portuguese) is supposedly a "Virtual Card" from a girl named "Carla". It even includes a "copyright" notice in the end of the email.

Well, maybe may mommy would be tempted to clink on these links but not me. Anyway, this kind of threat is getting more sophisticated as time passes so pay attention where you put your mouse :).



Oct 21, 2008

Oct 17, 2008

Benefits of working from home - Part V - Show me the money


I've always the feeling that my investment in computer hardware/software was somewhat a waste of money; you see, usually I get a pretty descent machine and stick with it for at least 3 years; so every 3 years I spend a lot of money to get a new one and I didn't get a direct return from my investment (not to mention that most of the day it keeps turned off), and to be fair, I should take internet connection fees into account.

Since I started working from home I may say that this is the first time I am getting a direct¹ (and measurable) return from this investment. It's even better, now it's easier to justify new hardware, software and other gadgets to the financial department, i.e, my wife :).

In other words, now my computer generates income and I feel compelled to invest more money to keep it up to date.


¹ I mean, direct, because I always studied a lot in my home computers so, at least indirectly, they always gave me a financial return (even tough it is hard to measure how much return I got).

Oct 15, 2008

Running Sharpen tests faster...

As you probably already know :), Sharpen is a tool (developed by db4o) that aims at easing development efforts by translating java source code into C#. This tools make it easier to provide native solutions in either Java/.Net platforms.

While talking about how to run Sharpen test suite in this post I told that I'd show how to improve these tests startup time.

After a long wait, here it is. So let's go.

If you tried to run Sharpen tests you probably noticed that whenever you launch them a new Eclipse instance starts also (with it's full GUI) and this is one of the culprits for these tests to take longer than necessary to run. The good news is that it's (relatively) easy to configure Eclipse to not display any GUI at all (since all feedback will be given through the main Eclipse window).

To do this, once you checkout all required projects from db4o SVN, just Right Click sharpen.ui.tests project and select Run As / Run Configurations menu.
Now, in "Run Configuration" dialog,  right click on "JUnit Plug-in Test" and select New.

If you followed the previous steps, "Run all tests ...." should contain the right value (sharpen.ui.tests). Just make sure that you have the latest JUnit selected on "Test Runner" dropdown.

We are almost there... :)

The next step is to click on "Main" tab (1), then select "Run as Application" checkbox and select "[No Application] - Headless mode" in the dropdown (2) and finally, click "Run" button (3).

That's it :)

Notice that now sharpen test suite starts faster.

Many thanks to a great friend (Rodrigo) for sharing this information with me.

See you.

Oct 13, 2008

Benefits of working from home - Part IV - DIY


How many times a developer approached you to ask something he/she could have
easily find by himself have he/she bothered to spend 10 minutes to do a google search?

And let's be fair, how many times you feel compelled to do the same? I have to confess that even being a firm believer of
"search before asking" principle, sometimes I do find myself doing the opposite: asking before looking for information.

And this lead us to this post subject: Working from home gave me more incentive to do "the right thing" :), i.e, to look for solutions prior to asking the guy next to me - after all there's no such thing as the "guy next to me" :)

At db4o we do exchange lots of information/knowledge but since we are not at the same room (and in most cases we are at different timezones also) it's more practical to do a quick search and try to fix/solve issues by myself. Only after spending some time in my own research I think about asking the gurus.

This attitude (searching before asking) leads to a better understanding of the subject and other developers will not be interrupted to explain. Of course (IMHO) there are times (and subjects) that requires someone with more knowledge to guide other developers.

Anyway, I do believe that the process of explaining some subject may help you to get more insight about it and I do appreciate helping other teammates to improve their knowledge (Nowadays I'm learning more than helping :).

What do you think?


Oct 11, 2008

Benefits of working from home - Part VIII - Working Time

One really great advantage (IMHO) of "traditional work style" is that usually you have very clear separation between work time/free time. Basically your working day finishes as soon as you get out of the office (ok, I known, in development, many times the solutions come to our heads at home :).

Working from home is a very different experience and you can find yourself working a lot more than you'd expect/are willing to :(. The problem (again, IMHO) is that it's hard to separate the matters; you see, the work is there, you are there, and the rest you can guess.

Of course other factors like your productivity, how your manager and you decide on what to do and how long it is expected to last, etc. also plays an important role and can turn your working experience more pleasant or more like a nightmare.

In my specific case, I participate in deciding which tasks I'll be working on every week so I am the only one to be blamed when my working days extends a little bit.

And theres an aggravating factor: I am kinda addicted to computers/programming and sometimes I get so excited to see the outcome of my code that I can't just stop :)

So if you are going to work from home, pay attention to these pretty common pitfalls to avoid getting trapped into them.

See you.


Oct 7, 2008

Benefits of working from home - Part III - Time efficiency

In my last post I was talking about not being required to commute to work and I pointed some related benefits.

Today, I'm going to talk about some more benefits (directly related to the previous one), so let's go.

As I explained in the previous post I used to spend 2 hours in traffic; well, since I started working from my home this was not an issue any more and not wasting my time on traffic jams made it possible to do other things (like sleep more, post more frequently, etc. :) and spend less money with gas, but (IMHO), more important than all, it made it possible to spend more time with my family.

Prior to joining db4o, I used to wake up at 7:00, take a short breakfast and drive to my work so I rarely joined my wife/daughter at breakfast. At lunch time I was not with them again (since it would take me 1 hour to go to home and another one to get back).

Now, even though I usually wake up at the same time, instead of having a (lonely) fast breakfast and going to my work I just go down to my office and start working (usually I put may email/web reading up to date) then 1 hour latter my daughter wakes up and we (I, my wife and my daughter) can have breakfast together. Them, at lunch time, we can have lunch together again :)

Pretty nice!

At the end of the day when my daughter returns from school I'm finishing my working day and we can spend a little more time together.

Well, as an interesting tv ad says:

Have a good breakfast: U$ 20,00; getting out to have a good meal: U$ 50,00; to be with your beloved ones at these moments: has no price! :)
See you!


Oct 5, 2008

Back to Vista x64


Some time ago (sometime around 10/2006) I installed Windows Vista (a release candidate at that time) on my home machine in order to "try" it (to be sincere I've installed various Vista beta/release candidates).

Performance was not impressive but since I'm a software developer (and I didn't used the machine to work anyway) I decided that it worths to be able to experiment with new API / functionality so I kept it.

Some time after that it was released so I got a copy and installed in the same machine.

On 10/2007 I joined db4o and started to work from my home which means that my machine now plays an important role in my development productivity and I decided that I'd rather go with Windows XP (x86 or 32 bits) again (due to the performance impacts I got with Vista x64).

Well, one year passed and I got a new machine (a pretty fast one, lets say) and so I decided to give Vista x64 a try again.

In the first days I do got some BSODs (which made me feel frustrated) but after spending some time searching I found some suggestions regarding memory configurations; after applying such changes (I just set the times after memory manufacturer specifications and increased memory voltage by 0,1 volts) it became stable (no BSOD since them). 

I can say that I'm satisfied up to now; no hardware or software conflicts, performance is pretty good (much faster than my previous machine running Windows XP - I know, XP would run even faster on this machine).

See you.


Oct 3, 2008

Benefits of working from home - Part II : No need to commute

In the previous post I just said I'd think aloud about advantages/drawbacks of working from home.

Let's take the half-full approach and present the advantages first starting with not needing to commute.

Well, before joining db4o I used to live in São Paulo - Brazil, so this point is pretty easy one ;)

Anyone that knows just a little bit about São Paulo knows that it has a very bad traffic! Usually, in the days that the traffic was not that bad, it used to took me no less than 1 hour from my house to my work place (and I was fortunate enough to not live that far from my job). So 2 hours of my life was spent in a car every

Also, not being required to commute (and so avoiding traffic jams) made my expenses with car maintenance
drop a little bit and getting involved in a car crash less likely.

As a bonus of not commuting I don't have to find a place to park in a, usually, crowed place :)

So, IMHO this is a huge advantage.

The next post will be closely related to this one but I'll talk about my working time.

PS: Do you work from home? What are your opinion about the subject?

See you!


Oct 1, 2008

Benefits of working from home - Part I - The dream job

As I posted here, some time ago (to be more precise, exactly one year ago) I joined db4o and started to work from my home; that was not an easy decision/move but (thanks God and some really good friends also) I took it.

Since one year has passed, I think it is a good time to review this journey and rethink whenever its paying off or not.

In the next posts I'll discuss (shortly) some advantages and some shortcomings (from my point of view, of course :) regarding working from home. The order in which these topics are presented has no particular meaning.

Keep in mind that my opinion is largely influenced by the place I live in, the environment I am inserted into and the kind of work I am involved with, so, what I see as an disadvantage you may well see as an advantage :). Don't worry, we are not supposed to agree on everything.

Another important point is that some teleworkers (as people that work from home are called) usually do work "part time" in a real office; that's not my case; I am working 100% of the time from my home and the nearest fellow is at least 100 Km (and the others are 1000 Km) away.

To start with, here are a couple of interesting articles to read.

Hope you find this information useful/fun :)

See you.


[edit: added link to following posts]

  1. This post
  2. No need to commute
  3. Time Efficiency
  4. DIY
  5. Show me the money
  6. Manage your own time
  7. Alone in the office
  8. Working Time
  9. Infrastructure
  10. Epilogue

Sep 10, 2008

Here we come again :) - Part III - The end

Well, after some time researching and comparing prices I've ordered my new toy with the following configuration :
MotherboardGIGABYTE GA-EP45-DS3R
ProcessorINTEL Core 2 Quad Q3300 2.66GHz 12MB 1.333MHz
Memoty8 Gb - OCZ DDR2 800
CoolerCooler Master Vortex
Power550W - Corsair
KeyboardMicrosoft Wireless Desktop 2000
Video CardGeforce XFX 9600GSO 384MB
HD750GB Samsung
I do hope that this machine can keep up with my needs ;) Also, I ordered a really big
(at least for my standards) monitor .... Now I need to wait more or less one week to put my hands on this and starting installing (probably Windows Vista x64 and some Linux x64 distro also). OMG, I am to anxious! Adriano

Aug 11, 2008

Extracting files from a MSI file.

Today I was looking for a way to extract files from a msi installation package when I found a blog just explaining how to do it:

msiexec /a filepath to MSI file /qb TARGETDIR=filepath to target folder
Despite the original blog title it does work with XP :) Adriano

Aug 4, 2008

Here we come again :) - Part II

Just a little bit more information on my new toy (the one I am planning to get)
MotherboardGIGABYTE GA-EP45-DS3R
ProcessorINTEL Core 2 Quad Q9450 2.66GHz 12MB 1.333MHz
Memoty8 Gb - G.SKILL DDR2 800
CoolerARCTIC COOLING Freezer 7 Pro
Power550W - Seventeam
KeyboardMicrosoft Wireless Desktop 2000 Optico
Video CardGeforce XFX 8600GT 256MB
Even not being the fastest possible configuration it is a pretty good one :) Why did I need such a beast: Well, working as a software developer sometimes I find myself running Eclipse, Visual Studio as well a guest OS within Virtualbox (running VS and some other programs there also ;). So I do believe (I'm not a expert in hardware) that a 4 core processor will be helpful; in the same way, 8 GB of memory doesn't seem that much :) I considered to get a WD Raptor but it's too expansive here; also, I'll install 2 other HDs (that are sitting in my current machine) so I'll get some performance gains due to a more distributed load. Do you have a raid 0 configuration? How does it perform? Is it reliable?
Right now I am considering to build a Raid 0 array also but I'm not sure. My past experience wih Raid 0 was not so good. Adriano

Aug 1, 2008

Here we come again :)

For some time now, my computer started to give me signs that its time is coming. It's a pity since it is only 2 years old and has a not so bad configuration. For me, it's always a dichotomy between a pain and a pleasure when I need to figure out a new configuration. Should I go for a brand computer or should I build it myself? Should I by the latest/fastest/expansive(est) :) processor/memory/whatever (in a useless try to protect my investment) or should I stick to more affordable parts? Please, keep in mind that I live in Brasil and here computers are not so cheap as in some other places. Anyway, just for fun, I am dumping all my previous computer's configuration along side my wishes for the new one:
Year Processor Freq. # Core RAM Hard Disk Graphics Card Internet
1989 6502 0,75 Mhz 1 256 Kb NA OnBoard NA
1992 Ciryx 486 DLC 40 Mhz 1 4 Mb 100 Mb Trident NA
1996 Pentium 100 100 Mhz 1 16 Mb 1.0 Gb ? 28 Kbps
1999 Athlon 400 400 Mhz 1 128 Mb 30 Gb 4 Mb 56 Kbps
2002 Athlon XP 2.1 1.8 Ghz 1 512 Mb 60 Gb AGP 64Mb 350 Kbps
2006 Athlon 64 3.8 X2 2.0 Ghz 2 2.0 Gb 370 Gb PCI-X 256Mb 2.0 Mbps
2008? Core 2 Quad 9XXXX > 2.50 Ghz 4 8.0 Gb 500 Gb PCI-X 256Mb 6.0 Mbps
Well, what can I say? Current PC, RIP :) What do you think? Adriano

Jul 23, 2008

My mind is about to blow

Hi. That computer technology evolves day by day and the amount of information in this area is gigantic many of you already know (so do I), but today I was talking to a friend of mine and I realized how many books I want to ready (only in the subject Windows + .Net). If you are curious you can see the list here but most of them were not published yet (and here you can find a list of some books I've already read / I'm reading). What do you think about them? Is there any other book related to .Net / Windows development you consider a must? PS: Feel free to give some of them as a gift when they get published :) Adriano

Jul 15, 2008

Another one in the obscure codding practices ...

As I said in this post, today I've found an interesting site about C++ programing practices. While reading this pages I learned another way to write a fragile application (as always, writing bad code is enough :) So, let's go for it! What will be the output of the following program?
void main(int argc, char* argv[])
  int n = 255;
  size_t size = sizeof(++n);
  printf("%d", n);
Maybe this be can pretty obvious to you, but it was not to me (maybe because I avoid to write obscure code as much as I can :) Adriano

CERT C++ Secure Coding Standard

Hi. Today I reached this page (on site talking about C++ secure standard practices. I haven't read it to the end yet but at a first glance it looks pretty interesting (and useful) to me. Wait, don't call yet!! There's a page regarding safe practices for C also! I'll be reading this as soon as I get some time to ;) Adriano

Jul 2, 2008

What is wrong with this code?

I was reading some blogs this week and find an interesting story related to references in C++ (and as it has some time that I don't work/post about C++) so I decided to post about it. Take a look in the code and try to answer the following questions below:
#include "stdafx.h"
#include "stdio.h"

class SimpleClass
SimpleClass(int n)
   value = n;

void FirstMethod(TCHAR* str)

void SecondMethod()
  wprintf(L"Value: %d", value);

int value;

void Test(SimpleClass &ref, int i)
  case 1:
     ref.FirstMethod(L"Hello world\r\n");

  case 2:

int _tmain(int argc, _TCHAR* argv[])
SimpleClass *p = 0;

Test(*p, 1);
Test(*p, 2);

return 0;
  • Will it compile? run?
  • What would be the outcome from Test being called in line 39?
  • What about line 40?
  • Is there any other issues?
(PS: VS 2008 compiled it with no warnings....) Adriano

Jun 29, 2008

Do it yourself

Hi, I'm a strong believer that the DIY (Dot it yourself) philosophy helps to improve knowledge on the topic you are working on. So if you If you are a developer using (or planing to use) db4o (and have the time), I highly recommend to try do build it yourself as explained here. One point that can be further explored is the possibility to run the tests on a ramdisk in order to improve performance (in may machine I get an improvement of 20%). To be able to do this you need to create a ramdisk (personally I use this one) and them set 2 properties in our file: java.vmargs=-Ddb4ounit.file.path=DIR dir.tests.temp=DIR Here, DIR is an path to your ramdisk (in may case I use r:/temp). Adriano

Jun 25, 2008

Type safe / refactor friendly configuration for Db4o - Part III

Hi, In the first installment of this series I presented the idea of having a typesafe way to configure db4o. In the second one, I explored how we could use expression trees to figure out a property name being accessed. In this post I'll address the issue on how to dive into the property's IL (intermediate language) to come up with a field name which we want to configure (if you are not familiar to IL, please, read along some of the links here). The best tools I'm aware of (when it comes to read or even change a method's IL!) are the Mono Cecil library and Net Reflector, which is an invaluable tool when you want just to look at a method's IL without writing one line of code. I don't need to say that I used these tools a lot :) In order to come up with a field name to be indexed, the main approach is to find all return paths for the property getter in question and check the field being returned. Simple, right? Unfortunately no; what if the property getter returns only constants? what if there are more than one field involved? Before we dig into the details about IL handling, let's document the behavior for some possible use cases (the less obvious ones) regarding property getter return paths:
  • Only constants: Throw exception
  • More than one field involved: Throw exception
  • Chained method: returns the called method / property accessed field.
(we could come up with different requirements, for instance, every field referenced in one property return path must be indexed, but in order to keep it simple, let's stick to the rules presented above). From my previous posts, we already have a way to figure out the property get being accessed; the next step is to analyze the method body; I used Cecil.FlowAnalisys to accomplish this task (line 6) in the following function:
public FieldReference Resolve(MethodDefinition method)
if (CheckRecursion(FullName(method))) return null;

ControlFlowGraph graph = FlowGraphFactory.CreateControlFlowGraph(method);


firstInstruction => Array.Find(
                  candidate => candidate.FirstInstruction == firstInstruction));


FieldReference reference = CheckReferencedFields(
                         referencedFields, method.Name);

return reference;
Next, for each control block we inspect it's IL as shown in the following code:
void Resolve(
    InstructionBlock block,
    Func<Instruction, InstructionBlock> blockForStartingInstruction)
if (AnalyzeInstructions(block.FirstInstruction, block.LastInstruction))

for (int i = 0; i < block.Successors.Length; i++)
  Resolve(block.Successors[i], blockForStartingInstruction);
In Line 5 we call a function that do the dirt work of analyzing the IL instructions. This function returns true if the block containing the next instruction (after the last instruction of the current block) should be handled as the "next block" (this is done to support finally blocks). Lines 12-15 just process the remaining blocks calling Resolve() recursively. The real fun is in AnalyzeInstructions() function which do the following:
  • Line 7/9: For Ldfld / Ret instruction sequences, add ldfld target to return field list (lines 11 and 12).
  • Line 16: Add an alias for the each Ldfld /Stloc sequence;
  • For Ldloc / Ret sequences, search the aliases to see if ldloc's operand is an alias for a field and add any alias found to the return field list (line 23).
  • If a method call is found, analyze the target's method body (lines 35 - 41).
bool AnalyzeInstructions(
Instruction current,
Instruction last)
while (current != last.Next)
if (IsLoadField(current))
 if (IsReturn(current.Next))
    EnsureLocalVariableAliasFor(current, () => (FieldReference)current.Operand);
else if (IsLdloc(current.OpCode))
 if (IsReturn(InstructionOrBranchTarget(current.Next)))
 else if (IsStore(InstructionOrBranchTarget(current.Next)))
        () => aliases.Find(
            candidate => candidate.OpCode == current.OpCode).Field);

    current = current.Next;
else if (IsMethodCall(current))
   () => Resolve(

current = current.Next;

return IsLeave(last);
That's it! You can download the full source code here. [Updated on 7/23/2008: Fixed the source code download link] Just in case you want to play with the code, one point can (need to) be improved is the handling of exception blocks. Thoughts? Adriano

Jun 23, 2008

Very interesting (and funny)

Hi, This morning a friend of mine send me this link about colaborative development in eclipse. Very interesting Adriano

Jun 21, 2008

You are not paid to introduce bugs :)

Hi, Today's post is in the series "what is wrong with this code" but before presenting the actual problematic code I want to give some background, so bear with me. At Db4o we run migration tests (regularly) in order to guarantee that we are able to load (and query) databases created by older versions of Db4o engine. The way it's accomplished is very simple:
  • for each configured version, create an database using it and perform a series of tests with the trunk version.
Some time ago, I was asked to fix an annoying bug in these migration tests. In order minimize the time required to run these tests, we do not run then against every existing Db4o version. To allow this selective running we introduced a way to specify the minimum version to be tested so, if one want to test versions 6.0 and above it is a simple matter of setting a constant in a C# source:
private const double MinimumVersionToTest = 6.0;
At some point in the code we called the following function (wrong version):
double VersionFromVersionName(string versionName)
Version version = new Version(versionName);
return version.Major + version.Minor / 10;
This function is supposed to return the double representation of an assembly version (string) but it fails miserably (this code works correctly only for versions with a decimal value 0 (zero); for instance, 6.0, 7.0, etc). Now the question is, what's is wrong with this function? To be fair I have to admit that it's not a hard to spot bug, but when you are in a hurry and have no test for your test code... The problem is that version.Minor is an integer field and so,
version.Minor / 10
will result in a integer number and the decimal part will be happily discarded. The developer who wrote this code (me) is aware of language type conversions but he didn't notice the error
(shame on me) ; so whenever we passed a version number not finished in 0 (zero) we got the wrong double representation for it!
Actual VersionFunction Return
The fix? Pretty easy: Just add a ".0" to the divisor :) (I could also add an F: 10F)
double VersionFromVersionName(string versionName)
 Version version = new Version(versionName);
 return version.Major + version.Minor / 10.0;
The bottom line? T
his episode just highlights (and reminds me about) the importance of double checking our test code! after all, as a friend of mine likes to ask:
who test that the tests test what they should test?
Have fun. Adriano

Jun 3, 2008

Running Sharpen Tests


If you start using sharpen, you'll probably find some limitation / bug and, maybe, want to take a look into the issue.

In this case the best approach (IMHO) would be to i) start a discussion in Sharpen Forum and, if
appropriated (in the case there's no issue filed already), ii) file a new Jira issue into our issue tracking system.

Next, if you have the time, iii) try
to replicate the behavior with a minimal test case. The last step iv) would be trying to fix the issue.

This post is all about iii, or to be more clear, on how to run / write unit tests for Sharpen.

Let's start by opening an empty eclipse workspace:

Next, open SVN perspective and add a new SVN repository pointing to

and checkout all projects.

No install the plugin (as explained here):
  • In package explorer (Java perspective), right click on sharpen.core and select "Export" from the context menu.

  • Expand the "Plug-in Development" folder and select "Deployable plug-ins and fragments".

  • Set "Destination" to the root folder of your eclipse installation and click "Finish";
Now you can run Sharpen Tests by right clicking on "sharpen.ui.tests" and selecting "Run as / JUnit Plug-in Test";

after some processing your screen should look something like:

When the tests finishes you should see 0 (zero) errors and failures (as of today, there's some issue with sharpen.builder and sometimes you will get 2 errors in its tests but these errors don't prevent sharpen to work properly and, as you can see, when I executed the tests the errors didn't showed up).

Now let's explore the general look 'n' feel of a Sharpen test. In package explorer expand the node sharpen.ui.tests then testscases.

For each sharpen functionality there will be at least one pair of files (collectively called Test Case Resource):
  • One .java.txt that stores the java source to be converted;
  • One .cs.txt storing the expected sharpened file;
In the above picture we are testing interface conversion. Take the time to poke around testcases folder checking some of the tests.

The next logical step is to add new tests. Basically to add a new tests we need to:
  1. Create the original java source (.java.txt)

  2. Create the expected cs file (.cs.txt)

  3. Plug these two files into the test engine. In the common scenarios, all we have to do is to call runResourceTestCase() function.

To see an example, just expand sharpen.ui.tests/src/sharpen.ui.tests folder and double click on

In a future post (soon I hope) I want to take a look in a few other points such as:
  • Getting a little better performance when starting sharpen using the approach presented in this post.
  • How to debug sharpen.
  • A trick to see the expected / actual values (useful when creating new tests).


Jun 2, 2008

Dumb security...

Hi! Am I in a bad mood today? Well, maybe, but I really feel upset when something supposed to help me to be safer on the net starts to get into my way or, even worse, pushes me in the other direction. That is what happened today when I tried to use a well know credit card website (which I'll not name here :) to see my billing information. Of course, as I don't use this service very often, I didn't remember my user name / password! Ok, (I thought) I just need to call their support service and ask them to reset my user name / password to one that I do know. So, I picked up the phone and called them. My first issue was that they didn't allowed me to choose my user name! Ack! Ok, this is not a big issue anyway (I can always write it down somewhere). The real problem (in my opinion) is that they requires that you MUST set a password which is at least 6 but no more than 8 characters in lenght! And you MUST use numbers also! Ok, I understand that mixing numbers, digits, punctuation, etc. in a password helps to make it stronger, but these rules forces me to give up on my "password schema" (I use different passwords for each site; each password is an encoding of a lengthy phrase). The result? I'd never be able to remember the password I choose (no matter which one I pick); it's even worse as probably I'd choose a weaker one in a desperate (hopeless) try to not forget it again. After this episode I decided to take the time (ok, I'm a little bit lazy) and give some password manager a try (at least they succeeded in the purpose of forcing users - at least me - to use a stronger password :). I'll be experimenting with a firefox plugin called iMacros. Let's see how it works :) See you. Adriano.

New programing language!

Hi! Today I got an "job opportunity" from one of jobs sites I'm registered (no, I'm not looking for a new job, I just didn't unregistered) with a really intriguing subject:
A skilled professional with 3 years of experience in C, Sharp and VB.NET.
I have to admit that I do know C and also a little of VB.NET, but I have never seen SHARP :) Ok, probably it was just a mistyping, but I bet the person who wrote this subject has no idea about programing languages whatsoever ;)

May 22, 2008

Where do you search for .Net tools?

Hi. This will be a very short, but I hope useful, post! Of course I usually do a google search when I want to find some system/programing tools. Also I do keep an eye on some pretty helpful sites:
  • The Free Country (
  • Source Forge (
  • Codeplex (
  • Fresgmeat (
One site that I really like when I want anything related to .Net is sharptoolbox ( If you are a .Net developer you should take a serious look into this site. Which sites do you visit to get system/programing tools? Adriano

May 15, 2008

Usefull firefox trick

There is one little trick in Firefox that few people I know are aware of: It's possible to create "shortcuts" in order to make it easy to browse for sites that accepts inputs.

As an example let's take the free dictionary, very nice (guess what ??) dictionary site :)

When you browse to and enter a word to search it navigates to

In Firefox we can add a shortcut so we can speedy our browsing experience. See the example below

Instead going to the TheFreeDictionary site and then typing the word we want to look for (for instance, cake), just type tfd cake in firefox address bar! Simple like that! :)

In order to make this work we need to tell firefox that we want a shortcut named tfd (you can name it at your will) and that it must navigate to

To do this, open bookmark manager (CTRL-B) add a new bookmark as follow:

(note the url:

Press Add and you are done! Now just type tfd cake on firefox address bar!


May 14, 2008

Type safe / refactor friendly configuration for Db4o - Part II

In my last post I proposed to derive field names from a property accessor in order to gain type safety and compiler support when configuring some aspects of D4bo.

So, given the following class:

public class Test
   private int _age;
   public int Age
      get { return _age; }
      set { _age = value; }
we could use the following code:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectField((Test t) => t.Age).Indexed = true;
instead of:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
to configure a field to be indexed. The first step to use this syntax is to be able to figure out the property being accessed. To demonstrate how this can be done let's write a simple function that takes advantage of C# Expression Trees:
public string GetPropertyName<T,R>(
               Expression<Func<T,R> exp)
  // Get the property name here.

public static void Main()
   string s = GetPropertyName((Test t) => t.Age);
When compiling the above code, the C# compiler will create an expression tree representing our lambda expression ( (Test t) => t.Age) and pass it along to GetPropertyName() function.

Inside this function we can just use the Body property (which in this case represents t.Age part of our lambda expression) and cast it to MemberExpression. Now all we have to do is to consult MemberExpression.Meber.Name property:

public string GetPropertyName<T,R>(
               Expression<Func<T,R> exp)
    MemberExpression me = fieldExp.Body as
    if (me == null) return "na";

    MemberInfo m = me.Member;
    return m.DeclaringType.FullName + "." + m.Name;

At this point we are able to figure out the name of the property being accessed! If you take a deeper look into me.Member we will see that it is a PropertyInfo instance where you can get a lot more information about the property.

In the next post I'll dig a little bit deeper and investigate how we can select a field based on the property being accessed ;)



May 10, 2008

Linq Console Update

Hi! I've just updated the Linq Console application! Now you don't need to copy your model assemblies to Linq Console folder anymore! You can use the load command as follow: :load "c:\my projects\test\Test.Model.dll" and the application will be able to load it :) The source code can be downloaded from our svn server: Adriano

May 1, 2008

Type safe / refactor friendly configuration for Db4o

As of today, Db4o uses strings to reference fields in some scenarios such:
  • SODA queries
  • Configuration

See the sample bellow:

IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
IMHO, using strings in these situations is sub-optimal as:
  • Such solution relies in internal class details (field names)
  • Compiler can't check whenever the field actually exists.
  • We don't take advantage of modern IDE's refactorings so, chances are that these entities and references to them get out of sync breaking your code; it's even worst because you will figure it out only at runtime :(; it may even get unnoticed as Db4o is completely happy with some invalid field names.
With the introduction of C# 3.0 and its automatic properties we have another issue: we don't even know the field's name used to back the property! Sure, we can cheat by using some tool like reflector or ildasm to figure it out but this would be a fragile solution as C# compiler may choose whatever name it wants, so it may choose different names schemas in the future and we don't want to get our code breaking when new C# compilers come out, do we?

I do believe that this approach was chosen due to technical limitations at the time the code was written, but now, with the debut of C# 3.0 and its new features like extension methods, lambda expressions, expression trees, etc. I bet we can do better :).

To be fair, we've already been improving (removing) some string usages, for instance, Linq / Native Queries uses strong typing instead of strings to reference fields (under the hood they generate SODA queries that still use strings, but the crux here is that these "names" will always be in sync with its entities).

One area that, in my opinion, can be improved is configuration. For instance, in order to setup indexes, deletion behavior (when to cascade delete), etc. we still use strings to identify the field we want to apply the configuration. Suppose we have the following code to configure indexes:

IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectClass(typeof(Test)).ObjectField("_age").Indexed = true;
We could introduce new methods to IConfiguration interface so one would be able to do something like this:
IConfiguration cfg = Db4oFactory.NewConfiguration();
cfg.ObjectField((Test s) => s.Age).Indexed = true;

Wow! Using this syntax we no longer have issues with refactorings, abusive internal class knowledge and we get compiler time support for free :) (for instance, if we mistype "s.Afe" C# compiler will complain).

To be fair, we have some issues with refactorings. If we change field/class's name we need to inform Db4o about this changes as explained here (I do have some ideas on how to express these calls also but this is a little bit more complex topic that I won't cover here).

What do you think?

In a following post I'll discuss how we could implement this new configuration method. Go to part II of this post. Adriano

10 years ago....

------------------------------ Warning: Personal post :) ------------------------------
Well, ten years ago (may, 1, 1998) I got married to Gislene, my wife :) 

Since then, she has been helping me, providing me advice, being patient with me and loving me! 
Gislene, thanks for all these years! I hope (and will do my best) to be at your side for the next 10 years, then for the next 10 and so on. 

I couldn't finish this without saying.. Gislene, I love you! 


Apr 24, 2008

Redirecting standard error output in cmd.exe

Hi. Suppose you have the following C++ program (in a Windows box):
#include "stdafx.h"
#include "string.h"

void write(char *str, FILE *target)
fwrite(str, strlen(str), 1, target);

void _tmain(int argc, _TCHAR* argv[])
write("Test:stderr\r\n", stderr);
write("Test:stdout\r\n", stdout);
and you want to redirect its output to a file. We could try something like in Windows console:
test.exe > myfile.txt

Unfortunately the naive approach don't work because there are data being outputted to stderr and we are redirecting only the standard output (stdout). In order to redirect stderr we can use the following syntax:
command handler# > target

let's try a sample:
test.exe 1>myfile.txt

This will redirect stdout (handle 1) to myfile.txt To redirect stderr (handle 2) we can use:
test.exe 2>myfile.txt

Ok. Now we can try:
test.exe > myfile.txt 2>myfile.txt

but, again, this doesn't work; instead we get an error message:
D:\temp\cpp\Test\Debug>Test > myfile.txt 2>myfile.txt
The process cannot access the file because it is being used by another process.
Ok, there's one last trick we can try (duplicate stderr to stdout):
test.exe > myfile.txt 2>&1

Great! Now it works as expected! Last, but not least,
you can find more information here. Hope this can be useful :) Adriano