Thursday, June 22, 2006

10 tips on writing reusable code

I have been trying to increase code reuse in the projects I have been doing recently. In my first few years of coding I hardly ever got to reuse any of my code because it was always too coupled together and dependant upon other parts of the code.

So recently I have been trying to write code which I can reuse. It has been interesting that since I have been doing this I have noticed that my library of code is starting to grow. I have started to create more Static Helper classes with useful methods in. I have also been removing the business logic away from any Struts actions or framework work.

To do this I have tried to do a number of things to help this and these are the sort of rules and things I do (in no order) to help me try and achieve this. They are a number of rules and tips I have picked up but can't remember where from

1. Keep the code DRY. Dry means Don't repeat yourself. This is one of the main changes I have tried to bring in. Always try to eradicate duplication and if you find any then move remove the duplication to a relevant place. Sometimes this has lead me to create Static Helper classes or sometimes move it to the class it makes most sense to have it.

2. Make a class/method do just one thing. This is along the lines of the advice of giving the class only one reason to change. This often means creating methods that other methods use but this helps to make the methods/classes simple and less coupled.

3. Write unit tests for your classes AND make it easy to test classes. Writing code that is easy to test is decoupled. If you write code and are thinking about writing a unit test for it then you tend to split up the code into smaller testable chunks.

4. Remove the business logic or main code away from any framework code. Following the rules above will help this. An example I have seen is code that is inside Struts Actions classes, this code is practically impossible to reuse because of all the Struts dependencies that it now linked with.

5. Try to think more abstractly and use Interfaces and Abstract classes. Try to hide dependencies of code behind a more Generic interface/abstract class. The benefit this gives the code is it creates a flexible point in the code where you can then hide future changes behind.

6. Code for extension. Write code that can easily be extended in the future. This is particularly true with the above point. If you write code that uses interfaces then you can extend that interface at a later point.

7. Don't write code that isn't needed. Do the simplest thing possible. Don't waste your time adding methods and classes that might be used in the future. Keep the code simple and focused on what you are trying to deliver. I think I read/heard Josh Bloch say once that "if in doubt, leave it out". Basically who wants to write code that no one (including yourself) is going to use again.

8. Try to reduce coupling. When writing code think about the links and coupling the code is creating, does it need to be linked to those other classes.

9. Be more Modular - make your code more modular, think modular, be modular.

10. Write code like your code is an External API. Imagine the code you are writing is a self contained component.

It wasn't going to be ten until I got to 8 and then thought no one writes 8 tips, lets add two more on. It isn't really a list but it's sort of aims and mental notes I try tell myself when writing code. They are more small bits of code I have written recently that has helped. I would like to hear people's comments and especially their tips on writing reusable code.

(http://cg.scs.carleton.ca/~morin/misc/sortalg/)

Unix: Ten Things Every Java Developer Should Know

One of the great things about Java is how multi-platform it really is. While cross platform glitches do occur, they are not really all that common. But since the law of unintended consequences is all pervasive, we now have the common sight of teams of developers building Java programs meant to run on Unix boxes on Windows.

Developing code meant for Unix on Windows does work reasonably well. The trouble is, many those coders slaving away in front of XP have a very limited understanding of their target platform. If that describes you, this following list is meant for you. Without further ado, here are the ten things you really need to know about Unix, in reverse David Letterman order:

10) You need to be special to use some ports

On Unix machines, programs run by ordinary mortals cannot use network ports less than 1024. Only the special root user can use these ports. If you do decide that you need to run your server as root, be very careful since a program running as root is all powerful on a Unix machine.

9) There is no magic file locking

Windows has this magic file locking mechanism that prevents people from removing a file while it is open. Thus, on a Windows box the call to delete() in the following code is pretty much sure to fail:

InputStream is = new FileInputStream("foo.txt");
(new File("foo.txt")).delete();
int ch;
while( (ch = is.read()) > 0 )
System.out.println( "char: " + (char)ch );
is.close();

The delete will fail because someone (our program in fact) has the file open. After we get done printing out its contents, foo.txt will still be there. The kicker is, the delete() will work just fine on any Unix box. Under Unix, the call to delete() will delete the entry for foo.txt out from the file system, but since someone (our program) still has the file open, the bytes will live on, to be read and printed out. Only when we close the stream will the contents of foo.txt follow its name into oblivion.

In exactly the same way, on a Unix box, someone can delete a program's current directory right out from underneath it.

8) Sometimes there is no GUI

