Monday, December 27, 2010

Check XPath in Firefox with Firebug

There is easy way to check any XPath expression in Firefox if you have Firebug plugin. Just type:

$x('//a')

with your XPath expression and it will output list of matched elements, so you can click it and see on the page. Very handy to check Selenium XPath selectors.

Monday, November 15, 2010

Debugging grails in Netbeans

Grails plugin for Netbeans lacks some must have features like test launching from IDE and so on. Fortunately, Grails debugging is still super-simple with Netbeans. All you have to do is to run Grails from console with grails-debug instead of simply grails. For example, you want to debug test SeleniumTest.
Just type command in command console:
grails-debug test-app functional: SeleniumTest
Then go to Netbeans and select from menu Debug > Attach Debugger..., by default there is JPDA debugger, connector - SocketAttach, just enter your host and port (default is 5005, you can see yours in Grails console). Press OK. And it should connect to Grails process, so it will stop on breakpoints. Easy.
One thing to notice is that if you want to evaluate some expression in debug mode, you should use Java, but not Groovy, at least now.

Saturday, August 7, 2010

Local git setup error

Recently I decided to check GIT. I am old fan of Tortoise tools and I decided to start with TortoiseGit. It is nice tool with familiar interface.

I am a little familiar with Mercurial and heard that they are quite similar in concepts. So I started by creating repository by command “Git create repository here”.
Then I created “Git Clone” of my repository in new folder. Then I started to play and created new files and commited changes. But then, when I tried to push my changes to master repository I got big ugly error:

git.exe push    "origin" master:master

remote: error: refusing to update checked out branch: refs/heads/master        
remote: error: By default, updating the current branch in a non-bare repository        
remote: error: is denied, because it will make the index and work tree inconsistent        
remote: error: with what you pushed, and will require 'git reset --hard' to match        
remote: error: the work tree to HEAD.        
remote: error:         
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to        
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into        
remote: error: its current branch; however, this is not recommended unless you        
remote: error: arranged to update its work tree to match what you pushed in some        
remote: error: other way.        
remote: error:         
remote: error: To squelch this message and still keep the default behaviour, set        
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.        
To C:\########
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:\########'

This was quite confusing and error is not helping much. Also this scenario was working nicely with Mercurial, so I was really confused. But after some googling I found really nice article about git at http://cworth.org/hgbook-git/tour/, and it is explained nicely how to create repository that can be used with “push”. You just have to create it with

git --bare init --shared

It is really strange that there is no any option that can be set while creating repository and you still have to do it command line way. But issue was solved.

Sunday, June 20, 2010

Wildcards in CLASSPATH

I am a little bit ashamed, but I didn't knew that since version 6, Java supports wildcards in classpath definitions. It is not that important nowadays when everyone is using build tools and IDEs, but still, it is nice that it exists. I guess for me it would be hugelly usefull some 10 years ago.

More information at http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html

When Greasemonkey scripts run?

Recently I found one interesting thing about Greasemonkey. I was moving my scripts from JQuery to plain Javascript and changed $(document).ready() to window.onload() and my script stopped to work. After investigating a while I found that $(document).ready() is called also AFTER document is loaded and window onload obviously only when onload event is fired. This is interesting feature by itself, but I was surprised that Greasemoneky code is called only after document is loaded. Somehow I was not thinking about it this way with many many years of onload usage.

Anyway this is great, because my Greasemonkey scripts looks much cleaner without these unnecessary callbacks - just plain logic.

Tuesday, June 15, 2010

Spring Roo with GWT

I tried Spring Roo recently and there are my comments about it.

Spring Roo is a tool that automates application development and configuration. It is like Maven, but Maven automates project setup and development tasks, and Spring Roo automates application development and tools integration.

Good:

1) Great idea. No doubt it is really good idea to speed up setup and scaffolding of java application. As most of them use the same set of technologies (Maven, Hibernate, JPA, Spring, Struts, jQuery, Selenium, AspectJ, JUnit) and if you have to configure everything by your own it can easily take hours (I wonder if there is competition for fastest java project setup like: fastest Maven+Struts+Spring+JPA, fastest Ant+Spring MVC+Spring+JPA). There is defenitely no need to be so.

2) Fast. No need to do it manually.

3) No dependency. At one point, there were already prebuilt setups in form of application servers, but then you have lifetime dependency on application server. With Spring Roo there is no dependency - you can loose it any time. This is also great feature. In contrast, Grails is another great tool, but also creates dependency.

