My thoughts as an enterprise Java developer.

Monday, December 17, 2007

Telecommuting

I telecommute one day per week and used to telecommute 2 days per week. I would like to telecommute more but my employer isn't very open to doing that (except short-term for a specific project). I don't know of any Java enterprise developers that do major telcommuting (4 days per week or more). I have also not seen very many telecommuting jobs for enterprise Java developers. Why don't more exist?

Technorati Profile

Wednesday, December 12, 2007

Subversion: Moving tags

I wish Subversion had a better way of moving tags. The only way that I know to move a tag is to remove the file from the tag and then copy it again. Revision tree browsers don't seem to handle that very well. This also requires keeping the directory structure under the trunk and tag in sync.

Use case: We have thousands of "maps" and we want to tag which version of each map is the "production" version. We need to be able to easily get the production version of all maps.

Can anyone suggest a better way to address our use case?
I have considered properties also but then we can't get the prod version of all files easily. Merging to the tag doesn't appear to be very easy either.

Monday, November 26, 2007

IntelliJ default class javadoc comment

Why does the default IntelliJ default class javadoc comment use non-standard syntax? Instead of creating a line with "User: jstauffer" it could create a line with "@author jstauffer". The other lines that it creates (Date and Time) probably don't have javadoc syntax to use but why not use the javadoc syntax when available?

For reference here is an example:
/**
* Created by IntelliJ IDEA.
* User: jstauffer
* Date: Nov 13, 2007
* Time: 11:15:10 AM
* To change this template use File | Settings | File Templates.
*/

Naming abstract classes

Normally I see abstract classes named as AbstractClass. But when there are many abstract classes that leads to needing to type at least AbstractC when using code completion. Therefore I suggest that abstract classes be named ClassAbstract so that code completion is more usable. "Abstract" is a modifier on the class name anyway and it doesn't need to be in the primary position. What do you think?



I know this isn't a huge deal -- I am just suggesting it as a minor improvement.

Wednesday, November 21, 2007

Defaults have consequences: Microsoft Word margins

How much paper would be saved each year it Microsoft changed the default margins in Word to 1" on each side (or even 1/2")?

Friday, October 19, 2007

Autoboxing quiz

Does widening or autoboxing happen first? Which param method will be called from the autoboxing method? If one param method is commented out then it will have no problem calling the other.

private static void autoboxing() {
Integer integer = new Integer(2);
param(integer);
}

private static void param(int param) {
System.out.println("param(int " + param + ")");
}

private static void param(Object param) {
System.out.println("param(Object " + param + ")");
}

Thursday, October 18, 2007

Website idea

If you make your fortune with this idea, send me a few bucks.
Make a website where the user can keep a list of things that they need/want to buy.
Allow easy management of that list (through web, WAP, SMS, etc).

Then....
Work with stores so they the user can get a list of all of the items in the list that the given store has. The store could even allow printing the list from a kiosk in the store (registry computers) and would include the location, price, etc. The stores would benefit because people would probably buy more if they remembered what they wanted to buy and they would buy items that they didn't know the given store had. You could then charge the store a small fee so that you wouldn't need ads on the website or user fees.

For stores that don't support that use GPS to determine the store and try to send a list of items that the store has (scrape website?).

Does a website like this exist?

Wednesday, October 17, 2007

Haiku

One connection good.
Then two connections better.
Or maybe not so.

Tuesday, October 09, 2007

Form post with URL paramters (after question mark)

I had a URL that I wanted to POST with JavaScript so a made a

<form name="doForm" action="" method="post">
</form>
and used JavaScript to set the action and call submit. But Tomcat showed the request as a GET. I found that adding a dummy form input fixed the problem:

<form name="doForm" action="" method="post">
<input type="hidden" name="blah" value="blah"/><!-- need at least 1 input or the form uses method="get" even when "post" is specified. -->
</form>

Exception plan

In projects on which I have worked I find that a few common Exceptions are used over and over again and tend to lose their meaning. Does anyone have good resources for exception patterns?

Thursday, October 04, 2007

Subversion notes

We recently converted from cvs to Subversion and overall I like it much better than cvs but:

  • I wish cvs2svn converted .cvsignore files to svn:ignore properties.
  • I wish it handled tags and branches natively instead of using the copy method. Tags and branches are core parts of version control and I think something is lost by implementing them non-natively.
  • I hope svn:externals will be able to point to a specific file soon.
  • I wish update and status didn't print so much extra info about the externals. For status I have to run svn status --ignore-externals --show-updates %* | grep -v "^[XI]" | grep -v "^Status against revision" just to get what I want.

Tuesday, October 02, 2007

Converting .cvsignore file to Subversion svn:ignore property

If you have converted a cvs repository to a Subversion repository and need to convert .cvsignore files to subversion svn:ignore properties then the following script should be useful to you. Note that it probably doesn't handle spaces in filenames.

#!/bin/bash

find . -name ".cvsignore" -print | sed "s/\/.cvsignore//" | tee ignoredirs.txt

for i in `cat ignoredirs.txt`
do
echo Processing $i/.cvsignore
svn propset svn:ignore -F "$i/.cvsignore" "$i"
svn remove "$i/.cvsignore"

done

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.