Wednesday, November 4, 2009

Install Tomcat on Windows 7

I decided to install Tomcat (6.0) on Windows 7 for a project.

I downloaded "apache-tomcat-6.0.20.exe" directly from Tomcat website.

I installed it on "d:\".

Then I started it, but nothing happen, it was always at "stopped".
I check the log file, and I could see "[error] Failed creating java C:\Program Files\Java\jre6\bin\client\jvm.dll"

Copy the file msvcr71.dll (C:\Program Files\Java\jre6\bin\msvcr71.dll) to D:\Tomcat 6.0\bin

This website help me to find this solution: http://mandown.co.nz/development/getting-tomcat-apache-to-run-on-microsoft-windows-7/

If this didn't help you, you can have a look here: http://www.mkyong.com/tomcat/tomcat-error-prunsrvc-failed-creating-java-jvmdll/

Thursday, July 30, 2009

update rubygems

I tried to update rubygems on CentOs but could not.
First, I asked help to my friend Google and found this site: http://rubygems.org/read/chapter/3
It worked well on one computer but on another one I had this error:
/usr/lib/ruby/site_ruby/1.8/rubygems.rb:578:
in 'report_activate_error': could not find RubyGem session (>= 0) (Gem::LoadError)


I tried many things until I realized that "session" is actually a gem!
So let's do:
gem install session


Another error "could not find RubyGem hoe-seattlerb..."
So let's do:
gem install hoe-seattlerb


Same error with "hoe". But this one is tricky, because hoe need rubygems > 1.3.1, but to install rubygems 1.3.5 we need hoe!

