Flying-Saucer and embedded images

I’m using Flying Saucer library in order to convert a couple of html files to pdf and I reached a problem – it seems that the library was not able to render the base64 embedded images. Inspired by this post, I wrote an implementation of ReplacedElementFactory in order to implement this feature. It will replace only the base64 embedded images – all the other elements are going to be handled by the default factory.

You have to configure the renderer in order to use the factory:

ITextRenderer renderer = new ITextRenderer();
SharedContext sharedContext = renderer.getSharedContext();
renderer.getSharedContext().setReplacedElementFactory(
new ITextExtendedReplacedElementFactory(
sharedContext.getReplacedElementFactory(),
sharedContext.getDotsPerPixel()));

Uninitialized constant MysqlCompat::MysqlRes

Since I’ve started to work in Ruby I’ve been plagued a couple of times with the following exception “uninitialized constant MysqlCompat::MysqlRes”. It worked after adding the following lines to my bash_profile:

export DYLD_LIBRARY_PATH=”/usr/local/mysql/lib:$DYLD_LIBRARY_PATH”

Last week I’ve updated my OSX to version 10.7.4 and once again I had to deal with the same exception. It was quite frustrating and it worked only after using install_name_tool like this:

install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib /Library/Ruby/Gems/1.8/gems/mysql-2.8.1/lib/mysql_api.bundle

 

OpenX displaying wrong statistics

I have seen some strange results when running the website report – one zone is showing more than one million clicks but only three impressions. The issue is quite serious because you cannot compute the clickthrough rate. First I thought that is an OpenX bug especially after that I discovered some strange data in the ox_data_summary_ad_hourly table – a very large number of lines having zone_id equal with zero.

After digging in the code and thinking twice I remembered that I modified the original code for displaying the ads..so I used Charles in order to check if the invoked url’s. I discovered that the call used to log an impression was something like server/www/delivery/lg.php?bannerid=10&campaignid=9&zoneid=4. It seemed that by mistake I used “&” instead of “&” and the campaignid and zoneid parameters were lost. Because OpenX was not able to find the zoneid it inserted lines having the zone_id equal with zero.

The problem was solved – the idea is to never log an impression without setting the zone_id..or better to patch the OpenX code in order to properly check the preconditions – I would have been able to identify problem way earlier in this case.

OpenX – enabling advanced reports on CentOS

I’m using CentOS for my cluster and I discovered that I’m not able to run the advanced reports from OpenX – I received the following error: “Using an input encoding requires PHP support for mb_convert_encoding() and mb_strlen()”.

The solution is quite simple: you need to install the Php multibyte string library. The command for doing that is “yum install php-mbstring”

 

Invoking OpenX api from Flex

For the last several months I was playing with OpenX, an open source ad server written in PHP.  You can interact with OpenX in two ways: first by using the admin graphical interface, second by using API calls – most of the UI functionality can be programmatically reproduced.

OpenX is exposing its API through XML-RPC and they have a couple of examples on their website how to invoke the API from PHP, Java and Ruby. In my case I was trying to display some statistics without going through a middleware, so I started to investigate how can I do it from Flex. It turned out to be quite easy – one can use the AS3 RPC written by Akeem Philbert, with a small modification. The following steps should be done:

a) download the source code of the library from this location (http://code.google.com/p/as3-rpclib/)

b) you have to fix a small issue in the class com.ak33m.rpc.xmlrpc. XMLRPCObject  (compatibility issue between SDK’s). The overloaded methods setCredentials and setRemoteCredentials should receive another parameter, called charset.

c)create the objects mapping the OpenX structures (advertiser, campaign, zone etc) and invoke the exposed methods

I did these steps and I created this Flash Builder project – you can import it into your workspace and change the file ServerConfig.as accordingly.

In my example I have just a couple of operations like login, displaying and creating advertisers. It can easily be extended in order to support the whole OpenX api.

Next post on OpenX will be about displaying the ads on your website, from Flash and HTML.

BlazeDS – message selectors vs subtopics

Let’s assume that in a Flex/BlazeDS application you have a destination and a number of producers and  consumers associated to that. All the messages created by the producers are received by the consumers, and sometimes you don’t want that – you need to send the message only to a specific consumer or to a specific subset. For example you may have a chat application, so you should be able to offer features like private messaging or the ability to send messages only to some selected users.

In order to implement that you can use message subtopics and message selectors. Both options are described in details in BlazeDS manual, however an important detail related to them is missing – what are the advantages and disadvantages in both cases. Below I’ll try to write the most significant one, related to performance.

The advantage of using selector is the fact that you can define complex expression in order to filter the clients – for example you can use SQL92 conditional expression syntax when testing the message header. The producer can add a string in the message header and every message will be scanned using Consumer selector. The disadvantage is related to performance – every message will be scanned using the consumer selector, and if you have a large number of consumers it can significantly hinder performance, so one should be be careful when using it.

The advantage of using a subtopic is related to performance. BlazeDS will build behind a HashMap per subtopic containing all the associated customers. When a message is produced it will be send to the customers from the corresponding map, without testing for a condition. If the number of consumers with the same subtopic is small compared with the total of consumers the performance difference between selectors and subtopics can be very large.

