Wednesday, December 16, 2009

JdkDynamicAopProxy ClassCastException

Problem:
I am suddenly getting an error after some spring config was changed:

java.lang.ClassCastException: $Proxy47 cannot be cast to com.mycompany.MyConcreteClass

The code looks like this:
MyConcreteClass myClass = (MyConcreteClass) model.get("myClass");

I should add that MyConcreteClass was autoWired with spring elsewhere, and this setup used to work until something was changed in spring config.

Solution:
This is happening because we are casting to the concrete implementation, what needs to be done is that the object needs to be cast to the interface:
MyInterface myClass = (MyInterface) model.get("myClass");

Also, the relevant spring configuration that causes this issue is:

<tx:annotation-driven manager="springTransactionManager" ></tx:annotation-driven>

In order for the proxy to not proxy the interfaces but concrete classes, you need to add the following attribute to the above directive:
proxy-target-class="true"

Friday, August 28, 2009

Javascript: insert table rows / table body

If you write lots of javascript, there will someday come a time when you need to do one of the following DOM manipulations:

  • Insert a new table body, discarding the old one
  • Insert some number of table rows after some given row
This can be easily accomplished using a javascript library like jQuery, but there is a major downside to this: very bad performance! (for big chunks of html)

The reason for this is that a library like jQuery must preform all sorts of checks for all sorts of corner cases, such as checking if the html you are inserting contains script blocks and running them if your browser does not support script eval (IE6 - 7). It must clean each string before turning it into DOM objects.

For this reason, it is better to use plain javascript to write all the table manipulation functions, and make assumptions about the html you will be inserting (so you dont have to clean it). Here is a collection of such functions that i have used in production code. They are on average 2 or 3 times faster than using jQuery for the same insert.

Inserting table rows after a row

Example Usage:

You can insert 1 or more rows this way.

Replacing a table body with a new table body
Note: html does not include the actual tbody tag, just the rows and columns.


Another function that I often use is a helper function for replacing the table body to be used with jQuery's ajax functions:


Caveats of using these functions:
  • On browsers that dont support scriptEval, scripts that are inserted into the table body will not be executed upon insertion. You will need to deal with them yourself. I usually include them in a hidden input with a predefined ID, and then eval the value of that input after insertion.
  • Leading and trailing whitespace counts as a DOM node in IE, and will have weird effects if the html used in these methods contains it. If you are in charge of creating the html you insert, make sure it doesnt have unneeded whitespace between and around nodes.
  • I dont know if liveQuery plugin will know about these dom modifications.

Wednesday, August 12, 2009

Readynas: insufficient system resources exist complete requested service

Problem:
Whenever i try to access my readynas nv+ shares from any computer, i get the following error message:
insufficient system resources exist complete requested service
All of my computers have plenty of free memory, hard disk space, etc. The problem is clearly the NAS. Googling leads me to believe that the NAS is returning a malformed response to windows and so windows gives this incorrect error message.

Moreover, i can still log into frontview, and ssh in.

Solution:
Recently i was playing around with the NAS, i installed the addon that gave me root and installed some programs in the root directory /root. One of those programs misbehaved and filled up my root partition with some data. I sshed in and checked diskspace:
df - k
This showed me that the root partition was indeed at 100%. This is the problem, to solve it i needed to delete the big files that were taking up all the space. I used the method i previously wrote about to find the big files and remove them. After i was finished, root was at 46% full. i rebooted the NAS and the problem went away.

Friday, July 31, 2009

Intellij Tomcat Configuration Already Run

Problem:
I have a debug tomcat configuration that i always use. Recently i started having a problem where after killing tomcat, and trying to run it again, i would get the error title "Configuration Already Run" which said "Run configuration 'tomcat local' has been already run. Do you want to redeploy it?". Clicking both yes and no buttons didnt do anything. Tomcat was not re-run.

(i am using tomcat 6, and intellij 8.1.3)

Solution:
This seems like an intellij bug. Confirm that tomcat is really dead by running this at the command line:
taskkill /F /IM tomcat6.exe

If that doesnt fix it, proceed with the workaround:
Open the debug tool panel in intellij, and locate the close button, its a red X above the help button, which is a question mark, its on the left side of the screen. Press the close button to close the debug tool panel. Start the debug tomcat, it should run now.

Wednesday, July 08, 2009

docx converter

docx sucks. microsoft should have stopped after word 2003. This patch will make you be able to open office 2007 documents in older (better) versions of office.

direct download link:
http://download.microsoft.com/download/9/2/2/9222d67f-7630-4f49-bd26-476b51517fc1/FileFormatConverters.exe