Improvements:

1) Configurable tools. It is already there at some point, but what I mean it is like to have ready setups for different tools. Like setup Spring+Struts+Hibernate+Ant+jQuery application, or another setup Spring+Maven+Spring MVC+Hibernate+GWT.

2) Aspects overuse. There is one funny approach to entity files: it creates one aj file for every use case for specific. Like there is one aj file for toString method, one aj for persistence operations, one aj for properties, one aj for setters and getters, one aj for @Configurable annotation. Total 5 files per entity. I have never worked with such approach, but it looks strange to me. It is good if it at least could be configured.

Conclusion:

It is great idea. I would be totally happy if there would be tool that can create ready setup with some example stubs where I just have to pick necessary tools, like:

create helloWorld --with spring, struts, hibernate, hypersonic, junit, jquery, selenium, jpa, rest, etc.

and it generates typical helloWorld with this info. I am happy. If it can create some entities - it is totally great.

Unfortunately, I don't think that Spring will support much of rival tools like Struts, Guice, JBoss, etc. And it will make it 99% less usefull for most users.

Friday, May 28, 2010

offsetHeight is 0 in Internet Explorer

Recently I had interesting issue while testing project in Internet Explorer. I have iframe burried under a long list of elements whose parent's height is updated by AJAX callback from iframe itself depending on iframe content height. In other browser everything works smoothly but in IE there is issue that document.body.offsetHeight is 0. I was digging issue and tried to debug it and finally noticed that when I stop with debug on the line that returns height - it showed correct number - and without debug still zero. I noticed that I had document.body opened on my watch list. After removing it - offsetHeight is again 0.

So there was some element in document.body that after being called, fixed offsetHeight to normal. And after small hack
    for (val in document.body) {
      var before = document.body.offsetHeight;
      document.body[val];
      if (before != document.body.offsetHeight) {
        alert(val);
      }
    }
I found that this magic element is filters and when it is called like
document.body.filters; 
it magically fixes documents offsetHeight.

Thursday, May 27, 2010

Logging in Struts 2

Struts 2 provides a lot of logging information. To enable it in debug mode, just create log4j.properties file in classpath and add the following content:

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n 

"There is no Action mapped" error for Struts 2 in Jetty

Recently I was trying to configure Struts 2 with Jetty. Everything was running smooth untill I tried to setup Convention plugin.

This plugin provides configuration by convention rather than XML files and has several nice features like annotation mappings for methods and reasonable default mappings. Nice plugin overall but somehow it didn't wanted to work with Jetty. It was finding JSP files without problems, but totally ignored my Actions.

I had this error:

There is no Action mapped for namespace / and action name ########. - [unknown location]
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:178)
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
...


After experimenting for some time, I found that there is some mess with Jetty class loaders and to solve it there is nice configuration property for plugin itself. If you have the same issue you can fix it by adding

  <constant name="struts.convention.exclude.parentClassLoader" value="false" />

to your struts.xml file.
Ironically, good old configuration solved convention plugin issues.

Thursday, May 20, 2010

How to create windows service from Java application

It is relatively easy with Java Service Wrapper. It is described with JBoss example at http://wrapper.tanukisoftware.org/doc/english/integrate-simple-win.html. But actually it is even easier, so I'll try to describe it here.

Let's assume there is some ready application with public static void main method in my.company.Application class.

First, you will need to download Wrapper from here. Unpack it to some folder, better in C:/ or some short folder, I had some problems with running it from deep folder hierarchy.

Second, you will need to update configuration file at "conf/wrapper.conf". Actually, it is quite long (mostly because of comments), but worth checking as it contains mostly necessary information. You will have to update:

# path to java
wrapper.java.command=java
# this is service launcher, leave it as is
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# jars related to wrapper
wrapper.java.classpath.1=../lib/wrappertest.jar
wrapper.java.classpath.2=../lib/wrapper.jar
# all jars related to your application
wrapper.java.classpath.3=../mylib/jetty-continuation-7.0.1.v20091125.jar
wrapper.java.classpath.4=../mylib/jetty-http-7.0.1.v20091125.jar
...
# your application class that contains main method
wrapper.app.parameter.1=my.company.Application
# all parameters, when needed
wrapper.app.parameter.2=param1
wrapper.app.parameter.3=param2
...


