July 2004 Archives

Eric M. Burke

AddThis Social Bookmark Button

Brian talked about Subversion at the OCI monthly Java lunch. (I know, it’s not technically a Java topic, but we digress some months). It was a good presentation, although 1 hour is not enough time.

The truth is, I’ve tinkered with Subversion here and there and fully intend to start using it. I currently use CVS at home and StarTeam at work. None of these is an ideal solution, but I believe Subversion will win people over in the long run. I’ve also used Visual SourceSafe at a previous job, as well as ClearCase a long time ago.

I only really heard of two Subversion limitations:

  1. The GUIs are not mature - CVS offers good GUIs and tight integration with IDEs. The Subversion IDE integrations are crude in comparison
  2. Subversion offers no exclusive locking scheme, which is essential in some environments. Don’t get me wrong, I prefer the concurrent editing mode of CVS and Subversion. However, many organizations store lots of big binary files in version control - like Word docs. Merging those kinds of files is either impossible or a pain, at best. Plus, some companies just won’t let you use a tool that does not support exclusive locking. Argue the merits of this if you will, the fact is that some companies just work that way. I heard that exclusive locking will be included in a future release, so it will not be a problem for long.

Subversion has a rock solid version control infrastructure under the covers. Here are some features that many other version control tools - surprisingly - don’t have:

  • The ability to version directories.
  • The ability to re-add files after you delete them, preserving the old history. StarTeam, for example, cannot do this.
  • An efficient branching and merging model.
  • Every operation is versioned - things like moves, copies, deletes, etc…
  • You can attach arbitrary attributes to any file, which is great for linking files to defects, for example.

Things like first-class GUIs and IDE integrations will be available for Subversion. It will take some time to catch up to CVS, but Subversion will catch up.

Eric M. Burke

AddThis Social Bookmark Button

Version 4.5 of the best Java IDE was released today. The biggest new feature? IDEA now supports JDK 1.5 syntax.

Marc Hedlund

AddThis Social Bookmark Button

Related link: http://www.bestpractical.com/rt/

Boy, I thought RT helped me out in my work, but my experience is nothing compared to this. Jesse Vincent is giving a tutorial on customizing RT here at OSCon, and as an aside he mentioned that a German peer-counseling group is using RT to track incoming emails from people in need of counseling. The group has customized RT so that if an email is sent in containing the words “suicide” or “kill myself,” the counselors get an immediate pager alert. I’m quoted on the RT praise page as saying I’d be screwed without RT; and the quote below mine says “RT *saved my life*.” It’s amazing how literally those words are true in Jesse’s anecdote.

Has software you’ve written ever saved a life?

Russell Miles

AddThis Social Bookmark Button

Related link: http://www.apple.com/downloads/macosx/development_tools/mono.html

I’m a Java and AspectJ developer at heart but, never one to ignore a programming language or technology, I’ve been playing with Mono on my Windows box at home when I was sent away on business with just my powerbook. Don’t get me wrong, I prefer the p’book anyway but I was playing with C# at the time and I could remember the all-too-recent pain I’d gone through getting mono onto my home iMac and so I was not relishing the same pain again in getting my new powerbook up to speed.

Then I found out that I needn’t have worried! The kind people at Novell have released a nice and easy way of getting mono onto OS X. It’s been up and available for a while, so my apologies to those out there who are going ‘duh, you’re slow on the uptake’, but I thought it was worth a posting here so that at least if anyone searches in the future then there’s an even better chance that they’ll go straight to the easiest way of getting mono on their mac.

Eric M. Burke

AddThis Social Bookmark Button

I’m trying to evaluate Macromedia Flash MX just for fun. I never used the product, and the GUI is proving to be quite difficult to learn.

I can generally figure stuff out, but lack of tooltips is driving me nuts. What the #$%^ do these buttons do:

image

A simple tooltip would likely make these buttons obvious, but half of the buttons in the Flash MX GUI don’t have any tips. No status bar line help, either. Nor do they have the typical “Context Help” toolbar button that would let me click on the button to figure out what it is. To top it off, I cannot even right click on these buttons to figure out what they do. No context menu, nada, zero.

