25/08/2009

Random hex string generator in ruby

I was looking around for a random hex string generator (pseudo random is fine for me too) and I wasn't too happy with what I found (source : http://snippets.dzone.com/posts/show/491 ):

def newpass( len )
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
    newpass = ""
    1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
    return newpass
end

I tried to come up with something more to my liking, on my own but didn't fare that much better:

def rand_hexstring(length=8)
  (1..length).inject("") {|x,i|
    x+=((rand()*128)).to_i.chr
  }.unpack("H*").to_s.slice 0..length
end

I had thought of filtering it at some point and came up on a blog ( http://www.rubyrailways.com/rubys-most-underused-keyword/ ) with the following :

  (0..9).map{rand(?z).chr[/[^_\W]/]||redo}*"" 

While in the end I had no use for filtering, and shed the nice redo trick, it made me realize I could improve on my answer by using map instead of inject :

  def rand_hexstring(length=8)
    ((0..length).map{rand(256).chr}*"").unpack("H*")[0][0,length]
  end

What this does is : for each element of the range ( map ), create a one char string ( rand(256).chr ) join the resulting array ( *"" ) unpack it to hexes, get the only element ( [0] ) of the resulting array and slice it to the requested length

16/08/2009

Eclipse 3.5 and Glassfish

I just tried to install a new instance of galileo and got bitten again:/ try to install glasfish support in galileo following the obvious path and you will be presented with a totally cryptic error message that basically tells you to go to hell with your request. ( I remember reading somewhere that p2 error messages are beyond the understanding of mortalsm I can only concur ).
Anyway, it looks like I am not the only one having trouble installing Glassfish v3 support for my favorite Java IDE : http://hardikmehta.wordpress.com/2009/06/29/glassfish-plugin-on-eclipse-3-5-galileo To sum it up, install glassfish support from the following update site: https://ajax.dev.java.net/eclipse/ and you will be setup in a sec

15/08/2009

JavaCamp Paris 5ème édition

Pour sa cinquième édition le JavaCamp paris prendra la forme d'un grand picnic au jardin des tuileries, ça se passe le jeudi 27 Août à 18h30. Le barcamp c'est un format totalement informel, l'inscription sert surtout a annoncer les sujets qui nous interessent, de façon que l'on sache un peu si on trouvera des gens pour discuter de ça pendant le barcamp. Comme cette fois on ne sera pas chez google, il n'y aura pas de buffet, il faut donc penser a amener a manger et a boire. En échage : pas de contrainte de place, je doute que nous remplissions la totalité du jardin des tuileries :D

10/08/2009

Cool iris

En fouinant dans les addons firefox à la recherche de l'addon delicious, je suis retombé sur cooliris. Il est maintenant disponible pour ma plateforme (linux 64bits) Je ne connais pas de meilleur facon de visionner une grande quantité d'images rapidement, pour moi qui passe beaucoup de temps a "lurker" sur flickr, cet addon c'est le bonheur. Merci cooliris!

06/08/2009

Impressions of TDD

A little think back on yesterday's TDD experiment. I left the tests in the order I wrote them. If you look closely enough, you will see that the test test_get_open_lockers_4_est_1_et_4 couldn't work until the last two tests were written. What that means is that I tried to take too big a step and wrote a test I couldn't make pass. I wrote more tests, leaving a failing test behind, fixing first the folowing tests and then that one. Was that the correct answer to too taking too big a step ?

Nerd, Jocks ans Lockers

I am a fanatic reader of the Daily WTF but until now I had never taken the time to try and solve a problem from the programming praxis category. So this time, I have gone and done it for the Nerds, Jocks and locker problem. the following is my entry done trying to follow TDD. test_locker_solver.rb:
require 'test/unit'
require 'locker_challenge'

class TestLockerSolver < Test::Unit::TestCase
 def test_prime_set_number_de_1_est_1_1() 
  solver=LockerSolver.new
  assert_equal [1,1], solver.get_prime_set(1)
 end
 def test_prime_set_number_de_2_est_1_2() 
  solver=LockerSolver.new
  assert_equal [1,2], solver.get_prime_set(2)
 end
 def test_prime_set_number_de_3_est_1_3() 
  solver=LockerSolver.new
  assert_equal [1,3], solver.get_prime_set(3)
 end
 def test_prime_set_number_de_4_est_1_2_2() 
  solver=LockerSolver.new
  assert_equal [1,2,2], solver.get_prime_set(4)
 end

 def test_get_open_lockers_1_est_1
  solver=LockerSolver.new
  assert_equal [1], solver.get_open_lockers(1)
 end
 
  def test_get_open_lockers_4_est_1_et_4
  solver=LockerSolver.new
  assert_equal [1,4], solver.get_open_lockers(4)
 end
 
 def test_count_primes_1_est_1x2
   solver=LockerSolver.new
   
   assert_equal({1 => 2}, solver.count_primes(1))
 end
  def test_count_primes_4_est_1x1_2x2
   solver=LockerSolver.new   
   assert_equal({1 => 1, 2=>2}, solver.count_primes(4))
 end
end
and locker_solver.rb:
class LockerSolver
 def get_prime_set(n=1)
  i=2
  while n%i!=0 and i<=n  
   i=i+1
  end
  i>=n ? [1,n] : [i,get_prime_set(n/i)].flatten.sort  
 end
 
 def count_primes(n=1)
  pset=get_prime_set(n)
  map=pset.inject({}) { |memo,n| memo[n].nil? ? memo[n]=1 : memo[n]+=1; memo }
 
 end
 
 def get_open_lockers(n)
  r=[]
  (1..n).each do |l|
    h=count_primes(l).delete_if {|key, value| key<2}
    isOpen=true
    h.each do |prime,count|
      isOpen &= (count%2==0)
    end
    isOpen ? r << l : false
  end
  r
 end
end

19/06/2009

Introducing dstx/wtx unit

Context

At my current client, I work with Datastage Transformation Extender (DSTX) recently re branded Websphere Transformation Extender since it was bought by IBM. To me DSTX looks like a strongly, statically typed functional programming language with added seemingly arbitrary limitations, but that's not the point for today. When I was asked to develop a completely new transformation map for my current project, I immediately thought, cool let's practice Test first, where do I find DstxUnit ? I didn't find it :(

Building DstxUnit

I could have done a small shell framework but I wanted it to both run under Unix (because I intend to make some kind of continuous integration later on) and Windows (developers). However I didn't want to bother with writing 2 shell scripts, also I was really looking forward to getting the green bar. Since DSTX is used for data transformation it is easy to make it take text files as input and write text files as output (you can even override input and output settings of the map for specific runs) So I went the java way (I am used to working with java) and extended a JUnit Testcase which provides runTx and assertTx.

runTx

runTx will take the transformation map name, the file extension for input and output, a test case number for the given map and a flag to know if errors are acceptable or not for this run. With that and a configuration file (to know where the maps are and where the resources are) it will build all the correct paths to run the map and place its output in a know location for comparison (see assertTx). Here is how my files are organized :
project/
  DSTX/
    Map/
     map.mms
     common/
       lib.mms
    Test/
      testmap.mms
      common/
        testlib.mms
      resources/
        in/
          test_map_1.txt
          common/
            test_lib_1.txt
            test_lib_2.txt
            test_lib_3.txt
            test_lib_4.txt
        out/
          [output of map run will be generated here]
          common/            
            [output of lib run will be generated here]
        ref/
          test_map_1.out
          common/
            test_lib_1.out
            test_lib_2.out
            test_lib_3.out
            test_lib_4.out
        trace/

assertTx

I chose to separate the run itself from asserting the results, mostly to be able to see an "assert" line in the test, but also because run errors are not the same as assertion errors. assertTx thus requires again the name of the map, the output extension, and the test case number and compares the produced output (in out/ ) with the reference file (in ref/ ) If the files are different, the assertTx method will raise an AssertionFailed exception including a detailed messages explaining the differences in the usual "expected <...> but got <...>" format.

28/04/2009

Headless gecko browser attempt 3

I reported my trouble in the comments of the bug which first proposed a new headless renderer. I got helpful comments from both Chris Lord and Sylvain Pausch, basically if your embedded application segfaults like this:
WARNING: NS_ENSURE_TRUE(compMgr) failed: file nsComponentManagerUtils.cpp, line 165
###!!! ASSERTION: You can't dereference a NULL nsCOMPtr with operator->().: 'mRawPtr != 0', file ../../../../dist/include/xpcom/nsCOMPtr.h, line 796
Segmentation fault
Make sure you have MOZILLA_FIVE_HOME environment variable pointing to the directory containing libxul.so ($prefix/lib/xulrunner-1.9.2a1pre/) when running the sample.

Headless gecko browser attempt 2

Okay since my attempt at using xulrunner failed, I tried again with c compilation. I went back in shame to my make manual and relearned the make basics. Using error and trial I finally got chris lord's example to compile, but it fails on a segfault. Now I remember why I dislike C so much :( For further reference, here is my makefile :
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include \
 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include
CFLAGS = -I./include/ -I../include/mozheadless/ -I../include/cairo/
LIBDIRS += ./lib/ ../lib/ /usr/lib/ /lib/ ../bin/
LDFLAGS= -L./lib -L ../lib -L../bin
LDLIBS= -lcairo -lglib-2.0 -lxul -lsqlite3 -lmozjs -lsoftokn3 -lnssutil3 -lnss3 -lnspr4

all: offbrowse

clean:
 -rm printenv *~ *.o *.bak core tags shar

offbrowse: moz-headless-screenshot.c
 $(CC) $(GLIB_CFLAGS)  $(CFLAGS) $? $(LDFLAGS) $(LDLIBS) -o $@
Once compiled I copied it to the bin directory of the sdk, added the current directory to de LD_LIBRARY_PATH and tried to run it here is what I got :
./offbrowse http://www.google.com 800 600 test.png
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 1035
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: NS_ENSURE_TRUE(compMgr) failed: file nsComponentManagerUtils.cpp, line 165
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 915
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 972
WARNING: NS_ENSURE_TRUE(compMgr) failed: file nsComponentManagerUtils.cpp, line 90
WARNING: XPCOM objects created/destroyed from static ctor/dtor: 'gActivityTLS != BAD_TLS_INDEX && NS_PTR_TO_INT32(PR_GetThreadPrivate(gActivityTLS)) == 0', file /home/jean/dev/embedding/offscreen/xpcom/base/nsTraceRefcntImpl.cpp, line 972
WARNING: NS_ENSURE_TRUE(compMgr) failed: file nsComponentManagerUtils.cpp, line 165
###!!! ASSERTION: You can't dereference a NULL nsCOMPtr with operator->().: 'mRawPtr != 0', file ../../../../dist/include/xpcom/nsCOMPtr.h, line 796
Segmentation fault
all the files (Make file, moz_headless_screenshot.c and error.txt) are available here

27/04/2009

Headless gecko browser attempt 1

I want to be able to run selenium in a headless browser without xvfb. While I searched the googlenet to find someone having done the same thing, I came upon this : https://bugzilla.mozilla.org/show_bug.cgi?id=446591 Which basically proposes to add a headless renderer to gecko. sounds exactly like what I need, following various indications here and there, I finally got the monster to compile and give me a supposedly headless xulrunner. here are the steps I took for this :
hg clone http://hg.mozilla.org/incubator/offscreen
cd offscreen
hg checkout headless
wget -O mozconfig https://bug446591.bugzilla.mozilla.org/attachment.cgi?id=350162
make -f client.mk build
cd ../obj-x86_64-unknown-linux-gnu
This got me my headless enabled xulrunner. Then I started trying to make a xul application with an embedded browser which I could send to the selenium core url I have a main.xul with a window, a script and a browser. The script only contains the onload of the window and gets the arguments from the command line to load the browser to the given url
function onLoad() {
  var browser = document.getElementById("browser");
  var windows = document.getElementById("main");
  var url = window.arguments[0].QueryInterface(Components.interfaces.nsICommandLine).getArgument(0);
alert(url);
  browser.loadURI(url, null, null) 
}
Works like a charm with the standard xulrunner, but when I run it headless :
jean@xps:~/dev/embedding/offbrowse$ ../obj-x86_64-unknown-linux-gnu/dist/bin/xulrunner ./application.ini http://localhost:7080/tester/
it fails with the following error :
 JavaScript error: , line 0: uncaught exception: [Exception... "Component returned failure code: 0x80004001 (NS_ERROR_NOT_IMPLEMENTED) [nsIDOMChromeWindow.getAttention]"  nsresult: "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)"  location: "JS frame :: chrome://global/content/commonDialog.js :: commonDialogOnLoad :: line 195"  data: no]
and I have no idea what it means. It's been a looong time since I have felt like I was playing with unknown forces of terrible power. I don't like the look of " chrome://global/content/commonDialog.js " sounds like it is somehow trying to read something from my "production" environment ( aka my normal firefox installation) buy I have no idea how to prevent it from doing that :( A zip with all the files can be found there

18/04/2009

Strobist info

La façon la plus interessante de présenter les infos strobistes que je connaisse : http://www.flickr.com/photos/polvero/sets/72157615873440953/ je ne suis pas le seul à le penser, son stream est passé sur le blog flickr :)

15/04/2009

We are linux

Liens rapides vers les 3 videos qui ont fait les finales de la campagne we are linux de la fondation linux. Il y a une video française ! Comme il se doit le budget de la vidéo française n'est pas à la hauteur de sa créativité mais ça reste quand même bien amusant.

What it means to be free

The Origin

Linux Pub

06/04/2009

Java Barcamp Paris 4 : Spring3

I first decided to attend the Spring3 session at javacampparis4. I was curious as to what is would bring over spring 2.5 and I wanted to discuss the missing generic DAO for hibernate forcing each project to reinvent the wheel. The main new feature of Spring 3 seems to be native REST support, even though it doesn't conform to the JAX-RS specification, which became a major discussion point. There was also some discussion around the arrival of EL in the spring3 config files allowing easier and cleaner management of instanciation time variables (basically PropertyPlaceHolder on steroids). We finally discussed the pros and cons of adding an generic DAO for hibernate and/or for other database access methods.

Java Barcamp Paris 4 : l'arrivée

J'ai participé à mon premier Javacamp Paris 4 dans les locaux de google mercredi dernier (31/03), et je dois avouer que je me suis bien amusé. J'ai débarqué dans les locaux sans trop savoir ce à quoi j'allais participer, j'ai été agréablement surpris du monde rencontré Une fois le plus gros du monde réuni, nous avons procédé à une ronde de présentation, chacun tient le stylo micro, donne son nom et ses sujets d'interet Une fois le tour de présentation terminé, on passe au choix des sujets, au début ça part doucement mais comme les premiers post-its commencent à apparaitre sur le tableau, les choses s'accélèrent, et on finit par retrouver plusieurs fois les même sujets. Au final le tableau donne ça: Et on est parti chacun pour sa salle. Pour nous faire rester jusqu'au bout des discussions, le buffet est déjà dressé :

12/03/2009

A case for the Generic lightweight DAO

This post stems from my research in how to correctly use hibernate3 in a spring-webmvc application. It outlines the various means to do so and proposes a rationale for using a generic lightweight DAO pattern. I have been spending some time researching the various ways of using hibernate3 with spring in a web app. The first thing I noticed is that there are multiple ways of doing that. The immediately obvious way is to inject the hibernate session factory in the various business components which would have to manipulate persistent data. This allows to work directly with the hibernate API, however it also means your business layer will become tightly coupled to Hibernate (think API usage all over the place) changing to a different orm later would be very hard. it also means code which is harder to test. The common answer to that is to use the DAO pattern (Not everyone agrees, see the ORM and the misleading DAO pattern at the serverside ). Supposedly it helps with the decoupling by centralizing the API usage in one place. On the implementation side however things tend to get messier than the theory predicts. Spring 2.5 proposes two ways to create DAO implementations :
  • inheriting from HibernateDaoSupport
  • using HibernateTemplate
Unfortunately they bring very little to the fight. HibernateDaoSupport offers almost nothing. it's a bare template for a DAO allowing sessionfactory injection and internally creating an hibernate template for inheritors to use, very little meat on this bone. HibernateTemplate has a lot more to offer but the way it's supposed to be used makes it next to useless : you are supposed to reimplement all the methods you want then delegate to hibernate template. I complained about this to a friend of mine whom I knew has been playing with these for a while now. His answer was that according to "purists" the DAO shouldn't expose more than what is required by the business, and that thus it was incorrect to make a generic dao implementation. While I agree, I still think this doesn't preclude a generic implementation of the DAO, the exposition is the concern of the DAOs Interfaces, this has nothing to do with implementation. The current implementations mean developpers must duplicate a lot of code to use a DAO. Sure there are considerations of backward compatibility with java 1.4, I still think a GenericDao implementation should be found in an optional spring lib somewhere. I hear it's coming with spring3.0 but what I have seen so far is not very convincing. It seems I am not the only one thinking along these lines, there are quite a few articles on the internet which show how to implement the DAO pattern using java generics to make for a DRY implementation. And there are at least two google projects proposing a small library implementing this pattern : I have settled for the former. The API seems simple enough, the design seems logical, only usage and time will tell now if I made the right choice... I'll publish the results of my experiments later on

11/03/2009

Manifesto for software craftmanship

Following a blog post by Dave Carver which I found through planet eclipse. I have signed the Manifesto for software craftmanship. It values the following : Not only working software, but also well-crafted software Not only responding to change, but also steadily adding value Not only individuals and interactions, but also a community of professionals Not only customer collaboration, but also productive partnerships

04/03/2009

VCS branching diagram

At last I have found a tool which makes branch diagrams easy enough to be formalized : yED It takes a couple seconds getting used to the UI: clicking drops a node by default, dragging creates an edge (at first you create a few unwanted nodes and edges) they have a very friendly palette system which allows you to define a node or edge archetype in a few cliks. Once you have defined you palette this is what you can get in a couple minutes: Alignement is handled automatically through the use of yED layouts. there are many many options, and I couldn't get it to do exactly what I wanted yet but I haven't read any doc either :) Definitely a tool I'll remeber for network and graph visualisation

20/02/2009

Ne pas oublier

I believe in the supreme worth of the individual and in his right to life, liberty, and the pursuit of happiness. I believe that every right implies a responsibility; every opportunity, an obligation; every possession, a duty I believe that the law was made for man and not man for the law; that government is the servant of the people and not their master. I believe in the Dignity of labour, whether with head or hand; that the world owes no man a liking but that it owes every man an opportunity to make a living. I believe that thrift is essential to well ordered living and that economy is a prime requisite of a sound financial structure, whether in government, business or personal affairs. I believe that truth and justice are fundamental to an enduring social order. I believe in the sacredness of a promise, that a mans word should be as good as his bond; that character not wealth or power or position - is of supreme worth. I believe that the rendering of useful service is the common duty of mankind and that only in the purifying fire of sacrifice is the dross of selfishness consumed and the greatness of the human soul set free. I believe in an all-wise and all-loving God, named by whatever name, and that the individuals highest fulfilment, greatest happiness, and widest usefulness are to be found in living in harmony with His Will. I believe that love is the greatest thing in the world; that it alone can overcome hate; that right can and will triumph over might.

John D Rockefeller Jnr.

Ou est SAEZ aujourd'hui ?

Pour rappel :
Ivre d'inconscience, tous Fils de France. Au pays des lumières, amnésie suicidaire. Non Non Non Non. Nous sommes, nous sommes La Nation des Droits de l' Homme. Nous sommes, nous sommes La Nation de la Tolérance. Nous sommes, nous sommes La Nation des Lumières.
Bizarrement ça s'applique presque aussi bien aujourd'hui qu'à l'époque, mais cette fois il a été démocratiquement élu ... cherchez l'erreur ... :(

11/02/2009

Vs Vista : Round 1

J'ai allumé mon XPS ! muni d'un direct soir, de mon passport et de mon appareil photo j'ai lancé la bête! Elle a démarré et comme prévu a commencé a essayer de me faire configurer Vista truc premium machin. Après un premier écran qui me demande de choisir la langue, je tombe sur le fameux écran avec les CLUFs : 1 pour l'univers microsoft (il annonce couvrir une tonne de trucs) et 1 pour dell. Suivant scrupuleusement le guide de racketiciel, je scroll le texte en prenant des photos. Processus rendu particulièrement lent par le fait que la fenêtre n'affiche que 4 lignes de texte a la fois. Arrivé a la section qui annonce que si je ne suis pas d'accord avec les conditions du CLUF j'arrete de lire et je passe au CLUF suivant. Celui-ci beaucoup plus court indique que si je ne suis pas d'accord avec les conditions, il faut que j'appelle le service client DELL. Evidement il est 18h10 et le service client ferme à 18h :( j'ai écrit a racketiciel avec l'espoir de sauter cette phase mais je reste pour l'instant sans nouvelles ... le pauvre correspondant de racketiciel qui doit gérer 50 personnes qui comme moi tatonnent a travers le dédale procédurier créé par les constructeur a le droit à toute ma compassion. Bref, je suis pour l'instant privé de PC, enfin pas tout a fait : Merci les live-cd linux => je vous écrit de mon XPS ! En mettant simplement le cd dans le lecteur, j'ai le wifi, les boutons tactiles la gestion de la luminosité bref tout les trucs que je m'attendais a voir foirer qui fonctionnent, j'ai pu regarder des videos a travers un partage sftp connecté sur le wifi :) Lire mes mails et tout mes sites habituels. Poster sur mon blog, parler avec des amis, ma vie habituelle quoi En attendant la suite : voilà à quoi ressemble l'écran de CLUF de mon Dell. Vous noterez qu'il ne propose pas l'option de refuser ce que je trouve assez lamentable. Au passage, le correspondant racketiciel m'a dit que ma license windows XP n'était pas valable, c'est dommage mais ça ne fait que renforcer ma détermination à ne pas relouer un nouveau windows