Update other parameters if needed, but better at least check them. There is valuable and handy stuff like service name and description.

Third, run bin/InstallTestWrapper-NT.bat.

You service is installed and ready. You can start it from Administrative tools or with bin/StartTestWrapper-NT.bat.

Intellij IDEA debugging trick

Recently discovered one nice debugging feature in Intellij IDEA.

Sometimes it is needed to stop on breakpoint after some other breakpoint was executed. For example there is next code:

1:parent.method(1);
2:parent.method(2);
3:parent.method(3);
4:parent.method(4);

5:void method(int i) {
6: init();
7: doStuff(i);
8:}

You want to stop on line 7 when parameter is 4. Using only basic breakpoints, you will have to skip 3 first stops or use some breakpoints conditions, which is not always handy for some types of parameters.

In Intellij there is nice feature, that let's you specify dependency between breakpoints. So, in this example, you will have to put breakpoint 1 on line 4 and breakpoint 2 on line 7 and configure breakpoint 2 to depend on breakpoint 1. Then breakpoint 2 will only stop after breakpoint 1 was executed.

Nice feature that saved some time for me.

Saturday, April 24, 2010

Switching components in Swing with MigLayout

During Swing application development, I had a situation when at one location I had to display one component or another, based on third component value.

Normally, I would have to create some tricks with sizes or remove items from layout, but with MigLayout this is fantastically easy.

There is magic parameter "hidemode". If you set this value to 2 it will automatically shrink element's sizes to 0 when they are hidden.

So complete solution is to put all switchable parameters to same cell and set this "hidemode" to 2.

panel.add(inputField, "split 2,hidemode 2");
panel.add(comboField, "hidemode 2");

Now, when you need to show one element, you just hide other and vice versa.

inputField.setVisible(true);
comboField.setVisible(false);

Writing binary data between Java and Python

I have small project where server-side is done in Python and client is J2ME application and they have to talk to each other. At one time I had JSON to do it, it is quite easy on both sides, there are nice libs both for Java and Python. But recently, as traffic was growing and JSON performance on J2ME is not suitable for my tasks, I decided to try Java serialization with data streams.

For Java it is trivial:

DataOutputStream daos = new DataOutputStream(baos);
daos.writeLong(value1);
daos.writeInt(value2);
daos.writeBoolean(value3);
daos.writeUTF(value4);

In Python there is no such thing, but there is nice utility package called struct. It basically allows to read and write binary data and convert it into normal data. It is configurable and with small experimenting it is possible to find matching reading and writing functions for Java counterparts.

For example to parse example that is written above:

result = struct.unpack('>II', input1)
value1 = (result[0] << 32) + result[1]
result = struct.unpack('>i', input2)   // result[0] becomes value2
result = struct.unpack('>b', input3)   // result[0] is 1 for true and 0 for false


With strings it is a little bit trickier, because with method writeUTF, Java writes string length as 2 byte number and UTF-8 string. So in Python it is:

result = struct.unpack('>H', input4)
result = input5 // it is already acceptable for Python, just calculate result[0] bytes from input

Similar is also writing from Python to Java; same data formats are good for Java reading.

There is nice trick in Python, it allows to unpack and pack a lot of parameters simultaneously, for example this example above can be shortened to:

result = struct.unpack('>IIibH', input6)  // result array now contains all unpacked values except string 

Thursday, April 8, 2010

Logging in Java Web Start

It is quite easy to use logging in Java Web Start applications - normal Java logging and System.out works just fine.

Basically, to work it first should be enabled from "Java Control Panel" and later logs can be found at specific folders.

It is described in details at http://java.sun.com/j2se/1.5.0/docs/guide/deployment/deployment-guide/tracing_logging.html.

Disable cookies in Java Web Start

I was creating application for Java Web Start that works with URLConnection. At some point, I have noticed strange behavior: for same requests I was receiving different responses. Digging deeper, I found that it was sending cookies that I was creating in browser by regular site browsing.

This became interesting and I googled it and found interesting document. So using browser cookies is actually a feature and was intentionally done and worked in Java Web Start and Java Plug-in applications.

For my case it was totally undesirable and I wanted to turn it off. Fortunately, it can be done quite easily (though more complicated then it should be):

       CookieManager cookieManager = new CookieManager();
       CookieHandler.setDefault(cookieManager);
       cookieManager.setCookiePolicy( CookiePolicy.ACCEPT_NONE);