People who are used to Windows are sometimes surprised to find their programs running on a Unix box that has no GUI at all. None. Zilch. Nada. In Unix, the GUI is an add on component and it is completely optional. The machine will run fine without it and servers commonly do. Be very careful making calls to those handy java.awt methods -- some of them will fail on a machine with no GUI.

While you are at it, you may want to rethink what you are writing out with System.out. Many severs not only lack a GUI, they are completely headless: no keyboard, no mouse, no screen. If you are deploying into this kind of environment, the log file is your friend, because your program's cries for help are unlikely to be heard anywhere else.

7) In Unix, there is no registry...

... but if there was, it would be a plain text file. Unix systems have no central place like the Windows registry for storing configuration information. Instead, Unix configuration is spread over a fair number of different files. Many of these files live in a directory called /etc : the list of users is in a file called /etc/passwd, while the name of the machine is typically found in /etc/host.

I guess if you are a Windows user that is the bad news. Here is the good news: most, if not all of the configuration files are plain text files. You can look at them with any old text editor. A further bit of good news is that all modern Unix like systems come with GUIs to edit the configuration files.

6) Forward slashes are your friend

This one is really more about Java on Windows than it is about Unix, but useful anyway. Just about everyone knows that Unix uses forward slashes to separate the bits of a path: /etc/passwd, while Windows uses backslashes: c:\Program Files\Windows. What a disturbing number of folks don't realize is that forward slashes work just fine on in Java on Windows too. On a Windows box, Java is smart enough to translate /a/b/c/foo.txt to something like C:\a\b\c\foo.txt.

Should you rely on this for production? No. If you are really coding cross platform Java, you need know about File.pathSeparator and the various File constructors. But if you are coding stuff that is only meant for Unix, and you just want to test it on your windows box, knowing that the forward slashes work in both places can save a lot of agony.

5) Our services are just programs

In Windows, system services are special programs, written to a particular service API. On Unix, services are provided by pretty ordinary programs that do service like things.

Typically, a Unix service consists of the useful program and a script which starts the program in the background when the system starts up and may shut it down again when the system is halting. Many Unix systems keep these scripts in the /etc/init.d directory.

4) Environment variables are hard to change

Windows programmers sometimes cook up little batch files that set the environment variables they want. Perhaps you need to roll back to an old version of Java and Ant. You might write a batch file that looks something like:

set JAVA_HOME=C:\java1.4.1_05
set ANT_HOME=C:\apache-ant-1.6.1

They can then run the batch file:

c:\> setenv.bat

and have the environment that you need. If you try to translate this directly into Unix-land, you get a script that looks not too different:

#!/bin/sh

JAVA_HOME=/usr/java1.4.1_05
export JAVA_HOME

ANT_HOME=/usr/apache-ant-1.6.1
export ANT_HOME

So you try out your new script...

$ setenv.sh

...and it does nothing. The trouble is that the Unix shell runs scripts by creating a copy of itself and running the script in the new shell. This new shell will read in the script, set all the environment variables and then exit, leaving the original shell and its environment unchanged. I hate when that happens. Changing directories works pretty much the same way: if you do a cd in an ordinary shell script, it will change the directory for that second shell, which may or may not be what you want.

If what you want is to change things in your current shell, you need to have the current shell read in the script directly, without starting a new shell to do the job. You can do this with by using the dot command:

. setenv.sh

Life will be good as your environment variables change.

I should mention that there are several different shells available in Unix. Which one you use is mostly a matter of taste, either yours or the person who set up your account. The commands above will work with many of the common Unix shells, but if you happen to be running the C shell (note the pun), then your little script will need to look something like:

setenv JAVA_HOME /usr/java1.4.1_05
setenv ANT_HOME /usr/apache-ant-1.6.1

You also need a different command to read the script in:

source setenv.csh

3) We don't like spaces in our file names

Okay, this one probably has more to do with Unix users and sys admins than the OS itself, but the fact is, we don't like spaces in our paths. Oh it is perfectly possibly to have spaces in Unix file names. In fact you can put darn near anything in a Unix file name: /tmp/:a,*b%c is actually the name of a directory on the system that I am using to write this.

But can and should are two different things. Unix users spend much of their time using the command line and Unix command line utilities are not crazy about paths with stars, question marks and especially spaces. The Unix guy can always find a way, but if you insist on putting strange characters like spaces in your file names, you are just finding a way to annoy your local Unix guy.

2) There is no carriage to return