10/02/2009

DELL règles d'engagement

Ca y est j'ai reçu la bête de course ce matin à 10:43 (dixit UPS, que j'ai imprimé en pdf aussi au cas où). Juste à temps! En effet je dois rendre l'ordinateur qui me sert a taper ces mots demain avant 16h (il s'agit d'un ordinateur de fonction et je quitte la société qui me l'a fourni, il veulent le récupérer ce que je comprends tout a fait). En d'autre terme demain soir sans mon XPS je n'aurais plus de PC ce qui me serait fortement préjudiciable puisque je dois suivre dès jeudi un cours à distance payé par mon nouvel employeur qui nécessite l'utilisation d'un ordinateur (sans parler de mes autres activités). Bref, je retourne sur le guide de remboursement du site racketiciel que je lis attentivement une fois de plus. Je note que je n'ai pas le journal du jour et comme je veux faire ça dans les règles (même si je ne suis pas convaincu de l'utilité du journal) je me contente de brancher l'ordinateur sur le secteur pour charger la batterie pendant la nuit. J'en profite pour lire les instructions de contact de racketiciel et je rédige la main courante qui m'accompagnera dans la suite de mes démarches. la suite demain : achat du journal du jour, prise des photos et enfin, enfin format bas niveau de windows vista et installation de l'ami kubuntu. edit-- juste pour être clair: je pense que le XPS est la meilleure machine disponible à ce jour en terme de rapport poid/puissance/qualité/prix j'adore déjà mon M1330 alors que je ne l'ai même pas encore démarré. par contre j'ai eu l'occasion de jouer avec vista sur le portable de mes parents (un monstre de 5kg avec la configuration pour justifier les 5kg) : il est hors de question que j'utilise cette chose quelque soit le niveau de service pack. j'envisagerais peut être l'achat du prochain windows mais vista ne vaut pas mieux que windows millenium.