Another gripe - keyboard shortcuts are not consistently displayed. You can right-click on the timeline and select “Insert Keyframe”. The menu does not display the fact that you can also hit F6 to insert the keyframe. How are us hapless users supposed to figure out keyboard shortcuts for all of the other menu items? It sure would be nice to display the shortcuts right there by the menu text, just like a sane person would expect a GUI to do.

My Flash MX evaluation is not getting off to a good start. I’ve spent about an hour tinkering, another 15 minutes writing this blog blowing off steam, and I’ve barely scratched the surface of what this tool is supposed to do.

The most frustrating part? Things like tooltips, context help, and displaying keyboard shortcuts are insanely easy things to add to the GUI. Adding these features to the GUI is trivial, making the tool infinitely easier for newbies. Seems like a no-brainer to me.

Marc Hedlund

AddThis Social Bookmark Button

Related link: http://www.blogonevent.com/blogon2004/

At the “Publishing Models” session of the BlogOn conference, people are bringing up all the arguments against adoption of RSS. “It’s too techy.” “Publishers will want control of their content.” “It will be too hard to monetize.” “Consumers will not understand what RSS means.”

All of these arguments remind me nearly verbatim of the objections to adoption of the Web ten years ago. http://? Give me a break! Give newspaper content away for free? How will that ever work?

It seems to me that commerce will find a way. I look at the great RSS products, my favorite being Bloglines, and I can clearly see analogous methods for them to become very big businesses, just as Web sites have become commercially successful today — even newspaper Web sites.

Marc Hedlund

AddThis Social Bookmark Button

Related link: http://www.blogonevent.com/blogon2004/

Halley Suitt: “Rafat, how do you think traditional media is reacting to RSS?”
Rafat Ali: “Traditional media? You mean c|net?”

Diego Doval

AddThis Social Bookmark Button

When obtaining content from websites (either for a server-based app, such as a crawler, or for a client app, such as a newsreader) it’s a good idea to avoid downloading content when possible. Additionally, many if not most servers
support dynamic stream compression, which has a big impact on download speeds, particularly when obtaining text-only
data (e.g., an RSS feed, which if every aggregator did, would help with problems like these). Throughout the Net there are a number of descriptions how to use some of these elements (For example, here is a good guide for conditional GETs, here is one for server-side compression), but I haven’t seen an example of Java client-side code that pulls all the basic techniques together in one place–so here it is.

Basically there are two things to deal with: the first is use of the ETag and Last-Modified headers that allow the server to reply with a 304 (Not modified) response code, thus avoiding altogether download of data we’ve already obtained. The second is that when there is a download, we allow the server to send the content compressed (in GZIP or Deflate –ZLib– formats) to save download time. For text content, compression can reduce the size of the download by a factor of 5 or more.

Without further ado, here’s the code:

...
//create a URL to O'Reilly's Atom feed
URL sourceURL = new URL("http://www.oreillynet.com/meerkat/?_fl=rss10&t=ALL&c=5209");
//obtain the connection
HttpURLConnection sourceConnection = (HttpURLConnection) sourceURL.openConnection();
//add parameters to the connection
sourceConnection.setFollowRedirects(true);
//allow both GZip and Deflate (ZLib) encodings
sourceConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");

// obtain the ETag from a local store, returns null if not found
String etag = loadETag(); 

if (etag != null) {
  sourceConnection.addRequestProperty("If-None-Match", etag);
}

// obtain the Last-Modified from a local store, returns null if not found
String lastModified = loadLastModified();
if (lastModified != null) {
  sourceConnection.addRequestProperty("If-Modified-Since",lastModified);
}

//establish connection, get response headers
sourceConnection.connect();

//obtain the encoding returned by the server
String encoding = sourceConnection.getContentEncoding();

//The Content-Type can be used later to determine the nature of the content regardless of compression
String contentType = sourceConnection.getContentType();

