Wednesday, September 8, 2010

How to install python PIL

Installing PIL library using easy_install is easy as always. But it has some dependencies, that are not so obvious at first. In order to have support for JPEG, PNG and Freetype we need to install those development libraries as well.
So the whole command list is as following:

> apt-get install zlib1g-dev libfreetype6-dev libjpeg-dev
> easy_install pil

After PIL installation script is finished you should check for the following lines:
*** TKINTER support not available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
*** LITTLECMS support not available

as you can see JPEG, ZLIB and FREETYPE support is available now.

Saturday, April 24, 2010

Flex OLAP Aggregators Fix for Null and Undefined Values

There is very little information available on Adobe Flex data visualization components. Sometimes I even question whether it is used in production at all. In one of our recent projects we used OLAP components extensively. It is the first time I had to check out the source of component so often: to check out how it is supposed to work and to fix issues (and there are quite a lot).

Data visualization provides a set of aggregators: sum, average, count, max, min. But there is an issue how they handle null or undefined values. Result defaults to 0(zero) even if there is no value defined for given dataField in a dataprovider or all values are null/undefined. Maybe it is by design, but it is not how it is used in real world scenarios. For example, Flex chart components support null/undefined values and there is even interpolateValues property in LineSeries to handle exactly this situation.

Fortunately, it is easy to fix. Let’s look at mx.olap.aggregators.SumAggregator source code for example. There are 3 methods of interest to us: computeBegin, computeLoop, and computeEnd. First, computeBegin is called and you create a holder object where temporary data will be stored as aggregation proceeds. Next, there is a call to computeLoop for every object in dataprovider where you update your holder object. Finally, computeEnd is called where you compute the final result and return it back. You see, the problem is in computeBegin and computeLoop:

1: public function computeBegin(dataField:String):Object
2: {
3:   var newObj:Object = {};
4:   newObj[dataField] = 0;
5:   return newObj;
6: }
8: public function computeLoop(data:Object, dataField:String,
9:                             rowData:Object):void
10: {
11:   var value:Number = rowData[dataField];        
12:   if (typeof(value) == "xml")
13:     value = Number(value.toString());
14:   if (!data.hasOwnProperty(dataField))
15:     data[dataField] = value ;
16:   else
17:     data[dataField] += value;
18: }


In comuteBegin holder object is immediately initialized to default 0 value (line 4). We can simply comment it, because in computeLoop this case is handled (line 14). But computeLoop has its own problems. There is no check for null/NaN values. So, if some of data objects does not have a value for given dataField the whole result is broken. Another problem is line 12. How Number type variable is supposed to be of type xml is beyond me. This check should be done before casting to Number. Looks like untested and unreviewed code to me. But interesting thing is how it stayed this way for 3 years. Anyway, here is the fixed version for sum aggregator:

