Thursday, August 16, 2007

Debugging - Best Practices ...

For the coders among us, long live the debugger! Today's IDEs not only can profile and optimize your code, they come with top-class debuggers at no additional cost. The best also allow you to change values of variables, backtrack from a breakpoint, review the heap (and save it if you wish), and hot-replace code when it changes during a debug session. I can't even imagine developing software without such a tool.
But a debugger is as good as the programmer that uses it: if you are not skilled in using it, it's not worth the cost. A debugger is your first line in finding and fixing bugs. Here are other tips I've relied on over the years:
  1. Know your IDE's debugger limitations and features, and how to run it well. Only then can it be reliable and feasible.
  2. The obvious places may not be the culprits! After developing for a while, you start building a mental list of possible failure points and such, and develop a tendency of focusing too much on those areas when bugs do manifest themselves. Throw that mentality out and analyze issues from a "big picture" standpoint.
  3. Revert to the last working code and increment towards the the failure until you may find which additions cause the bug to happen. To this, you need a good versioning system. I've used Subversion, CVS, and Superversion - all free, of course.
  4. If there is a chunk of code causing the problem, contain the bug by using try/catch statements around it, and get a full error log. Then start walking that chunk, checking whether expected values are being set properly, and what is missing-in-action.
  5. Befriend the specification documents for insight. If you've debugged programs that use Windows system calls alot, you obviously don't have Windows source code to walk through, so MSDN (as scant as it is) will help some. Knowing what the WinAPI expects will help. Language forums are great help - chances are that you ain't the first person seeing this.
  6. Learn to read memory dumps, especially if you write C/C++ programs, or have to use JNI. Java hides these details from you, but Java debuggers should allow you to review entire data structures.
  7. Walk away from the code - take a hike, sleep, talk to your dog - whatever you do to take your mind off the issue. You won't believe how many times I've returned to the code and seen the problem right away - and felt so dumb.
  8. The blame game should start from inside out - first yourself, then the design, then the compiler, then the OS, and if you want - the language.
  9. Rewrite the offending chunk of code, perhaps using a different technique or even technology. Sometimes to understand C program issues, I've re-written chunks in Java and analyzed them from that standpoint. If you've fixed the same section nearly 5 times, it's time to re-write that piece afresh.
  10. Output messages - usually the first thing everyone does. I'm moving away from this - one of the 9 steps above will get me to the bug much faster.