//if it returns Not modified then we already have the content, return
if (sourceConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
  //disconnect() should only be used when you won't
  //connect to the same site in a while,
  //since it disconnects the socket. Only losing
  //the stream on an HTTP 1.1 connection will
  //maintain the connection waiting and be
  //faster the next time around
  sourceConnection.disconnect();
  return;
}

//get the last modified & etag and
//store them for the next check
storeLastModified(sourceConnection.getHeaderField("Last-Modified"));
storeETag(sourceConnection.getHeaderField("ETag"));

InputStream resultingInputStream = null;

//create the appropriate stream wrapper based on
//the encoding type
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
  resultingInputStream = new GZIPInputStream(sourceConnection.getInputStream());
}
else if (encoding != null && encoding.equalsIgnoreCase("deflate")) {
  resultingInputStream = new InflaterInputStream(sourceConnection.getInputStream(), new Inflater(true));
}
else {
  resultingInputStream = sourceConnection.getInputStream();
}

...

//now the stream can be read directly,
//and the data will be on the contentType received above.

Basically the code sets up the connection and adds the “gzip” and “deflate” encodings as recognized encodings by the app, and if ETag/Last-Modified values exist then they are added to the request with the If-None-Match header for ETag and If-Modified-Since header for Last-Modified, allowing the server to check if the content has changed since that check. If the ETag and Last-Modified are null (that is, this is the first time we are downloading the page) then they are not included in the request.

Once we establish the connection through connect() we check whether the reponse code is “not modified” and in that case we simply disconnect() and return, otherwise we continue by storing the Etag and Last-Modified values returned, and then creating the appropriate wrapper (depending on the content encoding returned by the server) for the network stream so that the content will be decompressed on the fly if necessary.

And that’s it!

PS: the loadETag(), loadLastModified(), storeLastModified(…) and storeETag(…) methods require a persistence layer of some sort (simple Java serialization would do) to access the ETag and Last-Modified values between runs of the application. Since this is heavily dependent on the application, they are not included.

AddThis Social Bookmark Button

Related link: http://subversion.tigris.org

Building Subversion on Mac OS X is
not hard. Building the Java bindings for
Subversion is challenging until you know what to do. Hopefully you find this
information helpful.

This blog shows how to build Subversion and the Subversion Java bindings. Why?
There are a few reasons you may need the Java bindings:

  • You want to write Java code to communicate with Subversion
  • You want to use SvnUp, which
    can be installed as a plug-in to
    IDEA

Install Subversion

Before we get started you need to install a
Berkeley DB
.
I have version 4.2 installed. They have plenty of documentation to help you.

Step 1

As of today, this is a two step process:

  1. Build and install a stable release version (currently 1.0.5) of the client
  2. Use the stable release version to checkout the latest source
    from the repository

NOTE: In order to build the Java bindings we need the latest source. Version 1.0.5
does not appear to support building the Java bindings using --enable-javahl and
SWIG does not work.

NOTE: Once version 1.1 becomes stable you should be able
to build the Java bindings using that code base, thus checking out
the latest code is no longer necessary.

NOTE: I was unable to build the Java bindings using
Subversion 1.1 RC1, thus having to build against the HEAD of the
repository. You may have better luck.

Once you have the stable release of Subversion installed use it to download the
latest version Subversion source code from the repository:

  svn co http://svn.collab.net/repos/svn/trunk subversion-tip

Now change to the source directory

  cd subversion-tip
NOTES
The Subversion revision number in this example is 10351.

Step 2

Execute autogen.sh

  ./autogen.sh

Step 3

Execute configure

./configure 
  --enable-javahl
  --with-jikes=no
  --prefix=/usr/local/svn-trunk-10351
NOTES
--enable-javahl
Enable compilation of Java bindings. This option appears to only be
available on version 1.1 and higher. I tried and tried to get version 1.0.5
to build using SWIG. I gave up on SWIG when I found out from
Weiqi
that the latest version supports javahl.

--with-jikes=no