public function computeBegin(dataField:String):Object
return  {};
public function computeLoop(data:Object, dataField:String,
  var value:Object = rowData[dataField];
  if(value == null)
  if (typeof(value) == "xml")
    value = Number(value.toString());
    value = Number(value);
  if(isNaN(value as Number))
  if (!data.hasOwnProperty(dataField))
    data[dataField] = value;
    data[dataField] += value;

Other aggregators can be fixed just the same way.

Friday, April 16, 2010

How To: Tomcat 6, BlazeDS 3.2, Hibernate 3.5 (JPA 2), Spring 3, Maven 2 – Part 1

In the following series of articles I want to explore how to set up a RIA project based on the latest stable Java and Flex stack using Maven and Eclipse. One would expect it to be easy enough and it is, but as always evil is in the details.

Prerequisites: recent version of Eclipse(3.4, 3.5) and m2eclipse plugin from SonaType.

Creating Web Project in Eclipse with Maven Dependency Management

In one of my previous posts I have tried to express my love for Maven. Using it from command prompt is a pleasure: quickly generating projects from templates(archetypes), building, running test, packaging and deploying, all is good. These are repetitive steps that need to be automated and maven handles that quite good. But we also need our old good IDEs with all the features we are used to have and got addicted to. So we need to look at our project from several different perspectives. To do that we need to set our project so that Maven and Eclipse understand the format/structure.

There are two ways to go: create Dynamic Web Project in Eclipse and enable Maven Dependency Management in it or create new Maven Project and enable Dynamic Web Module Facet in it.

First approach is more appropriate when you have some project in progress and want to start managing its dependencies with Maven. You can accomplish this from Project context menu/Maven/Enable Dependency Management. But it is not enough, you will have to modify folder structure according to established Maven project structure standards. Your sources should be in src/main/java and web content should be in src/main/webapp. Then you will have to edit some configuration files. For example you need to edit wb-resource parameters in org.eclipse.wst.common.component file located in .settings folder, and some more.

It looks like too much manual modification of Eclipse managed and hidden(by default) settings files and that is why I prefer the second way (with some maven plug-in help of course). Here is a step by step explanation:

1. Create new Maven Project. Check “Create a simple maven project(skip archetype selection)” option and set packaging to WAR. You have a working maven project structure. No we would like to work with the project as if it is native eclipse dynamic web project.

2. But first you should modify your pom.xml file to enable Java version 1.5 (or 1.6, what ever you need). It is necessary,  because  by default Maven compiles java code as Java 1.4. We also need this configuration for the next step. Just add the following xml in you pom.xml file:


It may look like too much custom xml, but after you work with maven for some time those plugin/dependency/groupId/artifactId elements just become part of your programming lexicon and m2eclipse plug-in with its code completion really helps here.

3. Now from Project context menu select Run As/Maven build… with the following options:

Goals = eclipse:eclipse

Parameter Name = wtpversion, Parameter Value = 2.0

After you run this maven build you get standard Eclipse Dynamic Web Project with Java Facet and Dynamic Web Module Facet enabled. Check it out from Project Properties / Project Facets section. Now you can configure Targeted Runtime (Tomcat 6 in our case) and other possible configurations you need just the same way you did it before maven era.

In Part2 we will explore how to further edit pom.xml file and add BlazeDS support using excellent Spring framework.

Sunday, January 17, 2010

Speed up compilation process with Ram Disk

I often review my software development toolbox to check if I my development process is actually optimal. Recently I was looking around if there is something new in the area of compilation time improvements. There are classics like IDE settings for Visual Studio and even more for Eclipse, maximum amount of RAM (unfortunately my notebook has 4Gb limit) and speedy hard disk options like 7200RPM and SSD disks. But there is something new (for me at least). All of you are familiar with DVD disk virtualization utilities. But what if we could have a virtual RAM disk? Something like ramdrive.sys from MS-DOS times. Then we could put our complete project folder on that disk and theoretically the compilation process, which has lots of disk read/writes, should speed up.

Before you try this option on your current project I should remind you that in case ram disk fails you loose all your work since the last backup! All these utilities provide persistence to disk image file, but how do you know that it won’t be corrupted somehow. I hear you saying that you often commit to your source control, so do I. Then in case of your very unlucky day when everything just breaks you should lose at most a few hours of work.

Below is the list of utilities:

QSoft Ramdisk –  My choice. Commercial but free for 6 months and a good price. Just runs. Runs on 64bit Windows. Do not be afraid of their confusing web site :)

Dataram Ramdisk – Would be my choice. Commercial with free option for up to 4Gb size disks. Seems to be the most popular and convenient, but I could not run it on Windows 7 64bit (compatibility mode does not help)

Superspeed – another popular commercial utility with lots of features.

Farstone Virtual Hard Drive PRO – commercial. Seems to be a good option with good reviews on blogs.

Softperfect Ramdisk – commercial. I did not try it myself

VSuite Ramdisk – commercial. I did not try it myself.

Tuesday, January 5, 2010

Class Not Found Issue in Eclipse

Recently I have come across a really strange bug in Eclipse 3.4.2 version. After adding new java class Eclipse refused to find it. And suddenly, it marked all my custom class imports as not found. Cleaning project, restarting IDE would not help. If you experience the same problem there is a simple quick solution. All you need is to change “Default output folder” in Project Properties/Java Build Path. Once you change output folder all those “class not found” errors will go away. Strange enough, but now you can change output folder path to the previous value and it will still compile correctly.

I am not sure what is the real cause of this error,  one possibility is that maven plug-in somehow interferes with the process. If it is Eclipse itself then upgrade to 3.5 version may resolve this issue. Need to check.