If I had just one magic lighting bolt to hurl at one person, I think I would pick the guy who decided to use different line terminating characters on the two major OS's. I suspect we would have hyper intelligent computers by now were it not for all the time wasted trying to figure out why my file looks funny on your OS.

In a plain text file, Windows typically uses a carriage return followed by a newline character to mark the end of a line. Unix dispenses with the carriage return and makes due with the single newline character. Although the tools are getting better, Unix style files may show up as one long line in Windows -- not a single carriage return/newline pair in that file, must be a single line. Likewise, Windows style files will sometimes show up on Unix with garbage characters at the end of a line -- that extra carriage return is meaningless under the Unix convention.

This doesn't matter much for Java files -- it's all white space to the Java compiler. But some native Unix programs care passionately about those funny characters at the end of a line. In particular if you use a Windows based tool to edit a Unix script and your tool adds carriage returns to the script file, you have screwed it up. The script will no longer run. Worse, since many Unix editors do now handle the carriage returns, you could look at the broken script and see nothing wrong.

1) You need a Linux box

If you are doing significant development for Unix, you owe it to yourself and your customers to know something about Unix. If all else fails, get yourself an old PC and some of that free Linux. Or get yourself one of the many bootable Linux-on-a-CD distributions and try it out on any machine. Java is nearly platform independent, but not quite. It is up to you to make up the difference.