For some reason Jikes is the default compiler. If Jikes is used the
configure script does not appear smart enough (on Mac OS X) to build the
classpath needed to compile the Java bindings. Disabling Jikes “enables” the
javac compiler, which works without any problems.

--prefix=/usr/local/svn-trunk-10351
You can put the compiled libraries where you want. I like to keep them
bundled in their own directory.

Step 4

Execute make

Step 5

Execute make javahl

NOTES
You may receive an error really quick. If the error has anything to do
with the /subversion/bindings/javahl/classes directory
not being found then manually create
the directory. Specifically, the classes directory does not exist.

Step 6

Execute make install

Subversion should be installed at /usr/local/svn-trunk-10351.

Step 7

Execute make install-javahl

The Java Bindings API should be installed at
/usr/local/svn-trunk-10351/lib/svn-javahl/svn-javahl.jar

Using The Java Bindings API

We have successfully built Subversion and the bindings
(svn-javahl.jar)
necessary for us to write Java code to talk with Subversion. Let’s take a
look at how we can get started using the API.

Here’s a class that uses the svn-javahl API:

import org.tigris.subversion.javahl.SVNClient;
import org.tigris.subversion.javahl.Notify;
import org.tigris.subversion.javahl.Revision;

public class SubversionDemo {

    public static void main(String[] args) throws Exception {

        SVNClient client = new SVNClient();

        // The SVNClient needs an implementation of Notify before
        // successfully executing any other methods.
        client.notification(new Notify() {
            public void onNotify(String path, int action, int kind,
                    String mimeType, int contentState, int propState,
                    long revision) {
                System.out.println("SubversionDemo.onNotify");
            }
        });

        // Assume that there is a valid repository with a project called
        // 'freedom'.
        client.checkout("file:///Users/briancoyner/svn-repository/freedom",
                "/Users/briancoyner/MyProjects", Revision.HEAD, true);
    }
}

NOTE: Be sure to add the svn-javahl.jar file to
your classpath.

After running this you should see this error message:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no svnjavahl in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
	at java.lang.Runtime.loadLibrary0(Runtime.java:788)
	at java.lang.System.loadLibrary(System.java:834)
	at org.tigris.subversion.javahl.SVNClient.(SVNClient.java:48)
	at com.briancoyner.subby.SubversionDemo.main(SubversionDemo.java:13)

The SVNClient object tries to load one of these native libraries
using System.loadLibrary (in this order):

  1. svnjavahl-1
  2. libsvnjavahl-1 (Mac OS X naming convention)
  3. svnjavahl

The “actual” native library on Mac OS X is called libsvnjavahl-1.0.dylib,
located under /usr/local/svn-trunk-10351/lib.

Mac OS X loads libraries
that start with lib and end with .jnilib.
A symbolic link named libsvnjavahl-1.jnilib already exists pointing to
libsvnjavahl-1.0.dylib, so we can simply
copy the link to a location known by the System property java.library.path.

I did this: cp libsvnjavahl-1.jnilib /usr/lib/java

You should now be able to:

  1. use Subversion from the command line
  2. write Java code to communicate with Subversion

I hope this helps.

I dislike developing on Windows but at least there are pre-built libraries that are easy to install.

Eric M. Burke

AddThis Social Bookmark Button

Related link: http://madbean.com/blog/2004/17/totallygridbag.html

Check out this flash animation showing a programmer trying to figure out GridBagLayout.

James Elliott

AddThis Social Bookmark Button

Related link: http://www.brunchboy.com/displaywatcher.shtml

One of my favorite features of Mac OS is how easily you can connect multiple displays, and spread your desktop between them. Heck, Microsoft even figured this one out after a decade or so. This means that when I’m at home, I like to have my PowerBook plugged into a nice big display, which has plenty of room to show the dock, while putting palettes like my DragThing window on the built-in display off to the side.

When I’m on the road, I have less real estate, so I like to hide the dock, and position a more compact DragThing configuration at the bottom of the screen, showing its own process dock.