link to the download page:
http://www.microsoft.com/downloads/details.aspx?FamilyId=941B3470-3AE9-4AEE-8F43-C6BB74CD1466&displaylang=en

Friday, June 26, 2009

checkbox margins in IE incorrect

Problem:
By default, checkboxes have some margin and perhaps padding so they take up a bit more space than is needed. I needed to make some checkboxes take up the least amount of space possible, and the following css:

input {
margin:0;
padding:0;
}


didnt work in IE6 and IE7, while working perfectly in firefox (as usual).

Solution:

Add the following IE only css:

<!--[if IE]>
<style type="text/css">
input {
margin: -5px;
}
</style>
<![endif]-->


This fixes the problem on IE6, and IE7, i dont know if IE8 has this problem or not.

Monday, June 22, 2009

Scroll bars not working and MSThemeCompatible

I recently had a problem where scroll bars were not working properly when windows XP was themed in the default theme (not classic). The scroll bar would not move if one used the arrows, or clicked in the area between the bar and the arrows. It could still be used by dragging it up and down.

The weirdest part of this issue was that the scroll bar worked normally in the windows 'classic' theme, but would seize to function correctly if you switched themes over to the ugly blue default theme.

I should also add that this scrollbar was part of a javascript widget where its position determined position of another DIV in the widget.

Solution (Hack):
Before i found the proper solution i came with a hack - on page load, add 1px to the width of the scrollbar and change its css left to -1px like so (this is jQuery):

$scrollY.css({"position":"relative", "left":"-1px"});
$scrollY.width($scrollY.width() + 1);

This seemed to work for some reason, the scrollbar works after this is applied.

Solution:
I later stumbled on another solution that didnt smell like such a hack, but i am not sure what side effects it has other then making the scrollbar work. The solution is to set an a meta tag in IE only (because firefox has a bug with this metatag):

Monday, June 08, 2009

Tellurium: A Better Functional Test

Lets face it, Selenium has been around for years, it has been a choice tool for functional testing for many because it is free, has good support, and it works. Sure, it hasnt seen many updates as some would have liked, for example it didnt have firefox 3 support for a very long time. No big deal right? The latest beta supports firefox, and every one knows how to use it, the feature set has remained pretty much unchanged for years.

Why would you want to break the mold of functional testing and try something new? Well, until very recently, there hasn't been a compelling enough reason to do this. Fortunately, now there is: Tellurium.

Tellurium is another open source functional testing framework that picks up where Selenium has left off, and packs many new great features. The ideas themselves aren't exactly new: caching, UI modules, DSLs to describe the UI, Data Driven Testing, Using a JS framework instead of xpath, just to name a few. These ideas have been around for ages, but never before have they all been implemented in a mature functional testing framework.

This is the reason you should try Tellurium: new features, and the speed of their implementation.
I didnt know what i was missing with selenium until I implemented a few test cases using Tellurium's UI mapping Groovy DSL. This was a year ago, and I took a gamble in a fairly young testing framework based on Selenium server. Let me tell you, it has paid off. Not only are my tests written in a more Object Oriented way, but since upgrading to Tellurium 0.6.0 my tests run faster.

Lets look at some benchmarks.

Right now Tellurium is built on top of Selenium server, it translates its calls into one or more Selenium calls to do it job. Selenium uses xpath as its primary selector, while Tellurium also supports using the sizzle selector engine, in its jQuery selector.
The following graph shows the sizzle engine speed versus the default xpath engine using by Selenium. The blue is the xpath execution speed, and the red and yellow is jquery without caching and with caching, respectively.

As you can see, the speed up from using siggle is about 30%. I should add that this benchmark was taken on IE6, the slowest javascript platform that is still supported by most sites.

This speed up is going to allow you to have more time to do other things, or write better test cases. It can greatly speed up continuus intergration tests.

For more information about caching see this page. For more information about jquery selector see this page.


Another big performance booster in tellurium 0.6.0 is the bulk data retrival that is possible when using jquery. Every one who has used jquery knows about the convenience of $("table td").text(). Tellurium now performs such calls if you ask it for the text of of all cells in the table, whereas selenium will get you that data cell by cell with overhead for every call.

The above graph shows the awesome speedup that is possible with bulk data retrival. Notice the rightmost group titled "Bulk Data". The yellow bar representing Tellurium performance is so small that it seems like it may be missing. In this case, the speedup from gathering all the data in the javascript, and transporting it in one call gives you an incredible speed up of a few 1000%.


Upcoming performance Improvements in 0.7.0

One nice thing about Tellurium is the speed of development, and new features that make it into the build.

I have been keeping an eye on a performance improvement called "Control Group". The idea behind control group is to group together Selenium server calls into groups, execute them, and return multiple data sets. Since the biggest overhead comes from interacting with the server, this will be a big improvement over the current situation.

