21/01/10
Kawa Camp Paris la première
Moins orienté Java toujours destiné aux caféinés, on espère que les sujets abordés au kawa camp seront un peu plus variés.
Les tags déjà inscrits sont prometteurs :)
Le kawa camp Paris 1 c'est le 3 février et ça se passe là :
http://barcamp.org/KawaCampParis1
25/08/09
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/09
Eclipse 3.5 and Glassfish
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/09
JavaCamp Paris 5ème édition
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/09
Cool iris
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/09
Impressions of TDD
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
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/09
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/09
Headless gecko browser attempt 3
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
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/09
Headless gecko browser attempt 1
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/09
Strobist info
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/09
We are linux
What it means to be free
The Origin
Linux Pub
06/04/09
Java Barcamp Paris 4 : Spring3
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 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é :