update_rubygems
/usr/lib/ruby/site_ruby/1.8/rubygems.rb:578:
in `report_activate_error’: Could not find RubyGem hoe (>= 2.3.0) (Gem::LoadError)

gem install hoe
ERROR: Error installing hoe:
hoe requires RubyGems version >= 1.3.1


I tried to do (wihout success):
gem install rubygems-update #by default, it installs the latest version which is 1.3.5 now
update_rubygems


The problem is in version 1.3.5! First remove all rubygems:
gem uninstall rubygems-update

#Then
gem install rubygems-update -v 1.3.4
update_rubygems

#Then you can install hoe
gem install hoe


I lost so many hours for this stupid mistake...

Thursday, June 25, 2009

insert date in sqlserver

Recently I saw a strange behavior, and I don't know why. When I create a new object model and set its attributes, if I set the date, then in the DB it shows me the day before.

For example:

abc = ABC.find(:first, :conditions => "id = 1")
puts abc["date"] # 2009-06-25

#let's create a new object 'model' and set the same date as ABC
model = Model.new
model.date = abc["date"]
model.name = "a name"
model.save!


After, in Sqlserver management studio:

select * from model;

--date = 2009-06-24 15:00:00:000
--name = "a name"


So why it's not the 25th?? Is there a bad configuration somewhere? Well, I don't know. When I have more time, I'll try to understand why, but for now, to avoid this problem, I'm doing the following:

model.date = "#{abc["date"] }"

Thursday, June 18, 2009

asynchrone Ajax query problem

Can you find what's wrong in this code:

function example(event){
for(i = 1; i < array.length; i++){
new Ajax.Request(url, {
method: 'put',
postBody: someParam,
onSuccess: function(transport){
$(array[i]).innerHTML = "updated!";
},
onFailure: function(transport){
//do something
}
});
}
}

Description: let's say the array elements are all IDs of some tags "div". There is a loop, for each element an ajax request is send.
Hint: The "a" of Ajax stands for "asynchronous".
So where is the problem?

The problem is here:
$(array[i]).innerHTML = "updated!";

Why? Because we use "i"! Let's say the array has 10 elements. First (asynchronous) request is send (i=1), so our controller is working, and at the same time the loop continue, so now i=2, another Ajax request is send and so on. Now i=4 and... oh! the controller just finished is work for the first request, so the function onSucces is called, and then $(array[i]).innerHTML = "updated!". But "i" is 4 now! It's not 1 ! So we write "updated!" in the wrong div.

Here is my solution (maybe not the best one), I send "i" as a parameter to the controller and the controller return it.

function example(event){
for(i = 1; i < array.length; i++){
new Ajax.Request(url, {
method: 'put',
postBody: i, //send "i"
onSuccess: function(transport){
//get the response
original_i = transport.responseJSON;

$(array[original_i]).innerHTML = "updated!";
},
onFailure: function(transport){
//do something
}
});
}
}

Insuide the controller:

def my_controller
post_data = request.raw_post #here we received "i"
....
....
....
render :text => post_data #and we return it
end

Tuesday, June 16, 2009

Open flash chart save image (ruby+IE6)

Presentation: one of my tasks was to implement a feature to print a flash chart. To generate the chart, I'm using Open Flash chart 2, great open source, free, library to draw chart dynamically. I downloaded it from PullMonkey website (because I'm working on Ruby).

Now let's try to print the chart. After the chart is generated (can't print if no render), we can get the image as binary:

document.getElementById('divfMyChart').get_img_binary()
//return a base 64 image, something like this: R0lGODlhFGHGGHRGH..... (very long string)

More info about base64. And here is an example of a base64 image:



If your web site support only FireFox and IE8 (and higher) that's perfect, because there is no problem! Here is the code, it will create a new window with the image:

img_src = document.getElementById('divOfMyChart').get_img_binary();
img_tag = "";
var img_win = window.open("", null);
with(img_win.document) {
write("my image" + img_tag + ""); } //change "t-itle" for "title"

You can see a more complete examples here.
Now if you open your web page with IE6 or IE7 it won't work! Why? Now begin the most interesting part of this post.
Well, it's not working because IE6 and IE7 don't support base64 format. It's not even a problem of your server, so you can not do anything except to change your source code.
I could see there is a library in PHP who can create an image from base64 image (base64_encode($string);).
So is there a similar library in Ruby? Yes there is! It's RMagick. An interface to the ImageMagick and GraphicsMagick image processing libraries. Supports over 100 image formats, including GIF, JPEG, PNG.

Download RMagick (current version 2.9.2): http://rubyforge.org/projects/rmagick/
If you're using Windows, download "rmagick-win32"!
Extract the files from the archive, and read README.html. Please follow the "Installation instructions". It's easy to install. RMagick requires ImageMagick or GraphicsMagick, so installed one (only one!). You can find the installation files in RMagick website.

And we need something else, the PNG library: http://www.libpng.org/pub/png/pngcode.html
PNG library is divided into 2 libraries :
zlib:Zlib is designed to be a free, general-purpose, legally unencumbered -- that is, not covered by any patents -- lossless data-compression library for use on virtually any computer hardware and operating system.
Download "zlib compiled DLL, version 1.2.3": http://www.zlib.net/ Extract the files and read USAGE.txt. It's easy to install: copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory.

libpng:This is an open source project to develop and maintain the reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files.
download "libpng-1.2.37-setup.exe": http://sourceforge.net/project/showfiles.php?group_id=23617&package_id=16183 and install it.


So now you have everything!
We create a JS function who will send an ajax request (with the binary image) to the controller. The controller will create an image (jpg) on the server and return the path to this image. Then the JS function will create a popup to show the image.
In my view:

function printChart(event){
new Ajax.Request(urlForPrintImage, {
method: 'put',
postBody: document.getElementById('divOfMyChart').get_img_binary(),
onSuccess: function(transport){
image_path = transport.responseText;

img = "";
var img_win = window.open("", null);
with(img_win.document) {
write("My image" + img + ""); } //change "t-itle" for "title"
},
onFailure: function(transport){}
});
}

In my controller:

require 'base64'
require 'rubygems'
require 'RMagick'

def print_image
#get the parameter sent by ajax query
png_data = request.raw_post

#file name and path for the image file
#(you have to change this depending of your routes)
file_name = "myPath/chart.jpg"

#decode the binary image with Base64
blob = Base64.decode64(png_data)

#use RMagick to create an image from the blob
image = Magick::Image.from_blob(blob).first
#save the file on the server
image.write(file_name){ self.quality = 100 }

#return the file path
render :text => file_name
end