Tuesday, February 24, 2009

Axis Dynamic Proxy Binding Tutorial

So you are accessing a SOAP Web Service that is being improved recently by their owners. They did not break previous functionality but they are returning an extra complex type member. Your code broke and the client you developed using WSDL2Java and static stubs does not work any longer.

The solution for this problem is called "Custom Serialization" and I have written a tutorial, result of my recent struggle with the issue. You can access it from here.

Thursday, February 12, 2009

Javascript ( JQuery ) Pagination

In every other WEB project you face you need pagination. I need to have this snippet at hand and so I have decided to post it here. I use JQuery and it is assumed I have a div#id=pagination nested into a div#id=content

function loadPagination(action, p, r, t){
var maxDirectPageLinks = 10;
var totalPages = t/r;
if(Math.floor(totalPages) != totalPages){
totalPages = Math.floor(totalPages) + 1;
}

$("#pagination").remove();
var start = 1;
var end = maxDirectPageLinks;

if(totalPages > 1){
if (maxDirectPageLinks < totalPages) {
if(p - maxDirectPageLinks/2 > 0 && p + maxDirectPageLinks/2 < totalPages) {
var start = p - maxDirectPageLinks/2 + 1;
var end = p + maxDirectPageLinks/2;
}else if(p - maxDirectPageLinks/2 < 0) {
var start = 1;
var end = maxDirectPageLinks;
}else if(p + maxDirectPageLinks/2 > totalPages) {
var start = totalPages - maxDirectPageLinks + 1;
var end = totalPages;
}
}else {
end = totalPages;
}
$("#content").append("
");
//$("#pagination").append("page " + p + " from " + totalPages + " pages for " + action + " (records per page/totalrecords=" + r + "/" + t);
if(p > 1){
$("#pagination").append("" + "Previous" + " ");
}
for(var i = start; i <= end; i++) {
if(i == p) {
$("#pagination").append(i + " ");
}else{
$("#pagination").append("" + i + " ");
}

}
if(p < totalPages){
$("#pagination").append("" + "Next" + " ");
}
$("#pagination").append("(" + totalPages + " total pages)")
}
}

Wednesday, February 04, 2009

IPhone SDK 2.2.1 with 2x faster Javascript

I was surprised when I finished deploying my application in an Ad Hoc IPod Touch device after seeing it was running faster than in my develoment IPhone.

The application makes heavy use of the WebKit and I was experiencing 5-6 seconds delay between heavy Views (6K JSON data) when deployed to the IPhone but it went down to 3-4 when I deployed into the IPod Touch. Considering sqlite takes around 2 seconds in either case we are definitely getting a 2x Javascript performance increase (faster JavaScript execution).

The reason for the boost? A new 2.2.1 version in the Ipod Touch (I have 2.2 in the Iphone).

Wednesday, January 28, 2009

Using Jar Class Loader (JCL) to reload classes from a JAR

I have been playing recently with JCL to load classes on demand from a jar file.

The immediate use of this is to build a plugin engine. A jar file might contain some code that can change without the need to restart the application using it.

Suppose you are told there is a specific functionality that should be changing regularly without affecting your server uptime. If you are behind a simple server container using WAR deployments you could use this method to ensure no WAR redeployment is needed when your functionality is in fact improved/changed.

I have put a running sample on SVN (JDK 5 needed, if you need to support a previous version just download jcl and compile it yourself).

To see it in action just run run.sh (using linux this time). If you are running Windows just get the *.sh files and provide similar *.bat files. Yes I know, Ant is cross platform and I should have used it for this post. Next time I will use Ant and even Maven ...

You will get full traces of what is happening every two minutes. Change constant 'version' in PluginImpl.java and run build-plugin.sh to see how the trace message is updated with the new version showing you can change your java class implementation at any time and your application does not need to be restarted.

I should remark here that when used from an application server like JBoss which uses its own class loader it is necessary to add the interface package to the newly created class loader (use jcl#add() for it). However if the plugin class refers directly to some classes in the current class loader jcl#add()-ing individual packages would be overkilling. You need then to use a custom loader like:
package mypackage;

import org.apache.log4j.Logger;

import xeus.jcl.loader.Loader;

class MyLoader extends Loader {
private Logger logger = Logger.getLogger(EISLoader.class);

public MyLoader() {
order = 4;
}

public Class load(String className, boolean resolveIt) {
Class result;
try {
result = this.getClass().getClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
return null;
}

if (logger.isTraceEnabled())
logger.trace("Returning class " + className + " loaded with parent classloader");

return result;
}

}
Then later use that loader as in:
MyLoader loader=new MyLoader();
loader.setOrder(4);
jcl.addLoader(loader);

I also found problems with log4j since JBoss uses its own and it might be old you might get:
java.lang.NoSuchMethodError: org.apache.log4j.Logger.isTraceEnabled()
At least in the case of JBoss 4.0.4 I managed to solve the problem using log4j-1.2.15.jar renamed as $JBOSS_HOME/lib/log4j-boot.jar and $JBOSS_HOME/server/$configuration-dir/lib/log4j.jar.

We can also go by ourselves and try to get this done without any special library using UrlClassLoader however I have done some tests and this solution appears to work in Windows but not in Linux. Once the plugin class is loaded the first time any further replacement will not be noticed in my Ubuntu Intrepid 2.6.27-9-generic Kernel.

Friday, January 16, 2009

Deploying applications to IPhone

While developing my first application for the IPhone I had fun. I really enjoy Objective-C messaging style and its dynamic capabilities. The simulator was really cool provided my previous experience with other device simulators.

However I was starting to get really desperate after finding too much problems when trying to deploy (using the official and legal way) the application to the real device.

I found then an excellent post that saved me perhaps several more hours of troubleshooting.

Later I was asked to deploy the application to several other phones. This time the existence of old and new profiles, several Xcode windows opened and lack of project info updates made me lose some more time so I am documenting here what I found as a solution:

. Delete all (related to the application to be deployed) files from ""~/Library/MobileDevice/Provisioning Profiles"".
. Close Xcode and ITunes. IPhone must be disconnected from PC.
. Open Xcode
. Drag the developer and the ad hoc profiles to the Xcode dock icon
. In Xcode select Menu|Window|Organizer and expand "Provisioning Profiles" on the left pane. You must have there two profiles (dev and ad hoc)
. On the IPhone select Settings|General|Profiles and delete any previous installed profiles (at least those related to the application you are trying to deploy)
. Connect the IPhone to the PC and check the profiles (dev and add hoc) are installed using Settings|General|Profiles
. From Xcode open the project and select Menu|Build|Clean All Targets
. Click on the project root folder on the left pane and select Project|Edit Project Settings
. Navigate to Build tab and locate "Code Signing" section. click on the value for "Code Signing Entity/Any IPhone OS Device" and select the value under the Dev profile.
. Build and Go

Thursday, November 20, 2008

Gmail Terminal Theme



I am a big fan of separation of concerns in my projects. Good implementations are so successful when they adhere to this simple concept. Think about the seven layers of the OSI Model or the MVC pattern applied to Web applications.

I simply liked too much GMail Console Theme to miss it here as a good example of how flexible a web application becomes when the concerns are handled in different layers.


Saturday, November 01, 2008

Picasa Slideshow: Creating a Google Gadget

A Google Gadget can be any HTML fragment and so it can contain any logic provided you use Javascript.

As soon as I got a couple of Gadgets in action I felt the necessity to play myself with them. Then I decided to build one which I think could be useful for others.

It is inspired in a good explanation[1] about how to embed a "Picasa Slideshow" (and others picture sharing sites) in a web page.

Take a look at the html page generated from the page that will be included in the XML file specifying a Google Gadget.

Sniff into the code.

Take a closer look to the whole URL. It starts with http://www.nestorurquiza.com/googlegadgets/picasaslideshow. I have hosted a simple Python script there which just accepts a GET parameter (see below) containing an RSS Picasa Album Feed to create a Slide show.

As mentioned above, you need to provide a parameter called rss which is basically the RSS link you can get from your preferred Picasa album. For the example I have used the same from [1]

After you have customized the URL including your own RSS and confirm it works like expected you need to URL Encode the whole customized URL (You can use one of the zillions of Online URL Encoding pages you can find in the WEB. Just Google it!)

Now you need to host an XML file with a similar format like the one you can find at http://localhost:8081/googlegadgets/xml/picasaslideshow.xml. Note the "href" attribute of the "Content" node which contains the custom encoded URL.

The XML URL from above will be used now from the "Add any Gadget From URL" Gadget as I explained in a previous post[2]

Now you can enjoy a slide show (or many since you just need to produce an XML file per album) of your favorite Picasa album in the left pane of your GMail WEB interface.

Of course if you get serious about Gadget programming you could use the official catalog directory[3] from Google to publish them, join the Google Gadget team and so on.


[1] http://philippe.chappuis.googlepages.com/slide-show-media-rss
[2] http://thinkinginsoftware.blogspot.com/2008/10/google-gadgets-everywhere.html
[3] http://www.google.com/ig/directory

Followers