01/02/2009

DELL la bataille se prépare

J'ai décidé d'acheter un XPS M1330, seulement voilà j'ai aussi décidé de ne pas payer une license de windows vista, ni une nième license de microsoft works ni d'ailleurs d'éventuelles licenses supplémentaires. Mon refus de vista tiens a deux choses : je possède une license windows XP po valide et je n'ai pas l'intention de payer pour un OS inférieur. Je suis conscient que ma future machine est 64bits et que ma license windows XP32 bits ne me permettra pas d'en profiter pleinement, mais ça ne me tracasse pas le moins du monde, j'ai un autre ami qui s'appelle kubuntu et que je rève de pouvoir enfin mettre sur une machine puissante. 
Peut m'importe de perdre la garantie de compatibilité logicielle à laquelle je n'aurais jamais fait appel de toute façon et j'ai pris les renseignements nécessaires, la garantie matérielle ne saurait en aucun cas être invalidée par l'utilisation d'un logiciel autre que celui qu'ils me forcent à acheter.
J'ai donc commencé à me renseigner sur internet (google est un ami fidèle) et je suis tombé sur le site http://www.racketiciel.info/ qui comporte un guide interessant sur la façon de se faire rembourser la  license, ce billet est partie prenante de cette stratégie : j'ai agi ce soir en pleine connaissance de cause. Je veux cette machine et pas les logiciels qu'ils veulent me forcer a acheter avec. 
J'ai commencé ma préparation au cours de la semaine en contactant le chat en ligne pour savoir si il était possible d'avoir un XPS M1330 sans logiciels microsoft. réponse suprenante : 
il faut appeller le service commande ils ont des options spéciales, ayant une éthique j'essaye autant que possible de limiter mes communications personnelles lors des heures de bureau, j'ai donc attendu samedi 31/01/2009 pour appeller. 
Après 1 répondeur automatique et une première personne j'ai fini par être renvoyé vers un commercial (enfin pas tant que ça vous le verrez plus tard). Là j'ai commis une faute d'inattention : je n'ai pas noté son nom. J'ai essayé de le raisonner pendant pres de 17 minutes (2.631€ d'après le suivi conso de free), pour qu'il me fournisse une trace écrite du refus qu'il m'opposait de me vendre une machine sans OS (sa réponse: je n'ai pas l'authorité pour, la mienne alors demandez a quelqu'un qui l'a de le faire, et on part en boucle infinie). 
Ceci étant fait et mis en face de l'impossibilité manifeste de commander la machine sans OS ou du moins sans produits microsoft ( car j'ai trouvé sur internet un test de cette même machine en date du 07/01/2009 qui indiquait qu'elle avait été livrée avec Ubuntu ! mais impossible de retrouver cette option sur le site). 
J'ai commandé ma machine, en prenant une image pdf de chaque page de la commande, en téléchargeant et en parcourant tous les PDFs de conditions générales et particulières que j'ai pu trouver, le tout afin de prouver que mon acte de refuser les license est délibéré et prémédité, et que j'avais été mis face à l'impossibilité d'acheter la machine dnas la configuration logicielle que je souhaitais. 
Maintenant j'attends qu'elle arrive pour suivre à la lettre les instructions du guide de remboursement en refusant les CLUFs et en formatant le disque après avoir pris les photos nécessaires à prouver que c'est bien le cas. Une fois ces préparatifs accomplis, la bataille pourra s'engager (bien que dell ait remboursé 180€ de logiciels + frais à un particulier au mois de décembre je sens qu'il va falloir insister un peu, si l'attitude du représentant de DELL auquel j'ai parlé est représentative.)
La suite bientôt.

27/01/2009

capture piped command status in ksh

The explanations I found are not so clear so I will write my own ... Consider the following script fail.sh:
echo "this is a failing script"
echo "this will fail after this line"
return 1
Now here is the problem, suppose this script needs to be called in the following form :
fail.sh | tee fail.log 
What happens if you check the return code ( $? ) of this command is that you will get a nice 0. The return code only gives you the return of the last command which was executed by the shell. In our example that would be tee and it worked fine, but we want to capture the failure in the middle ... The following is by no means original, I built it from various sources on the net:
exec 3>&1
status=`((fail.sh 2>&1 ; echo $? >&4)| tee fail.log >&3) 4>&1`
echo $status
Alright, so I assume you (like me) know that 1 is the stdout file descriptor and that 2 is the stderr file descriptor. But what the hell are 3 and 4 ?!
  • 3 is a copy of the stdout file descriptor.This copy is done with the initial exec command.Throughout the execution of the line, anything directed to it will get on the stdout of the wrapping script. Thus the tee output is redirected to it so we see the output of fail.sh on the terminal.
  • 4 is a file descriptor to a new buffer which receives the value of the exit code and is merged in stdout at the end of the command. Since the line is executed in backticks the stdout is stored in the status variable.
  • The 2>&1 is the classic merge of stderr in stdout for the fail command. this is useless here as our script doesn't output anything on stderr but it can come in handy with other scripts.

09/01/2009

Starting an Eclipse headless build from ant

The following snippet will allow you to start an headless eclipse instance and make it start an ant script:
<java classname="org.eclipse.core.launcher.Main" fork="true" failonerror="true" maxmemory="1024m" logError="true" resultproperty="eclipse.run.result">                            
  <arg value="-application"/>
  <arg value="com.ibm.etools.j2ee.ant.RunAnt"/>
  <arg value="-buildfile" />
  <arg value="${build.dir}\masterBuild.xml" />       
  <arg value="-data"/>
  <arg value="${workspace}"/>             
  <classpath>
    <pathelement location="${wid.home}/eclipse/startup.jar"/>
  </classpath>
  <jvmarg value="-Dlog.dir=${automation.home}/dailybuilds/output/logs"/>
</java>
I use this to run the Webspehre integration developper build process from cruise control in a cross platform way.