Input Validation in Swing

Swing provides built-in text field validation. JComponent has method "setInputVerifier" and this method accepts implementations of abstract class called InputVerifier. InputVerifier has only one method that developer has to implement:

boolean verify(JComponent input)

This method must return true if input is valid and false otherwise. It cann't be easier.

However there are some glitches. For example, it seems that it only hijacks focus for text components, because checkboxes and buttons remain clickable and fully functional. To overcome this problem (and also for usability) I started to show JOptionPane on invalid inputs. Now, when my text field tries to loose focus, JOptionPane hijacks it from targeted buttons or checkboxes and shows error, and after disappearing text field is again focused.

    port.setInputVerifier(new InputVerifier() {
      public boolean verify(JComponent input) {
        String value = port.getText();
        int port = -1;
        try {
          port = Integer.parseInt(value);
        } catch (NumberFormatException e) {
        }
        if ((port > 0) && (port < 65535)) {
          return true;
        } else {
          JOptionPane.showMessageDialog(settings, "Port must be number between 0 and 65535", "Input error", JOptionPane.ERROR_MESSAGE);
          return false;
        }
      }
    });


So it works fully as expected. Basically, this simple use case is exactly what I needed, so I am quite happy with this InputVerifier. However, for some more advanced or trickier situations there maybe still necessary to create some little custom framework.

Wednesday, March 31, 2010

Miglayout

Recently, found amazing Swing layout manager called MigLayout.

Compare this GroupLayout:

    GroupLayout layout = new GroupLayout(infoPanel);
    infoPanel.setLayout(layout);
    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);
    GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
    hGroup.addGroup(layout.createParallelGroup().addComponent(typeLabel).addComponent(formatLabel).addComponent(idLabel).addComponent(resultLabel));
    hGroup.addGroup(layout.createParallelGroup().addGroup(layout.createSequentialGroup().addComponent(typeUser).addComponent(typePlaylist).addComponent(typeFavorites)).addComponent(formats).addComponent(id).addComponent(result, GroupLayout.DEFAULT_SIZE, 400, GroupLayout.DEFAULT_SIZE));
    hGroup.addGroup(layout.createParallelGroup().addComponent(typesGap).addComponent(formatsGap).addComponent(generateButton).addComponent(copyButton));
    layout.setHorizontalGroup(hGroup);
    GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
    vGroup.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(typeLabel).addGroup(layout.createParallelGroup().addComponent(typeUser).addComponent(typePlaylist).addComponent(typeFavorites)).addComponent(typesGap));
    vGroup.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(formatLabel).addComponent(formats).addComponent(formatsGap));
    vGroup.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(idLabel).addComponent(id).addComponent(generateButton));
    vGroup.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(resultLabel).addComponent(result, GroupLayout.DEFAULT_SIZE, 200, GroupLayout.DEFAULT_SIZE).addComponent(copyButton));
    layout.setVerticalGroup(vGroup);


to this MigLayout:

    JPanel infoPanel = new JPanel(new MigLayout("", "[][grow][]", "[][][][grow]"));
    infoPanel.add(typeLabel, "");
    infoPanel.add(typeUser, "split 3");
    infoPanel.add(typePlaylist, "");
    infoPanel.add(typeFavorites, "wrap");
    infoPanel.add(formatLabel, "");
    infoPanel.add(formats, "wrap");
    infoPanel.add(idLabel, "");
    infoPanel.add(id, "growx, width 30::");
    infoPanel.add(generateButton, "wrap");
    infoPanel.add(resultLabel, "top");
    infoPanel.add(result, "grow, width 30:300:, height 10:100:");
    infoPanel.add(copyButton, "top");

Both pieces of code layouts form the same way, but code for GroupLayout looks squared compared to MigLayout. And I was thinking GroupLayout is good!

It is absolutely amazing how more undestandable it is compared to any other layout and how powerfull it is. I have created my form in 5 minutes after reading "Quick Start" guide. This MigLayout is also available for SWT and JavaFX, so maybe JavaFX is not that bad after all (except for textareas).

JavaFX

For new project, I need to create desktop UI. Of course there is good old Swing, but it is good known for his flaws and it is always interesting to pick something new and sexy. JavaFX got some buzz lately, so I decided to try it.