Of course the art (notice it's not a "science") of debugging is different for everyone, but once you find a few good methodologies of finding bugs, work on making them better. Everyone should have a few tried and true ones, and then ask for help when bugs persist.

Wednesday, August 15, 2007

Testing Web-Based Applications

In my 4 years as a software developer, I've worked on a sizable number of web-based applications, and I thought I should share some insights - even as I am in the middle of yet another web-based project at this writing. Once in great while, I come across a website that is not pleasant to visit, and I wonder what kind of testing such a website might have undergone. Even more common are ActiveX or Javascript issues that litter websites on the Internet - ones that when you visit a page, an error is displayed and asks you whether you want to debug (dumb!!). These are signs of poor testing for a web application.
Comprehensive testing can improve the quality of web apps and lead to better long-term support for the application. Before deployment, functional and performance testing must be done, including security and accessibility certification of the web application. All this testing is done by testers, automated scripts, and a representative group of end users. Developers of the web application should only participate to provide expert support.

TESTERS:
Tester selection depends on testing needs, complexity of the application, time needed to learn the application, number of test scripts and scenarios, and total time available for testing. Choose testers with a goal to provide a diverse skill set and experience levels. You will need 3 kinds of testers: functional testers, performance testers, and scenario/script testers (differences will be seen in testing description). Obviously individual testers can do all these, but it's advisable to separate the roles.

TEST MANAGEMENT SYSTEMS:
Helps organize test resources such as documentation and requirements, scripts or scenarios, defects, and test results. Such a system is easily accessible by all groups for progress reports and task or defect tracking. The system also provides traceability and can be harnessed to lighten the load of documentation.

TESTING:

(1) Functional testing
determines if the web application works as designed, satisfying the requirements. Testers need to have an eye for anomalies and inconsistencies during such testing. Testing is manual, requiring a live person.
Automated tests should be applied to repeatable tasks that don't necessarily need human decision or observation skills. Scripts can help test more configurations in a consistent and predictable way, usually their course drawn from experiences of live testers. Functional testing also covers ideas like users entering bad data, no data, or unreasonably unrealistic data into the application.

(2) Performance testing for web applications focuses on response times. Tests may include spike (worst-case scenarios), stress (determine the failure conditions by subjecting it to increasing loads), and load (running 72-hour tests at near-breaking point - sustained high volume).

(3) Security testing
tests user authentication and verification, and accessibility to restricted content. It also tests session management issues, user privacy, and the protection of user transactions. Banking applications, for example, need to make sure they support SSL and TLS for secure communication.

(4) Integration testing
involves running the web application on various operating systems and web browsers. This is where the real difference between web browsers begins to show, and we've often had to write workarounds for web browsers that do not adhere to standards (IE is notorious for this ...). Also, all scripts and plugins are tested in more configurations at this point, resolving issues of when a browser doesn't support certain plugins, or the OS has to be configured to handle what we need.

(5) Accessibility and usability testing is geared towards those with disabilities. This is a much overlooked area of testing, but web applications should be able to support alternative input and output methods such as audio instructions, scanner input, and special keyboards. In fact, there exists laws on the books requiring government websites to support this feature (see Section 508 of the 1973 Rehabilitation Act).

TESTPLANS:
With all the testing considerations above, it is possible to write a comprehensive testplan that can cover all the aspects discussed. Just remember this plan should be adaptable enough for any changes to requirements and needs of the application.
Testcases should be prioritized such that when a regression needs to be done, high-priority and must-always-test testcases are done. Regression testing should always happen whenever a fix is applied to the application, patches are done to the environment, or new builds are deployed. The regression testplan should be more automated than regular testing, the results of which would guide live testers to focus on specific areas.

BEYOND DEPLOYMENT:
Ownership of the web application does not end after you hand it off to the client. At that point, you transition into a support role. In support, you deal with training the application's user community, providing help desk support, and facilitating knowledge transfer (documentation, knowledge base).
At a minimum, every website should have a help section that includes a user manual of sorts, frequently asked questions, application tips, and work-arounds for known inconveniences.

Monday, August 13, 2007

Practical Limits of File Sharing


A recent survey of teenagers and college students about file sharing revealed that despite threats of lawsuits from the RIAA, file sharing is thriving. In my opinion, file sharing will never end - not all of it is illegal. And as long as the networks exist, files will always be shared.
Though, there are limits that will curtail the file sharing phenomenon:

(1) You'll need more and more hard disk space to store all the files you download. A full (uncompressed) movie requires 9GB. A regular DVD rip requires 4GB, and many TV downloads are about 350MB large. A music album is about 125MB. With such space requirements, you computer will soon fill up, and that alone will slow down the file downloading habit. This is a weak argument though, as hard drive prices keep coming down sizes increase. Right now, you can buy hard drives at about 70 cents/GB. Small cost.

(2) A lot of file sharing utilities are advertisement-supported, which install malware and ad engines on your computer. Some of these utilities know how to disable antivirus programs and firewalls, and can turn your computer into a zombie. For fear of such a nightmare, people will stay away from file sharing. However, a new breed of no-ad download utilities is thriving. Some even check the authenticity of the files you download.

(3) Internet speeds will always deter whether downloading is worth your time. Presently, you can download a TV show in 30 minutes, and a full album in 11 minutes or so, depending on availability. ISPs can now detect whether you are downloading by monitoring traffic trends on your connection. If you suddenly start using consistently high bandwidth, their software can automatically throttle you down to a trickle.

(4) Software you need to rip DVDs, capture TV shows, and extract albums is getting more and more complex. It takes more than a few tries to get things right. This complexity will keep a lot of people away from file sharing activities. In addition, as ripping and sound/video capture from HDTV and such becomes more popular, there will be fewer software that's available for free. And as encryption schemes get harder, the activity will naturally decrease.

(5) Threats of lawsuits: a lot of people just hate to be tangled up in lawsuits they can necessarily avoid. The RIAA doesn't make sense when they try to charge you $750/song! But it'd be time wasting for you to want to defend yourself - the RIAA is a company of lawyers that pretend to watch out for artists' rights. I don't think that they care when their cases are without merit.

(6) Poorly designed file-sharing software: you don't want it to take over your internet. Some just hog your entire connection and expose to the world more than they should. If you can't surf normally because you are downloading or sharing files, it's a bad experience that'll discourage the activity.

(7) Burden of proof: anyone that sues you for illegally downloading their stuff has to prove that it is indeed their stuff that you downloaded. They have to find it on your computer, statistically show that it is a copy of what they have, and prove the means that you got it. It's not easy to get a warrant to seize someone's computer because you think they stole your source code or software - more proof is needed.

(8) Not all file sharing is illegal: so networks cannot be shut down and technologies absolved. For example, owning DVD-ripping software is legal and so is backing up your DVD movies. Problem is that a lot of people rip rented movies, and that's the vice. The laws being unclear will keep the world of file-sharing alive.

(9) US laws do not apply to other countries. Although most of the content being shared back and forth originates from the US, our laws don't apply to citizens elsewhere. If their governments are lazy about enforcing anti-piracy laws, more loss to US producers.

(10) Availability of files will always be sketchy. Files available for download depend on the season really - most people have the latest shows and music, partly because they have to clean up eventually (see #1 above). It's a rotating cycle that cannot be relied on. In addition, only about 30% of computer users leave their computers on the internet "all the time".

(11) Sharing stingy-ness: because share seeds can be tracked and because seeding files makes your computer a server, most people don;t share after they download files. That's selfish, by the way. Others share for a few minutes a day, which is hardly enough to broadcast your content to even the most popular trackers (talking BitTorrent here).

(12) It's geek activity to file-share and download. Those who think it's that bad an image won't do it. Beyond that, you need a certain levels of technical savvy to know which software, processes and places to go to for these services. About 60% of internet users have no idea about such things, or it's too tedious to be worth it.

Some of the points are limits against organizations such as the RIAA and their cohorts. I don't even know what will happen to file-sharing when non-DRM music begins to outsell copy-protected versions, or when digital TV becomes so popular you can watch it from your computer or even save shows directly to your computer. As we say in the programming world, if it's software, it's hackable. If it runs on my machine, I can rip it. If I can hear or see it, I can record it. And as long as I have friends, I shall share with them.

Wednesday, August 08, 2007

Data Converters for JSF Components

It is inevitable that when users fill forms in their web browsers, data arrives at the server as a bunch of strings. Then it's up to the server to convert the string to appropriate objects. To facilitate this conversion in JSF, you can write your own data converters.

Supposing we have an input field in which a user is expected to enter time, such as "08:45 am", and we need to convert this data to a Date object. Begin by defining the converter class:

public class TimeConverter implements Converter{
public TimeConverter() {}
public Object getAsObject(FacesContext context, UIComponent uiComp, String timeStr) {
try {
String displayFormat = "hh:mm a";
return new SimpleDateFormat(displayFormat).parse(timeStr);
} catch (ParseException ex) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ParsingError", "");
throw new ConverterException(message);
}
}
public String getAsString(FacesContext context, UIComponent uiComp, Object date) {
String displayForma = "hh:mm a";
return new SimpleDateFormat(displayFormat).format((Date)date);
}
}

The class must implement the javax.faces.convert.Converter interface, and its getAsObject() method must throw a javax.faces.convert.ConverterException. getAsObject() returns a Date, while getAsString() returns a string. Then you must register the converter with JSF:
<converter>
<converter-id>timeConverter</converter-id>
<converter-class>com.strive.research.timecard.converters.TimeConverter</converter-class>
</converter>

The JSP/JSF page should be able to utilize the converter when you attach an instance to any component, in this case, an input field:
<h:inputText styleClass="timeentrytext" value="#{timecardbean.tue_lunchout}">
<f:converter converterId="timeConverter"/>
</h:inputText>

The component above uses values from a managed bean. In that bean, the getter and setter look like this:
public Date getTue_lunchout() {
// return a date object;
}
public void setTue_lunchout(Date tue_lunchout) {
// some code
}
As shown, the task of conversion is no longer the managed bean's reponsibity. Earlier we had a utility class who's job was to convert dates; we don't really need (most of) it in this scenario.

Potential issues you might run into:
java.lang.ArrayStoreException: java.lang.Float = just means wherever you are storing objects must be generic enough to take casts of what you are storing. I got a similar exception when my double-subscripted Object array is instantialized as a String[][]. Dumb - I just forgot that's how I was doing it.
java.lang.IllegalArgumentException: Illegal pattern character 'o' = the pattern you are sending SimpleDateFormat is not correct. My patterns are generated based on browser language, and I had a bug in the algorithm. Simply fixed.

Tuesday, August 07, 2007

Detect Browser Language In JSF

The webapp developed so far (build 0.0.5) allows users to select from a dropdown list which language they would like the website to exhibit - English (default), French, and Spanish. However, language selection can be automated by reading the default language of the client's web browser.
In JSF application, you'll most probably do request processing in a managed bean, so that's where language detection should happen. Every web request arrives with information about the web browser in a request header. This information is available to the application via an ExternalContext object:

// Get the application context
FacesContext facescontext = FacesContext.getCurrentInstance();
// Get the request headers
Map requestHeaders = facescontext.getExternalContext().getRequestHeaderMap();
// Read the supported languages
String languages = (String) requestHeaders.get("Accept-Language");
String lang = Options.INTL_ENGLISH;
if(languages != null) {
if(languages.contains("es"))
lang = Options.INTL_SPANISH;
else if(languages.contains("fr"))
lang = Options.INTL_FRENCH;
else // default
lang = Options.INTL_ENGLISH;
}

To change the default language for Firefox, open the options dialog (Tools | Options...) and click the Advanced tab. Select Languages and choose which language to use. You need to restart Firefox for the changes to take effect. Most websites should then begin to detect your preferred language and present data in that language (if they are internationalized). Try Google, for example.

Monday, August 06, 2007

Free Stuff Better Be Free!

Whatever happened to just giving free things freely without arm-twisting and manipulation? I'm hating website that purport to give free services and products at the expense of your time, personal information, and headache! This is nothing new on the web, but I think websites should be more honest about a simple matter like this.

Case in point: I needed a download of RadView's WebLOAD web application test and performance suite. On their website, they advertise both a free (open source) and a professional ($) version. All over their main website, there's download links for the professional version, but none for the free version - not even on the downloads page. To get to this, you have to browse via product overviews, where you discover that there is another website dedicated to the open-source community version. Cool beans - so I follow the links to get the latest stable version, and it mentions I need to be a member to download. So I register, of course, and then it takes me to SourceForge! Wtf?? You don't need registration to download software from SF.

At that point, you know you just got swung: they collected your information, wasted your time (20 min), and generated some traffic for their websites (page views). Fortunately, I've been here before, so I can waste their resources in "revenge" - I give them bogus email and contact information. Here's what sucks even more - required fields for registration include a phone number and address - like I need them to call about this free thing? Why do they need this? Most people visit this category of website exactly once and may end up re-registering when they return next time. Well, they won't use what I gave them ... it's an airport address, and the phone number is a Hawaii area code with a California city code. Their databases will fill up with unusable information - payback.

See the point? I think if something is free, just provide a link, perhaps with a disclaimer, and let people get it as anonymously as can be. It's almost as if there's mouseprint all over the web that says: if you want free things, be prepared to lose something personal. How free does that sound?
Despite this vent, I'll still review their application with all fairness, including this story. Sorry folks.