(http://www.javalobby.org/articles/10things-unix/)

Tuesday, June 13, 2006

New Robot Has Powerful Cling by Tracy Staedter

A novel, walling-climbing robot could cut thousands of dollars off building inspection fees and one day work to survey urban war zones, where corners, rooftops and building materials thwart otherwise capable robots.

The City Climber rover, being developed by Jizhong Xiao and his team at the City College of New York, uses a vacuum chamber to get vertical. The robot is part of a project that aims to automate mandatory building inspections.

"New York City mandates that the facades of buildings be inspected every five years," said Xiao. "But the current manual inspection is time-consuming and the cost is very high — about $5,000 for one day."

Xiao thinks his robot, which costs less than one day’s work, can do the job faster, cheaper, and more thoroughly than trained technicians, who typically perform their gravity-defying work from suspended scaffolding.

Robotic wall climbers typically employ more superhero-like methods: sticky feet, suction cups, claws, or magnets. But those grippers are only as good as the surface they make contact with.

Suction cups or sticky feet, for example, work best on smooth surfaces such as glass or marble, but not so well on brick. Clawed toes clamber well over rock and brick but slip on glass.

What’s more, such devices tend to move tentatively and cannot navigate over a variety of textured surfaces.

Getting a robot to both cling to a wall and maneuver effortlessly over it are among the two biggest challenges that face researchers focused on wall-climbing robots, said Ning Xi, director of the Laboratory of Robotics and Automation at Michigan State University.

"In both aspects, the City Climber is probably the best in the world right now," said Xi, who is not associated with the project.

The 1-kilogram device clings to the wall by way of a vacuum rotor located in the center of its underbelly. The rotor’s impeller draws air in from the center of the device and spews it out toward the edges.

The column of circulating air creates a region of low air pressure inside the vacuum chamber. Because the surrounding air pressure is higher, it pushes down on the device, keeping it tight to the wall.

Small wheels on the underbelly of the device drive the robot forward and back.

By linking two triangular-shaped modules with a hinged arm, the researchers were able to make the City Climber maneuver around 90-degree angle corners and transition from a wall to a roof — all with the strength to pull or carry a payload four times its weight.

"They have achieved one of the highest payloads reported in the literature," said

professor Nikos Papanikolopoulos of the University of Minnesota.

Xiao will be capitalizing on his rover’s payload capabilities this summer by equipping it with a high-resolution digital camera to conduct a mock building inspection.

(http://dsc.discovery.com/news/briefs/20060612/cityclimber_tec_print.html)

Friday, June 09, 2006

Computer 'Beings' Evolve as Society by Tracy Staedter

Millions of computer-generated entities that live and die by natural selection could reveal how our own culture and language evolve.

The software agents are part of a project called NEW TIES (New and Emergent World Models Through Individual, Evolutionary, and Social Learning), which draws on the expertise of five European research institutions to push computer simulation of artificial worlds further than ever before.

The joint computer project not only reproduces individual and evolutionary learning, but also social learning.

"Social learning is these guys telling each other what they learn on their own. One is learning about hot and cold and another is learning about soft and hard.

"They exchange knowledge and save effort," explained project coordinator Gusz Eiben, a professor of artificial intelligence at the Vrije University, Amsterdam.

Understanding gleaned from such a project could advance machine learning for a range of applications. The learning software could guide exploratory or search and rescue robots that must cooperate to accomplish tasks in unknown environments.

The simulation computer project could even allow policy makers to test out new laws before carrying them out in real life.

The team of computer scientists, sociologists and linguists are creating a population of millions of unique entities that have the ability to pass on life-prolonging tips to their community. In the process, they may evolve their own language.

Computers Create Unique Beings

Each agent is randomly generated by a computer to possess a gender and different variations of life expectancy, fertility, size, and metabolism. The randomness of their programs allows each one to behave differently even when faced with the same set of circumstances.

The outcome of their actions — moving around, talking with another entity, and giving birth — burns fuel that can be replenished by finding the right food source.

Those who lack the wherewithal to survive risk certain death and the inability to propagate their genes.

A simple vocabulary of five to tens words, such as "food," "near" and "agent" gives the entities the basics for communication.

Meanwhile, an algorithm enables two entities to agree on the meaning of new words and could allow the artificial beings to evolve a language.

The idea is to expose the agents to challenges and see how they adapt and develop their own world models.

Recently, Eiben and his team began running their first simulations using 1,000 to 3,000 agents to ask the question: Does individual learning compensate for bad genes? Eventually they plan to scale up to millions of agents.

The big challenge the team faces, said senior researcher Michele Sebag, an expert in artificial intelligence at the University of Paris-Sud, is tracking the behavior of each of the millions of agents.

"You can't look at every agent individually. You have to have new facilities in data mining to understand what is going on in your population," she said.

Following the rationale that "birds of feather stick together," Gusz will be pinpointing and profiling agents who cluster together as well as tracking the locations of each agent as it moves over time.

(http://dsc.discovery.com/news/briefs/20060605/computerculture_tec_print.html)

Thursday, June 08, 2006

java.lang.ThreadLocal

hadn't previously had a reason to use java.lang.ThreadLocal, but I used it recently to add multi-threaded capabilities to a previously single-threaded application...

The application I modified is a basic batch maintenance JDBC type of stand-alone application that reads a text file and updates a database. In order to speed things up, the application was parallelized (if that is a word).

The problem was that the DB2 java.sql.Connection object (which was being retrieved from a custom factory) was not thread-safe. So I opted to use an individual Connection per thread. But how to implement this strategy?

I could have used a connection pool (FOSS or rolled) to help out, but there were a bunch of reasons why I didn't, here's a sampling:

  • The app is small and lean. Adding 3rd party pooling would be considered bloat, writing one myself would be a waste of time.
  • No sharing benefit; one app runs per JVM. If the system were deployed on an app server, where multiple apps could benefit from the same pool, the centralized management might be worth it.

I chose to wrap the Connection in ThreadLocal instead. Then redirect all calls for a connection (in the factory) to ThreadLocal.get().

The class snippet below doesn't really work but it illustrates the point.

public static Connection getConnection() {
return (Connection) conn.get();
}

private static ThreadLocal conn = new ThreadLocal() {
public Object initialValue() {
String driverClass = "whatever";
try {
Class.forName(driverClass);
Connection con =
DriverManager.getConnection("connectionURL",
"user", "password");
con.setReadOnly(true);
con.setAutoCommit(false);
return con;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
It worked like a champ.. every thread that called getConnection() got a different Connection and the threads could do their work independently.

(http://mattfleming.com/node/118)

Analysing GC the affordable way

Lately i have been running into memory problems at a customer and i was ready to go with a to be bought profiler to the customer and play the profiler game. But after visiting or contacting most of the major players in the profiler segment like JProfiler, JProbe, Yourkit or OptimizeIT, i had to realize that the complete crowd dont support Java on Linux/PPC. First i thought that this cant be real because nearly all IBM machines and therefore nearly all IBM customers are running linux on Power Architecture (except xSeries of course). But it is real and so far i dont know any profiler which is running there.

So i searched for alternatives and used the JVM boardtools like verboseGC and the new Java5 switches for memory profiling. After getting some more log files from the JVM, i found the "IBM Pattern Modeling and Analysis Tool for Java Garbage Collector" quite useful. BTW you can get it here. So i run this tool with my first verboseGC log and even its not an exhausting information, its enough to get the idea and to look further. Below the screenshot. There are some more tools in this space from IBM i will cover in the next days.



Posted by Picasa

(http://www.logemann.org/blojsom/blog/default/?permalink=analysing-GC-the-affordable-way.html)