There are several installation of JavaFX, I decided to go with simple SDK. Installation was ok, I had to update my JDK to 6u18. From development process perspective I was not expecting anything fancy, nice Ant task to compile files was completely sufficient. Compiled code runs simply by Java runtime, no special tools needed - just bunch of new libs. So there is little overhead over any classic Swing application, that can run on plain JDK.

JavaFX has it's own language, which looks like some mix between JSON (visually) and HTML (idea), plus it can hold scripts. Language is quite ok, but in my opinion desktop requires more separation between layout, styles and code like in web development, but here again everything is mixed like in Swing. But anyway, language is quite ellegant and is easily understood.

Stage {
    title: "Test"
    scene: Scene {
        width: 300
        height: 250
        content: [
          VBox {translateX: 10 translateY: 10 spacing: 20
                content: [
                     HBox {spacing: 5
                       content: [
                         Label {text: "Field:"}
                         Button {text: "Button1" strong: true }
                         Button {text: "Button2" strong: true }
                       ]
                     }

Minus is that language is not supported by my Intellij, but there are plugins for Eclipse and NetBeans.

But what totally disapointed me was that it is looks very raw and not ready for production use. For example, there is no textarea (TEXTAREA!!!),  there are only basic layouts like grid and horizontal/vertical boxes. In Java 6 there is already GroupLayout, it even looks the same way as JavaFX, but still for some reason it is not part of it. There is general feeling that it is more like some fancy toy, but not usefull tool to do things. What kind of form can one build with grid layout?

There is one interesting concept though. Which maybe even future of layout managers - it is called binding. I have not seen anything like it before and to me it seems really interesting. It is possible to bind one parameter to some variable or variable expression, and when this bound variable changes, initial parameter is updated. So for example, you can bind start of textfields to maximum value of labels and this way to have nicely aligned form.

Anyway, even if there are some cool and promising features, I needed textarea and some normal layout for forms, so I decided to stick with Swing just for a while more.

Maybe I'll have more luck with Griffon.


UPDATE:
There was article on JavaLobby with link to another article about upcomming features in JavaFX 1.3. And it already looks a little bit better with Textarea and CSS. So I'll wait for next version.

Full article at http://learnjavafx.typepad.com/weblog/2009/12/javafx-13-leakage-at-devoxx-and-%C3%B8redev.html.

Tuesday, March 30, 2010

Gradle

For one new project I have had to choose new build tool. I know Maven and Ant for long time already and heard about Gradle here and there. So I have decided first to check these tools, and only look for something else if they will not be good for me.

My project is quite small and I was not going to configure it a lot, so some all-in-one tool would be great, however some customization would be still nice.

So Ant is good that it is extremely popular and robust and can be extended and customized quite easily. Big minus for me is that it does not have build in dependency manager, so I have to download and additionally configure Ivy. Also, I have to configure absolutely everything, there is no defaults like in Maven.

Maven is good, because it has these defaults, like compile, test and build. It has also dependency manager, which is great. Unfortunately, it is not easily customizable, and I need customization. For example, for Java Web Start project I need to sign all dependency jars (in Maven there is only plugin to sign build jar), I also need to upload automaticaly my jars and other files to Google Code.

So here comes Gradle. In short it combines good things from both Maven and Ant: includes dependency management (via Ivy, but with native Gradle integration) and has predefined tasks like Maven; all extension in one same build file like with Ant and natively can call Ant tasks - so you don't have to throw them away or rewrite everything.

Plus, there is also one (and not so little) bonus: no XML, all configuration is in Groovy, which is both: sexier and easier. There is only one minus I can see so far - it is quite large, about 20M, probably because it packages Groovy inside it, but anyway it is not show stopper for me.

Few examples:

Dependency definitions:

dependencies {
    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-util', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '7.0.1.v20091125'
    compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

Dependencies are downloaded from Maven repository by default.

This is simple task that cleans and creates folder for libs and signs all runtime dependencies:


task copyAndSign() << {
    ant.delete(dir:'build/signed')
    ant.mkdir(dir:'build/signed')
    for(file in configurations.runtime.resolve()) {
      ant.signjar(destDir: 'build/signed', jar: file, alias:"myself", keystore:"myKeystore", storepass:"123456", preservelastmodified:"true")
    }
}

It uses Ant tasks to do actual job.

This task signs jar file after running JAR task, of course it will be run also after any task that depends on JAR task.


jar.doLast {
  ant.signjar(destDir: 'build/signed', jar: tasks.jar.archivePath, alias:"myself", keystore:"myKeystore", :"123456", preservelastmodified:"true")
}


You can also define custom Ant task from Gradle.

ant {
  taskdef( name: 'gcupload', classname: 'net.bluecow.googlecode.ant.GoogleCodeUploadTask', classpath: 'ant/ant-googlecode-0.0.2.jar' )
}
task uploadAll << {
  collection = files { file('build/signed/').listFiles() }
  collection.each { 
    ant.gcupload(username:gcusername, password:gcpassword, projectname:"project", 
        filename:it, targetfilename:it.name, summary:"automatic", labels:"")
  }
}

Wednesday, March 17, 2010

Tuesday, March 16, 2010

Code bubbles IDE

There is  buzz in java world about new IDE concept. Idea is that it combines contexts and helps to keep all related files and information around tasks and ideas, but not around files and classes like traditional IDE.
Generally it is the same Mylyn idea, maybe better implementation, but should be tried.
Interesting presentation anyway.

Sunday, March 14, 2010

Ajax mock

One thing missing in QUnit and other javascript frameworks that I was looking for is mocking. Mock is object that replaces some complicated system, to simplify tests.
For example, I want to test javascript that I have ajax calls.

function serverSideSum(v1, v2) {
  $.post('http://localhost/sum', {val1: v1, val2: v2}, function(data) {
    $('#result').text(data.result);
  });
}

Normally, to make them work I have to run server that would answer to my calls. There is a number of problems
  • It is much slower compared to normal javascript tests
  • It requires infrastructure
  • How to check that my javascript sends correct data?
  • How to validate response or be sure that server part is not broken
Other option is to replace calls to real server with artificial function calls that always returns good results.
  • It is fast
  • Runs without server
  • Can check input data
  • Server response is always as good as you need

It is very easy to create mock in javascript. You just have to redefine some function. For example in JQuery ajax calls are sent by calling $.post() and $.get()
methods. So mock can be:

$.post = function(url, data, func) {
  func({result:4});
};



We can check parameters too:

$.post = function(url, data, func) {
  equals(data.val1, 2);
  equals(data.val2, 2);
  func({result:4});
};

And complete test looks like:

test("server side 2+2=4", function() {
  $.post = function(url, data, func) {
    equals(data.val1, 2);
    equals(data.val2, 2);
    func({result:4});
  };
  serverSideSum(2, 2);
  equals(4, $('#result').text());
});

Nice, but what if there are several calls to same ajax method during one function invocation?
For example, our function will also get number of calls to server:

function serverSideSum(v1, v2) {
  $.post('http://localhost/sum', {val1: v1, val2: v2}, function(data) {
    $('#result').text(data.result);
  });
  $.post('http://localhost/counter', {}, function(data) {
    $('#counter').text(data.count);
  });
}

Finally we can update our test to something like:

test("server side 2+2=4", function() {
  ajaxMock([
    [{result:4}, function(data) {equals(data.val1, 2); equals(data.val2, 2);}],
    [{count:123}, function(data) {}]
  ]);
  serverSideSum(2, 2);
  equals(4, $('#result').text());
  equals(123, $('#counter').text());
});


Function ajaxMock has one parameter - array of objects, and every object represents one ajax call and consists of call results and function thatvalidates input parameters.
Implementation of this method can be something like this:

function ajaxMock(params) {
  ajaxCallsCounter = 0;
  ajaxCallsParams = params;
  var callback = function(url, data, func) {
    ajaxCallsParams[ajaxCallsCounter][1](data);
    func(ajaxCallsParams[ajaxCallsCounter][0]);
    ajaxCallsCounter++;
  }
  $.get = callback;
  $.post = callback;
}

All ajax calls are stored in memory. After ajax call, array index ajaxCallsCounter will be increased and will not be called again, so this ensures that all ajax calls are done only once and in correct order.
Additionaly, you can verify that all calls were made by comparing array index with it's length, like this:

equals(ajaxCallsCounter, ajaxCallsParams.length);

Tuesday, March 9, 2010

YouTube API issue too_many_recent_calls

I have application on Google App Engine that uses YouTube API.
Recently I got error message like:
too_many_recent_calls
Which started to pop-up more and more often.
I have investigated this quota issue and solved problem by adding developers key to all API requests. And it nicely resolved this issue.
My guess is that someone else from same sever started to use YouTube API, but when there is no developers key, YouTube tracks number of request by IP address or something.

Groovy and SQL

Today I needed to do some boring import into db for some predefined structure and decided to do it some new way, just to stretch brain a little bit. I decided to use Groovy, as it seems that it was made for such things.

GSQL is built-in feature in Groovy so it does not require any additional lib, but database driver lib is still needed.

Connecting to dabase is as easy as:

import groovy.sql.Sql
sql = Sql.newInstance("jdbc:oracle:thin:@########", "login", "password", "oracle.jdbc.driver.OracleDriver")

To iterate table it is only needed

    sql.eachRow("select * from get_data_from_table") {goal-> 
        ...
    }

And you can access table fields just as parameters.

To insert new row you just need to

    def display = sql.dataSet("add_to_table") 
    display.add(id:goal.goal_id, country:it, type:'P') 

Quick and simple, just what is needed for such kind of scripts.

My only dissapointment with Groovy today was Grape. My idea was to inject it into script and download Oracle drivers automatically, but for some reasons it didn't worked out and I didn't had time to investigate and fix it. I hope to try it next time.

import groovy.sql.Sql
sql = Sql.newInstance("jdbc:oracle:thin:@########", "login", "password", "oracle.jdbc.driver.OracleDriver")
langs = ['LV', 'LT', 'EE']

def update() { 
    def display = sql.dataSet("add_to_table") 
    sql.eachRow("select * from get_data_from_table") {goal-> 
        langs.each{ 
            display.add(id:goal.goal_id, country:it, type:'P') 
            display.add(id:goal.goal_id, country:it, type:'B') 
        } 
    }
}

update()

Sunday, March 7, 2010

Generics in Hibernate

Recently, I found one feature from Hibernate that I am missing. I have two identical tables that differs only by foreign keys. Looks like perfect case for generics. Like:

<class name="com.test.GenericClass<Reference>">

But it does not looks like Hibernate supports it. So finally, I had to create empty implementations for my classes. Like:

public class SpecificClass extends GenericClass<Reference>

Saturday, March 6, 2010

BDD - Behavior Driven Development

New interesting methodology that combines automatic testing and requirements specification. I love the concept for some time with Fitnesse, but here is another formalized methodology and buzzword. More about it here.

Method chaining issue

I met one interesting issue with method chaining today.
Method chaining is popular thing now, introduced by Martin Fowler and you probably seen it somewhere already, you can read about it here.
Generaly it looks like:

new HardDrive().capacity(150).external().speed(7200);

contrary to classic Java style

HardDrive hd = new HardDrive();
hd.setCapacity(150);
hd.setExternal(true);
hd.setSpeed(7200);


Today I found one funny issue with it. I got bug in this code:


parent.add(new Node()
.setName(name)
.setValue(value)
.setParent(parent))
.setId(id)


Of course, bug is trivial and easily found with debug. But what is bad with this bug, syntax is correct, so it is not discovered by IDE and it is not easily visible. For example, compare it to old style:


Node node = new Node();
node.setName(name);
node.setValue(value);
node.setParent(parent);
parent.setId(id);
parent.add(node);


Another minor bonus is that it is also easier to debug.

JSON formatting

Sometimes it is needed to format JSON to check it's content. Intellij IDEA and Eclipse do the job pretty well, but if these are not available it is easily possible in Google Chrome. To do it:
1) Go to Control the current page menu (document icon to the left of address input) then Developer/JavaScript console.
2) Enter console.log({qwe:123}) (where {qwe:123} is just any JSON object).
3) You got nice JSON object tree as output.
There is some noise from Chrome, but it is possible to see and browse your object.
Same feature is in Firefox with Firebug plugin, even the same syntax.


UPDATED: Nice online JSON formatting tool: http://chris.photobooks.com/json/default.htm .

Friday, March 5, 2010

Javascript unit testing

Javascript unit test framework is just plain html file loaded in browser, which executes your javascript code in predefined order.
It is quite easy to create it from scratch, but there is a plenty of ready frameworks, that provide nice reports and allow to run different combinations of tests.
I tried QUnit and it quite ok. It is just basically several files, that you have to download - javascript and css. Then you have to create new html file where you will describe your tests. Also from this html you have to link QUnit files and javascript code that you want to test. Unless you want to put your functions in test file, you must have javascript in separate file.
So, in the end you will have something like this:

<html>
  <head>
    <script src="jquery-1.3.2.js"></script>
    <script src="testrunner.js"></script>
    <script type="text/javascript" src="code.js" ></script>
    <link rel="stylesheet" href="testsuite.css" type="text/css"/>
    <script type="text/javascript">

    </script>
  </head>
  <body>
    <ol id="tests"></ol>
    <div id="main"></div>
  </body>
</html>


Where code.js is your javascript code to test.
<ol id="tests"></ol> and <div id="main"></div> is where QUnit puts it's stats.
Now you can start to write tests.
For example, our code.js has something like:

function sum(v1, v2) {
  return v1 + v2;
}


To test it, we should have to call method test, for example like

test("2+2=4", function() {
  var result = sum(2, 2);
  equals(4, result);
});


If your code accesses some html element, there are several options - you can include your real html code into tests.html body, or you can mock it with some trivial html element. You can also add and destroy necessary html elements in test scenario. In general, include is probably best option as it avoids dublication, but simple mock elements was best choise in my cases so far. Drawbacks of include is that it requires server-side code and calls.
For example, if your code is

function showSum(v1, v2) {
  $('#result').text(sum(v1, v2));
}


You can add div element with id 'result'. And now all your tests will look like:

<html>
  <head>
    <script src="jquery-1.3.2.js"></script>
    <script src="testrunner.js"></script>
    <script type="text/javascript" src="code.js" ></script>
    <link rel="stylesheet" href="testsuite.css" type="text/css"/>
    <script type="text/javascript">
      test("2+2=4", function() {
        var result = sum(2, 2);
        equals(4, result);
      });
      test("show 2+2=4", function() {
        showSum(2, 2);
        equals(4, $('#result').text());
      });
    </script>
  </head>
  <body>
    <ol id="tests"></ol>
    <div id="main"></div>
    <div id="result"></div>
  </body>
</html>


Now we have some state between tests (value in 'result' div) and it is not good, because it can confuse tests and bring some surprizes.
Traditional way how to clean state between tests is to reset it. It is normally done in methods setup or teardown.
Setup is called before every test and supposed to prepare test for running and teardown is called after every test and supposed to clean environment after test.
In QUnit it is set in function 'module', like this:

module("my tests", {
  setup: function() {
    $('#result').text('12345');
  },
  teardown: function() {
    $('#result').text('');
  }
});


Here we set result to some value, for example, to check that it really updates value, but not appends. And in teardown we reset 'result' div to it's initial empty state for next test. It usually has more sence in big projects with many state parameters.

localStorage returns undefined value

When I have just started to work with localStoage without reading much about it I have created something like this
localStorage['key'] = 'value';
alert(localStorage['key']);
Result was great, and I got nice alert with 'value' on it.
Quite excited, i created functionality i wanted to have, created nice tests and found out that something is not great at all and after localizing error I have found out that similar piece of code is not working as good as previous.
localStorage['key'] = {test:'value'};
alert(localStorage['key'].test);

In this case, alert returned 'undefined', but not 'value', what was quite unexpected.
However this code
localStorage['key'] = {test:'value'};
alert(localStorage['key']);
says that I have nice '[object Object]'. I checked it a bit and had found that this script
localStorage['key'] = {test:'value'};
alert(typeof localStorage['key']);
says that my localStorage result is in fact 'string', which was quite unexpected, as it should be Object.
As it turned out, localStorage uses structured clone algorithm and whether because of this or for some other reason it converts my object into string, stores it as such and therefore looses all properties and values.
Finally, I have found easy way to solve this problem by converting my object into JSON string. Fortunately Firefox have native JSON coverter functions and everything can be done simply like
localStorage['key'] = JSON.stringify({test:'value'});
alert(JSON.parse(localStorage['key']).test);
In WRT there is no such nice lib, but it is possible to download it at json.org. And it can be nicely used like this:
widget.setPreferenceForKey(JSON.stringify({test:'value'}), 'key');
alert(eval(widget.preferenceForKey('key')).test);
There is small issue though. As you see JSON lib is used to convert object to string, but it was not able to convert string to object on my Nokia device. But this small eval hack still works great and I am getting my value as expected.

Let's start

Today I start this blog. I have created articles here and there before, but never in some organized way. So I'll try to put everything about programming, software and internet that can be related to my professional development.