In conclusion try to stick with subtopics – in most of the cases you don’t need the selector flexibility.

SQLLoader and ORA-04043

I had to import almost half of billion rows in one Oracle table and for that I wrote a small SQLLoader script (below):

"load data infile * append into table "usermonth....."

And I received the following error message

"SQL*Loader-941: Error during describe of table "usermonth"
ORA-04043: object "usermonth" does not exist"

After one hour of despair and I realized by pure luck that you need to provide the name of the table with upper case, otherwise the utility is not able to find it. Quite strange, but at least I’m happy that now it works.

Java exceptions and Flex

I’ve seen some articles on this subject but I have not found one dealing with all cases (webservices, BlazeDS, BlazeDS and Spring, data management). Also the approach for BlazeDS is different than the one used with Spring/BlazeDS integration, and this thing can be a little bit confusing for a beginner.

Let’s assume that you have a layer of services that should be invoked from your Flex application. You can expose these services as web services or as remote methods. Or you can use data management. The Java methods may throw errors and you want to display them in the Flex application.

For simplicity I will use a very short method as an example. The method signature is :

public String returnResults() throws DatabaseDownException;

There are four main use cases:

a)You have to write a webservice to return the result as XML. For example:

<?xml version="1.0" encoding="UTF-8"?>
<data>
<result>
</result>
</data>

In this case you will need to enhance your XML to add a structure for keeping error messages – like this:

<?xml version="1.0" encoding="UTF-8"?>
<data>
<result>
</result>
<error>
</error>
</data>

When building the XML the <error> body is going to envelope the exception message. Of course more information can be added, including exception type, severity, and so on. The same approach should be used also when working with SOAP services

b)You plan to use BlazeDS and Java remoting

In this case things are going to be easier,  because BlazeDS is able to automatically serialize the thrown exception and you can find the serialized exception in the FaultEvent object. Assume that you have the Java exception declared below. It extends the RuntimeException and it has a getter method for a custom field.

public class DatabaseDownException extends RuntimeException{
private String customField;
public String getCustomField(){
return customField;
}
}

The Flex code declares a remote object and registers a handler (which is also included) for failure.

<mx:RemoteObject id="test" destination="testDestination" result="resultHandler(event)" fault="faultHandler(event)"/>
private function faultHandler(event:FaultEvent):void{
var exception:Object = event.fault.rootCause;
Alert.show(exception.cause);
Alert.show(exception.localizedMessage);
Alert.show(exception.message);
Alert.show(exception.customField);
}

There are four fields in the serialized exception. The first three are inherited from the Throwable object, the last one is declared in your exception. It is interesting to note that you need not have a pair of set/get function in order to have your property serialized. The Throwable object is the only object in which  it is enough to have get methods in order to serialize the values (you can take a look at flex.messaging.io.ThrowableProxy to check that).

The only drawback is that you are working with untyped objects..if you don’t like that you can throw instead instances of flex.messaging.MessageException. This Java class is part of the BlazeDS and it will be deserialized using the class mx.messaging.messages.ErrorMessage (obtained from the event.message property).

You can add your custom data in the MessageException class using the extended property. For example:

MessageException messageException = new MessageException();
HashMap<String,String> map = new HashMap<String,String>();
map.put("clientName", "JOHN");
map.put("clientSurname", "MASTER");
messageException.setExtendedData(map);
messageException.setCode("ACCOUNT_DISABLED");
throw messageException;

And on the Flex side:

private function faultHandler(event:FaultEvent):void{
var errorMessage:ErrorMessage = event.message as ErrorMessage;
trace(errorMessage.extendedData.clientName);
trace(errorMessage.extendedData.clientSurname);
trace(errorMessage.faultCode);
}

You probably do not want to have an explicit dependence between your service layer and the BlazeDS libraries, so in this case you should build a delegate on top of it, which will also act as an exception translator.

c)Using Spring BlazeDS Integration

You have several benefits when using Spring BlazeDS integration, and if your middle tier is already using Spring it’s a must. The benefit related to exception handling is the exception translator mechanism. This translator will catch all the exceptions thrown from the services invoked from Flex and you can translate them into something more meaningful for the client.

First you need to declare the exception translator:

<bean id="exceptionTranslator" class="com.test.exception.ExceptionTranslatorImpl" />
<flex:message-broker services-config-path="/WEB-INF/flex/services-config.xml">
........
<flex:exception-translator ref="exceptionTranslator" />
</flex:message-broker>

The exception translator is below:

public class ExceptionTranslatorImpl implements ExceptionTranslator{
//handles all
public boolean handles(final Class<?> clazz){
return true;
}
public MessageException translate(final Throwable throwable){
if (throwable instanceof DatabaseDownException){
MessageException exception = new MessageException();
exception.setCode("FATAL_DB_DOWN");
return exception;
}
if ...........//check another things
}
}

Note that in the current version of Spring/BlazeDS integration it is mandatory to have an exception translator, otherwise the original error is going to be swallowed and you will receive some generic error.

d)Using data management

The same approach from point c) applies here. Basically your assembler – which is going to invoke some service to obtain/create data – will take care of translating the exceptions into something meaningful for the client. I wrote some time ago a short post about that here.

Note: this article was translated also in Belorussian (thanks Patricia), you can find it here.