My thoughts as an enterprise Java developer.

Friday, September 28, 2007

Garbage collecting file system

Why don't current file systems implement garbage collection so that deleting a directory takes constant time (regardless of how many descendants it has)?

Google has done that See section 4.4 (page 8) of http://209.85.163.132/papers/gfs-sosp2003.pdf

Subversion: Setting svn:keywords property

If you converted from cvs and need to set the svn:keywords property you can use the following script (doesn't handle spaces). I wrote this before I realized that cvs2svn already set the property and I therefore didn't need it.


#!/bin/bash

echo Seaching...
# Put Keywords up one directory so the 2nd-last greps don't search it.
grep -R -H "\$Date:" * | grep "\$Date:" > ../Keywords.txt
grep -R -H "\$Revision:" * | grep "\$Revision:" >> ../Keywords.txt
grep -R -H "\$Author:" * | grep "\$Author:" >> ../Keywords.txt
grep -R -H "\$Id:" * | grep "\$Id:" >> ../Keywords.txt

echo Setting Properties...
cat ../Keywords.txt | sed "s/:.*$//" | sed "s/^/\"/" | sed "s/$/\"/" | xargs -L 1 svn propset svn:keywords "Date Revision Author Id"
echo Results:
svn status

Tuesday, September 25, 2007

Remove empty Subversion directories

I couldn't find any scripts that would prune empty Subversion controlled directories so I wrote the following. Enjoy!

#!/usr/bin/bash

for i in `find . -type d -print -name ".svn" | grep -v "/\.svn"`
do
if [ -z "`ls -A $i | grep -v '\.svn' `" ]
then
echo Removing $i
ls -A $i
svn remove $i
fi
done
echo Results:
svn status


Update:
The script above doesn't handle spaces in the filename so use the following two scripts if you have spaces in any filename:


svnPrune.sh
#!/bin/bash

echo Searching...
find . -type d ! -path "*\.svn*" ! -name "\." ! -name "tags" ! -name "branches" -exec /svn/svnPruneDirectory.sh {} \;

echo Results:
svn status

svnPruneDirectory.sh
#!/bin/bash
directory="$*"
#echo Processing $directory ------------------------------------------------------

files=`ls -A "$directory" | grep -v '\.svn'`
#echo files=$files
childrenCount=`ls -A "$directory" | grep -v '\.svn' | wc -l`
#echo $directory: $childrenCount
if [ "$childrenCount" -eq "0" ]
then
echo Removing $directory
# echo $files
svn remove "$directory"
fi

Monday, September 24, 2007

Terminal window with 3 frames

I think it would be useful to have a terminal window with 3 frames.
  1. Output frame (At the top): Shows all program ouput and input/commands that the have been processed.
  2. Input frame (in the middle): Allows the user to enter standard input. Only show when a program is waiting for standard input.
  3. Command frame (at the bottom): Allows the user to enter commands.
Benefits:
  • It would be obvious when I wrote a command that is waiting for user input.
  • It could allow you to provide standard input via a command after running another command.
This could probably also be done in one frame with coloring to show the different parts. The prompt would change color when waiting for standard input (as opposed to waiting for the process to finish).

What do you think? Does something like this exist?

Friday, September 07, 2007

Java applet to check Java version

Out product only requires Java 1.4 (or higher) but we want to require Java 1.5. About 10% of applet requests used Java 1.4 so we want a way to notify the users who use Java 1.4 that they should upgrade. Searching with Google I couldn't find any such applet so here is my version.


JavaVersionCheck.class:
import javax.swing.*;

/**
* Prints the <code>message</code> if the java version doesn't match
* <code>javaVersionPattern</code>.
* @author James Stauffer
*/
public class JavaVersionCheck extends JApplet {
public void init() {
try {
String javaVersionPattern = getParameter("javaVersionPattern");
String message = getParameter("message");
if(VersionMatches(javaVersionPattern)) {
add(new JLabel(message));
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static boolean VersionMatches(String javaVersionPattern) {
String javaVersion = System.getProperty("java.version");
return javaVersion.matches(javaVersionPattern);
}

public static void main(String args[]) {
if(args.length > 0) {
String javaVersionPattern = args[0];
if(VersionMatches(javaVersionPattern)) {
if(args.length > 1) {
System.out.println(args[1]);
} else {
System.out.println("Matches " + javaVersionPattern);
}
}
}
}
}


HTML:

<applet height="30" width="300" code="JavaVersionCheck.class">
<param name="javaVersionPattern" value="^1\.4.*">
<param name="message" value="Java 1.4 is not supported. Please upgrade to 1.5.">
</applet>

Friday, August 10, 2007

toString() cost

Do you assume that toString() on any given object has a low cost? I do. Is that assumption valid? If it has a high cost should that normally be changed? What are valid reasons to make a toString() method with a high cost?

Thursday, August 02, 2007

Dynamic/static language

What if a language allow both static and dynamic types. That might allow the best of both worlds. i.e.:
String str = "Hello";
var temp = str;
temp = 10;

1. Would that be possible?
2. Would that be beneficial?

Wednesday, June 27, 2007

Debugger for *nix pipe commands

As I build *nix piped commands I find that I want to see the output of one stage to verify correctness before building the next stage but I don't want to re-run each stage. Does anyone know of a program that will help with that? It would keep the output of the last stage automatically to use for any new stages. I usually do this by sending the result of each command to a temporary file but it would be nice for a program to handle this.

Monday, June 25, 2007

10 things to do today

Here is my list of 10 things to do today:
  • Code
  • Goto #1

Friday, May 18, 2007

Telecommuting tips

I have been telecommutting 1-2 days/week for a few years so I present the following tips to those who want to telecommute:
  1. Practice communicating by email (especially when it is easier to talk in person about something) so you get better at writing emails that are complete and easy to understand.
  2. Practice doing as many normal activities on your telecommuting days as possible. Minimize "waiting until you get back to the office".
  3. Practice minimizing differences between your telecommuting and in-office days so that your telecommuting doesn't negatively affect the company.
For me #1 was the hardest to learn.

Monday, May 07, 2007

Method return values for null objects

Would it be useful to be able to provide method return value for null objects?
For a List the null return values might be:
get(int) : null
size() : 0
iterator() would be an empty iterator

That would allow the following code that has less null checks.

List items = null;

if(something) {
items = ...
}

for(int index = 0; index < items.size(); index++) {
Object obj = items.get(index);
}

Friday, March 30, 2007

Automatic casts

Why can't the compiler automatically insert casts?
List list = new ArrayList();
list.add("one");
list.add("two");
for(Iterator i = list.iterator(); i.hasNext(); ) {
String item = i.next();//Automatic casts
System.out.println(item);
}
//Or using the new for construct:
for(String item : list) {
System.out.println(item);
}

http://weblogs.java.net/blog/emcmanus/archive/2007/03/getting_rid_of.html shows that the compiler can get really close. Why can't it go the rest of the way?

Friday, March 16, 2007

IDE freedom

One way that I evaluate a new IDE is by opening a file in a fresh install and determining how much I can do with that file. Obivously features that need to know about the other files in the project won't work. I recently tried to use NetBeans and JDeveloper to generate getters and setters. Neither would allow me to do that and one of them allowed me to choose that menu item but it just did nothing at all. Maybe creating a project would have helped but that should be needless. When an IDE "gets in the way" with what I want to do like that then it feels more like a straightjacket than a tool. I know that is a simplistic evaluation but when that test fails I wonder how constraining the rest of the IDE is.
Do you think that is a fair way to evaluate?

Friday, February 23, 2007

Cygwin ssh and key files

I tried to use key files with Cygwin ssh (so I don't have to provide my password each time) but kept running into the following error:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '//turfclub/users/jstauffe/.ssh/id_rsa' are too open.
It is recommended that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: //turfclub/users/jstauffe/.ssh/id_rsa
The problem is that chmod wouldn't actually change the permissions so I couldn't get past this problem. When I searched on this I found refernces to turning StrictMode off but that didn't work for me can caused errors.

To fix this I did the following:
  1. Started my bash shell
  2. mkdir /home
  3. mkdir /home/.ssh
  4. cp ~/.ssh/* /home/.ssh
  5. chmod 600 /home/.ssh/*
  6. mv ~/.ssh ~/.ssh.bak
  7. cd ~
  8. ln -s /home/.ssh

It now works great (even in the normal Windows shell)!

Wednesday, January 17, 2007

Automatic casting

Is there any downside or problem potential to change the Java compiler to automatically cast? In the example below the result of list.get(0) would automatically be casted to the type of the variable hi.

List list = new ArrayList();
list.add("hi");
String hi = list.get(0);


I know that generics allow you to reduce casting but they do so at the expense of making declaration more difficult. To me, the benefit of generics is that they allow you to have the complier enforce more rules -- not they they reduce casting (but I haven't used them much so I am somewhat uninformed). This proposal would only reduce the amount of code to type, not move it to another place.

Tuesday, January 16, 2007

Who has changed the most lines in cvs?

The following was done on a Windows machine with UnxUtils.

cvs annotate > annotate.txt
rem remove the portion before the name
sed "s/^[0-9. (]*//" annotate.txt > annotate2.txt
rem remove the portion after the name
sed "s/[ ].*$//" annotate2.txt > annotate3.txt
sort annotate3.txt > annotate4.txt
uniq -c annotate4.txt > annotate5.txt

Monday, January 15, 2007

Tip: Need to communicate between anonymous inner classes?

Here is a quick tip:
Do you have two anonymous inner classes that need to communicate? I had two anonymous inner classes that implemented Runnable and needed to communicate with a boolean value. Therefore I decided to make a boolean variable in the declaring method but in order for the inner class to access the variable it needs to be declared final. But that would prevent me from changing the variable! I needed a mutable Boolean. Instead of creating a MutableBoolean class I declared the variable as "final boolean[] done = new boolean[]{false};" so that one thread could call "done[0] = true;" and the other thread could check "if(!done[0])". If there is a better pattern for this please tell me.

Background of why I needed this:
In an applet, I was saving data back to the server. In order to keep the UI responsive I of course do that in a separate Thread from the Event Distpatch Thread. When I save the data I first send then data and then read the response so the user only really needs to wait for the data to be sent. Therefore I have a timer that tells the user that they don't need to continue waiting after they have waited 30 seconds. But I don't need to pop that if the response is already read so I needed a way for the reader thread to tell the timer message Runnable that it was already done. I actually found a better solution: The reader thread can call stop on the Timer so that it is never run.

Tuesday, November 21, 2006

Thursday, November 02, 2006

Search and replace across files

Some of my co-workers had their cvs login name changed so we had the problem where every directory checked out from cvs had a CVS subdirectory with a Root file in it that had the old username. The easy way was to delete all checkouts and checkout again but if that would cause the loss of data we needed a different solution.

I handled my machine by doing a Windows search for all Root files, adding them to a new project in Source Insight, then doing a search and replace but others don't have nice editors like that. My machine had over 10,000 Root files so manual processes were out of the question.

For those without a nice editor that can do a replace across files I came up with the following solution:
  1. Install UnxUtils and add the main directory to the path.
  2. Run:

    find . -name Root -print | sed "s/.*/copy & &.new \&\& sed \"s\/jstauffer\/jstauffe\/\" &.new > & \&\&amp;amp;amp;amp; del &.new/" > Root.bat

    Windows has find so I had to make sure that it used the correct find. Basically it finds all Root files, creates a command to copy that file, use sed to do the replace back to the original file, and delete the copy of the file.
  3. Run Root.bat
I know the same could have been achieved in Perl or even Java but is there anything else that would be as quick and easy (granted it isn't easy to understand)?