So, try tellurium out, you wont be disappointed.

Friday, May 15, 2009

HTML forms - Things you should know

This is a list of things every web developer should know about forms. I didnt know these things, and thus wasted many hours banging my head against the desk. Hopefully this post will save someone else that time.

1. Disabled inputs are not submitted.

The HTML spec defines that only 'successful' controls's values will be sent in the form on submit. disabled controls arent 'successful' and are not submitted. If you want to submit a disabled control you will have to either:

  • Enable it right before submitting the form, and then disable it.
  • Copy its value into a hidden input before submit

2.
A form with only 1 text input will submit on enter in that input.

This is another little gem from the HTML spec that drove me nuts for a while. I couldnt figure out why the form was submitting on enter in an input type='text' when no key handlers were attached to the input, what was worse, my on submit validation was skipped. It turned out that if a form has a single input of type 'text' then pressing enter in this input will submit the form. To get around this you must:
  • Add another input of type text and hide it with css

3.
Internet exporer will not submit a form if it contains a file chooser with an invalid file path.

This is a fun one. IE does some rudementary form validation for you, and if it finds that you have selected a file which does not exist, it will not let you submit the form. This by itself is not a bad thing, but what is bad, is that it does not let the user, or the programmer know that the form was not submitted. As a UI programmer, I want to have an error message if the form submition fails, but I have no way of knowing it. To get around this you must:
  • Validate the path yourself using regex, and try to find invalid file paths, and raise error yourself before IE
  • Copy the value of the filechooser into a hidden input, disable the file chooser, and deal with invalid paths in serverside validation.(wont work as pointed out)

Form submitted unexpectedly on enter

Problem:
I have a form that would be submitted when i pressed enter in a text input field. It would skip over all my validation that i was doing in the input's onKeyDown callback function. I removed the onKeyDown event handler, and still the form would be submitted on enter. The input was not a submit type input so the submission was not expected.

Solution:
This problem stemmed from the fact that the input box in question was the only text type input box on the form. The HTML4 spec states that if you have one input box of type text, pressing enter in this input box will submit the form!

I solved this by adding another input of type text with style="display:none" and a name:

<input type="text" style="display:none" name="dummyinput" value="" id="dummyinput" >

The reason for this hack being that I had bound on-enter handlers to the first inputfield of my own, and trying to prevent those would break my code also.

Monday, May 11, 2009

Eric's Roommates's Favorite Grilled Shrimp

  • 2T Samba sauce (red sauce from chinese places)
  • 2T Mirin (sweet wine-like stuff japanese cook with)
  • 1T Sesame oil
  • 1/4c Chopped fresh cilantro (dried does not suffice)
  • Juice from 1 lime
  • 1-2 pounds raw shrimp

Marinate 1hr max if at room temp, up to 3-5hrs if in fridge. Grill.

Thursday, April 30, 2009

Book Ratings

Another note to self. Book ratings:

Scale of 1 to 10.
R = reread

Dune 1 - 9
Dune (last one) - 10 R (might be difficult without rereading the entire series)
Alan Stelle - Coyotte 1 - 9 R
Alan Stelle - Coyotte 2 - 10 R
Alan Stelle - Coyotte 3 - 6
Jared Diamond - Guns Germs and Steel - 7

Monday, April 27, 2009

Microsoft LifeCam VX-1000 driver download

The Microsoft LifeCam VX-1000 driver is a pain to find on the internets:

http://download.microsoft.com/download/6/6/6/6663B667-3D5E-4637-A615-80EC6BA1E4AC/LifeCam3.0.exe

This driver also works for VX2000, VX3000, VX, VX5000, and XV7000


feel free to click on an ad on my blog if this entry has saved you some searching =)

Also, if you cant download the driver from the microsoft site, i am providing a mirror on my server for the download:

Mirror: http://programmingdrunk.com/random-stuff/LifeCam3.0.exe

edit 7/28/09: Some people are having problems getting this webcam to run on windows Vista with 4GB+ ram. There is a hotfix for that here:
http://thehotfixshare.net/board/index.php?autocom=downloads&req=download&code=confirm_download&id=126 (Windows6.0-KB933433-x64.msu)

edit 9/1/09: updated driver link to 3.0

Friday, April 03, 2009

Trim a string in perl

problem:
I am a perl noob and i need trim a string.

solution:
1) if i can modify the actual string:
sub trim {$_[0] =~s/^\s+|\s+$//g}

2)if i don't want it to modify:
sub trim {my $s = $_[0]; $s=~s/^\s+|\s+$//g;return $s;}