Mac OS is very good about remembering the physical relationships between different displays that I connect, but I was still spending more time than I liked manually toggling the dock and switching between DragThing settings. So, being a typical proactively lazy geek, I decided to build a tool to do this for me. It would be a great excuse to learn a little Cocoa programming.

I’ve been using DisplayWatcher for a few months now, but I still get a little thrill out of watching the dock and DragThing reconfigure themselves, as if by magic, when I plug in or disconnect an external monitor. I also added the ability to run a script whenever my PowerBook wakes up from sleep–I use this to re-establish SSH tunnels for accessing and sending mail through my personal and corporate IMAP servers, CVS and the like. Now I’m far less reluctant to put my machine to sleep or move to other rooms, because there is no more hassle involved. That’s how a laptop should work!

Since DisplayWatcher seems very stable, I’m making it available for others who might find it useful. For now it is a binary-only download, but when I have time to write up some in-depth explanation, I hope to release it as open source as well. I certainly found it an instructive project myself, and would like to share that aspect as well.

If you’re interested, follow the URL associated with this posting and check out the instructions, or download it and play with it.

If you download and use it, please let me know… especially if you come up with interesting new scenarios!

Eric M. Burke

AddThis Social Bookmark Button

Quick…what is the number one source of bugs?

My answer is “duplication”.

Eric M. Burke

AddThis Social Bookmark Button

I finished off my basement a few years ago. I thought it would be cool to add a little high tech flash, so I put all of the basement lighting on X10. It was nice because I only had to run one wire to a bank of X10 dimmer switches that lets me adjust all the lights from a single spot. Cool.

Until a few months ago.

Now my lights turn on and off by themselves, and I don’t know how to diagnose the problem. I cannot think of any new electronic devices in my home…my assumption is that some signal is coming in from outside the house. It started with one particular light, then over the subsequent weeks the other lights in the basement started turning on and off by themselves. A light may switch on or off every 15-30 minutes now.

Maybe my house is haunted. Nah, that’s a stupid theory.

Do I need a Whole House Blocking Coupler? I’m reluctant to spend $75 and rip into my main breaker box based on a hunch. Is there any way to know what is causing this problem before I start buying new devices?

Dejan Bosanac

AddThis Social Bookmark Button

Even if you try to develop a total Java solution, you always need some kind of shell scripting. For standalone applications it is not convenient to let your users start an application by typing

java -Djava.util.logging.config.file=app.properties -cp path_to/lib.jar -jar app.jar

So in most cases these applications have shell scripts for starting and stopping the application. In some cases you’ll need few more scripts that works with your application.
Common tasks for startup script are:

  • Setting local classpath for application
  • Testing if required environment variables are set
  • Executing java application

Why should you use groovy for this? and how?
First of all, Java developers find Java-like syntax scripting language easier to use, but huge advance is that you have access to all Java libraries that you need. For example you can establish XML-RPC or database connections if you have to.
I have the Java application that have XML-RPC interface and tends to crash from time to time because of unexpected signal 11 (more on this in some future post). I’ve created a groovy script that calls dummy XML-RPC method of the application and if an exception is thrown (meaning that application is not working properly) application is restarted. I’ve put this script in cron to be executed every five minutes and in case that application crashes it is restarted in few minutes. It’s needless to say that I’m sleeping much better since then :). Of course this could be done in million other ways, but the point here is that this is ten-lines script and ten minutes of work.

We can also go one step further. Most of these standalone application main methods do tasks like:

  • Parsing command line arguments
  • Reading property files
  • Initializing and configuring other classes in order to run application (Loggers, scheduler, server threads, …)

This tasks could be also moved to startup scripts, leading to more maintainable application.
Command line argument parsing is the ideal job for scripting, because it’s all about string comparison.
Some of the basic configuration parameters could be set on the top of the script too. Of course you can’t avoid property files in general, because many libraries use them.
And if you have all the arguments and configuration parameters, you are free to initialize your object properly.
To make a shell script with groovy, all you need to do is to put

#!/usr/bin/env groovy

in the first line of the script, and you are back in Java-land.

Have you find any useful usage of groovy as a language for shell scripting?

Advertisement