Subversion: First Impression
Subversion is on the news lately with its 1.0 release.
I've heard about Subversion for a few years now. I just never used it. I remembered seeing Subversion being installed as part of Fedora Core 1 when I installed it on my laptop 110 days ago. It's version 0.32.1. According to the Subversion status page, this was released on October 23, 2003, and the 1.0 release was branched from 0.35 on December 19, 2003. So I decided to try out Subversion 0.32.1. It can't be too far from the 1.0 release.
Subversion is billed as a compelling replacement for CVS in the open source community. What is the number one thing that I do with CVS? Getting the sources of an open source project. Wouldn't it be nice if I can grab the source of a project with Subversion? But which projects are using Subversion as their source control system? I bet the Subversion guys are eating their own dog food!
Sure enough, their version control page tells how:
To check out this project, use a Subversion client like so:
$ svn co http://svn.collab.net/repos/svn/trunk svn
Issuing the command from my GnomeTerminal resulted in this:
[weiqi@gao] $ svn co http://svn.collab.net/repos/svn/trunk svn A svn/Makefile.in A svn/ac-helpers A svn/ac-helpers/install.sh A svn/ac-helpers/install-sh A svn/build.conf ...
Worm and fuzzy!
What about update?
[weiqi@gao] $ cd svn [weiqi@gao] $ svn up At revision 8860.
Nice touch. The update command recurses over all subdirectories by default. The -N option makes it non-recursive.
svn diff generates diff files in the unified output format (the format generated by cvs diff -u), the diff file format requested for most other open source projects.
svn log works just like cvs log and display the log messages of past commits.
Since co, up, diff and log are the only four CVS commands I ever used when participating in a CVS based open source project, I'm now confident that I can participate in a Subversion based open source project comfortably as well.
I'm Going To Reuse It
Lately I've been thinking about why it is that programming is so hard. I'm convinced that programming is hard because we make it hard ourselves.
How do we make programming hard? Easy, just follow some "in fashion" advice blindly without thinking. Here's some examples:
- I'm going to reuse it. I hear this phrase uttered too often while a programmer is working on a specific problem. The desire to make the solution general also makes the solution complicated. Without the actual "here and now" reuse to test for the "general" solution at another spot leaves the solution not general enough, making it unusable when the time comes. At the end, a lot more complexity without any pay off.
- I'm about to write a new class. I'll write an interface for it. The use of interfaces at strategic places when different subsystems interact with each other is a good thing. Over use it, at a level where things should be tightly couple, you are inviting more work. Not only can't you navigate from the call site to the definition within an IDE, you are also required to modify two places every time your class changes.
- I'll just call super. In rare situations when you are using a class library not of your own making, and when you painted yourself into a corner, override a method and then calling super can be used as a last resort. In all other cases, you are better off not do it.
- I'll just create a thread. I don't need to synchronize anything. No, you won't! As soon as you create that thread, the need to synchronize will be apparent to you. And nine times out of ten, you wish you have not used threads.
- This class should be a singleton. Really? Have you read about the guarantees provided by your favorite language for static initialization?
- This is just an Abel-Galois permutation convolution isomorphism. I'll just use the Hamilton-Vick-Sylvester algorithm here. Say good-bye to maintainability of your code by anybody else but you.
Don't know about the Hamilton-Vick-Sylvester algorithm? And you call yourself an Architect?
Pebble 1.4 Final Is Here
Simon Brown released his excellent weblog software Pebble 1.4 today. (It's still Sunday around here, java.lang.System.nanoTime() being 1077499848027663000 right now.)
So I grabbed the war file (actually did a cvs up -dP; ant dist) dropped it in to my JBoss instance, worked on the theme a little bit. I do have to restart JBoss this time to make the newer version work. Otherwise JBoss would complain about a tag not being defined in admin.jsp. I think it has something to do with the way JBoss loads classes.
I'm also doing something new this time. I have enabled pinging of JavaBlogs.com on new postings. I'm eager to see how that works.
Just last week I was talking with a colleague about Weblog software and here's what I told him:
That depends on what you want to do. Pebble certainly has been good for me. I actually tried to setup Roller before I heard of Pebble, but Roller is just too complicated for me.
Pebble pros:
- Open Source
- Simple to setup
- Data are saved in a directory structure (that I commit to CVS on a different box everyday)
- Data files are XML
- Simple web interface to write blogs and administer site (altering themes, upload images, etc. from anywhere on the Internet)
- Supports multiple users each with different themes (I haven't used it)
- Categories (I haven't used it)
- Pinging aggregator sites such as JavaBlogs.com when posting new blogs (I haven't used it, JavaBlogs.com polls my server every 2 hours)
- I've been running it for 214 days, and Pebble never died on me. Then again, I don't draw that much traffic.
Cons:
- No spell checker (I have to preview, copy to file, run spell on file)
- Hand code of HTML tags (not that big a deal for me)
- Single man project (Simon Brown has been very responsive though)
I'm not trying to put down other Weblog softwares here. I'm just saying for my use case, a one person blog on a cheap Linux box behind a DSL line, Pebble has been a good fit.
Thanks a lot Simon!
We Learn, We Marvel, We Forget, ...
Went to a internal lunch meeting yesterday with Zhicheng Li and Shu Zhu at OCI, where Mark Volkmann talked about groovy. (Mark will present on the same topic at the No Fluff, Just Stuff symposium in St. Louis March 19-21, 2004.)
Here's the conversation on the ride back:
When do you think groovy will achieve mainstream acceptance?
It probably won't. And it doesn't need to be.
But BeanShell is being used in important products, that's close to mainstream acceptance.
I'm sure the others, Rhino and Jython, are also being used in other important products. We just don't know yet.
Will we see a big project written entirely in groovy?
Probably not. But I sure can use some of those list iteration facilities. Closures too. :)
You'll know it if you really need something like groovy in your product. If you have to wait for "mainstream acceptance", you probably don't need it.
Maybe Sun should standardize on a scripting language API, so that we can plug in any scripting languages.
I don't like that kind of an API. It actually will lock the developers down and lock vendors out.
Let's go back to Java.
We went back to plain Java coding, using getters and setters and anonymous inner classes and if/then/else statements. The C-style for loop, now, what, 35 years old, worked just fine.
IDEA 4.0, J2SDK 1.5.0 Beta 1, Generify, ...
Got my brand new IDEA 4.0 today, and immediately saw the "Generify..." Refactoring. Given:
interface I {}
class A implements I {}
It turns code like this:
List list = new ArrayList();
list.add(new A());
Iterator iter = list.iterator();
while (iter.hasNext()) {
I i = (I) iter.next();
System.out.println(i);
}
into this:
List<I> list = new ArrayList<I>();
list.add(new A());
Iterator<I> iter = list.iterator();
while (iter.hasNext()) {
I i = iter.next();
System.out.println(i);
}
You can even select multiple classes from the Project Tool Window, and select Refactor | Generify from the context menu to have it done to all of them. Really slick!
Figuring out how to use the 1.5.0 compiler with IDEA 4.0 is a little bit challenging because the documentation still talks about the add_generics-2_2-ea.zip and the gjc-rt.jar and collect.jar files therein.
It turns out, with the 1.5.0 compiler, you don't have to do any of that. Simply:
- Select 1.5.0 as the compiler for the project as you would normally do
- Uncheck the "Use generics-enabled compiler" check box in Compiler settings dialog box
- Add "-source 1.5" to the "Additional javac command line parameters" field
J2SDK 1.5.0 Beta 1, Class File Versions, Compatibility, ...
When I tried the J2SE 1.5.0 Beta 1 nine days ago, I was met with a slew of exceptions, including a java.lang.ClassFormatError:
Thrown when the Java Virtual Machine attempts to read a class file and determines that the file is malformed or otherwise cannot be interpreted as a class file.
To find out why, I compiled "interface X{}" with both 1.4.2_03 and 1.5.0 and compared the results:
[weiqi@gao] $ ls -l X.class.* -rw-rw-r-- 1 weiqi weiqi 83 Feb 14 06:28 X.class.1.4.2 -rw-rw-r-- 1 weiqi weiqi 83 Feb 14 06:32 X.class.1.5.0 [weiqi@gao]$ od -t x1 X.class.1.4.2 0000000 ca fe ba be 00 00 00 2e 00 07 07 00 05 07 00 06 0000020 01 00 0a 53 6f 75 72 63 65 46 69 6c 65 01 00 06 0000040 58 2e 6a 61 76 61 01 00 01 58 01 00 10 6a 61 76 0000060 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 06 00 00 0000100 01 00 02 00 00 00 00 00 00 00 01 00 03 00 00 00 0000120 02 00 04 0000123 [weiqi@gao]$ od -t x1 X.class.1.5.0 0000000 ca fe ba be 00 00 00 30 00 07 07 00 05 07 00 06 0000020 01 00 0a 53 6f 75 72 63 65 46 69 6c 65 01 00 06 0000040 58 2e 6a 61 76 61 01 00 01 58 01 00 10 6a 61 76 0000060 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 06 00 00 0000100 01 00 02 00 00 00 00 00 00 00 01 00 03 00 00 00 0000120 02 00 04 0000123 [weiqi@gao]$ jcf-dump X.class.1.4.2 Reading .class from X.class.1.4.2. Magic number: 0xcafebabe, minor_version: 0, major_version: 46. ... [weiqi@gao]$ jcf-dump X.class.1.5.0 Reading .class from X.class.1.5.0. Magic number: 0xcafebabe, minor_version: 0, major_version: 48. ...
So the major version number of class files generated by default from javac has been bumped up, from 46 to 48.
On a practical level, this means that JODE 1.1.1 won't work with 1.5.0 anymore, even for java.lang.Object. :(
The class file version number is controlled by the -target switch on the command line:
| -target | major | minor | note |
|---|---|---|---|
| 1.1 | 45 | 3 | 1.4.2_03 only |
| 1.2 | 46 | 0 | -source 1.2 switch needed for 1.5.0 |
| 1.3 | 47 | 0 | -source 1.3 switch needed for 1.5.0 |
| 1.4 | 48 | 0 | |
| 1.5 | 49 | 0 | 1.5.0 only |
All of this indicates that the upgrade from 1.4 to 1.5 will be harder than the upgrade from 1.2 to 1.3 or from 1.3 to 1.4. It will more likely be as hard as the upgrade from 1.1 to 1.2. Remember that?
Web Services, SQL, XQuery
Mark Volkmann talked about J2EE's Web Services APIs at St. Louis Java Users Group tonight. Slides will be posted soon. Watch this space.
SAAJ, XML-RPC, JAXR, WSDL, UDDI, SOAPEnvelop, Axis, DIME, doc/literal, etc., ...
Update: The presentation slides are here.
Jason Hunter posted on the XQuery mailing list an interesting article on the commoditization of SQL by Jim Melton of Oracle.
Jim's future has XQuery in it.
Jason Hunter also let slip that he's working on an XQuery book for O'Reilly.
Java Service Wrapper
Saw a glowing review of Java Service Wrapper:
Nick Minutello: Java Service Wrapper is an excellent open source tool for running your java application as a Windows Service / Unix daemon.
I have been using it to on both Linux and Windows 2000 to start JBoss (where this blog runs) for quite some time now. And I have to agree with Nick that it does work as advertised.
Thank you, Java Service Wrapper team.
An Evening of Exceptions
J2SE 1.5 is indeed a major upgrade. Here's just a few exceptions I encountered (while using everyday Java based tools):
- java.lang.ClassFormatError
- java.lang.InstantiationException
- java.lang.ClassNotFoundException
- java.lang.NoClassDefFoundError
- javax.management.InstanceNotFoundException
On the other hand the new features are cool. Time to review Jeff Brown's J2SE 1.5 Overview presentation at the St. Louis Java Users Group.
XQuery, Kawa, Readline, ...
In my Introduction to XQuery article posted 32 days ago, I used Per Bothner's XQuery processing tool Qexo.
Qexo is actually a small part of something bigger called Kawa that started out as a Scheme implementation but grow into a JVM language framework that supports other languages.
One key feature of Kawa is that it compiles programs (scheme, XQuery, etc.) down to Java bytecodes without going through the JDK's compiler (no intermediate Java source code, no temporary working directory to hold them, compiled classes can be loaded immediately to the JVM). Another feature is its interactive shell that supports the GNU readline command line editing and command line history, which makes using it that much friendly.
Building Kawa on Linux is a breeze. You just do something like:
[weiqi@gao] $ ./configure --prefix=/opt/kawa \
--enable-kawa-frontend \
--enable-servlets \
--enable-swing
[weiqi@gao] $ make
[weiqi@gao] $ make install
However building Kawa on Windows is not easy. You can build it using Ant, but then you don't get to use the Readline command line editing feature. In the past I have modified the generated Makefiles to straighten out the CLASSPATH handling (Sun's javac doesn't like colon separated CLASSPATH, which the Makefile uses).
Lately I've found a workaround that will build Kawa on Windows with GNU readline support. To do this you need to have Cygwin (which includes GCC 3.3.1, and GNU readline) installed. The idea is to build Java class files and the jar file using Ant, and then build the Kawa frondend, a native program with readline support, whose source files and Makefile reside in the bin subdirectory, using GCC. Here's the full procedure:
[weiqi@gao] $ ./configure --prefix=/opt/kawa \
--enable-kawa-frontend \
--enable-servlets \
--enable-swing
[weiqi@gao] $ ant
[weiqi@gao] $ cd bin
[weiqi@gao] $ make
[weiqi@gao] $ cd ..
[weiqi@gao] $ make install