Why I Like the MacBook (and Other Things)

Note: I posted this already a few days ago, but then the post got lost and my blog started acting up, creating two copies of every post I wrote. I hope that’s now fixed.

A friend of mine recently sent me an email and asked me about my opinion about Macs. He had never used or liked Macs or Linux very much, but this is changing due to his job, and he wanted some input for making personal product chocies.

I have never found Mac particularly appealing, but neither did I find Linux appealing;

I was pretty much in the same camp, which is probably not a camp at all: I wasn’t for Macs, I wasn’t for Windows, but I also wasn’t for Windows or against the other two. I just didn’t want to find something cool just because the in-crowd thought it was cool.

My view of Linux changed when I got a CSnet account (Owlnet wasn’t enough), and when Corky accidentally ordered two MacBooks, of course I said yes, I’d take one. Who wouldn’t? Working with the MacBook and MacOS X dramatically changed my view of Macs, and now I love the Mac notebooks. I have no real opinion of Mac desktops though.

But Linux, or bash or some kind of descent shell is a must-have for me. I just can’t deal with Windows’ cmd.exe, because quite often I want to recursively search a directory for files of a certain name, then filter out the files that do not contain a certain string, etc. And it’s so easy with bash, but virtually impossible with cmd.exe, unless you have special programs, and they tend to be heavy-weight.

yet after working with it more, I see its advantages, and I can begin to see why you find working on Windows impossible without Cygwin. I can see why Mac might seem the perfect hybrid platform — real Unix back end and consoles, but with a beautiful user interface (which is Unix’s primary failing) and good hardware compatibility.

Especially since you can, almost without performance penalty on x86 Macs, emulate Windows using Parallels Desktop or vmWare. I don’t anymore since I lost my MacBook hard drive, but for a while I ran Windows 2000 effortlessly within Mac OS, including file transfer, drag and drop, and clipboard.

These are things I can see, but I wanted to ask you personally. What do you find so appealing about the Mac laptop?

I find myself doing almost everything casual on the MacBook. Only stuff that requires lots of screen real estate I do on my Windows PC (but then again, I can’t speak for dual-screen Mac desktops). The GUI is just very slick, easy to use and intuitive. You can literally do most things with just one finger.

Then there is the other side, a solid Linux-style operating system underneath, with all the strength of Linux shells. As a bonus, all free Linux apps that you have to compile also work on the Mac, and that’s a lot. I guess they work on Windows too, if you have Cygwin and do some configuring.

What I don’t like about the Mac is that it’s impossible to list folders first in the Finder (=Explorer). Whenever someone asks for that feature, the reply of the Mac-Nazis is “that’s a Windows thing; get used to how it’s done on the Mac.” Not very satisfactory, I think. But there are 3rd party programs like Pathfinder that solve the problem.

Another problem is that Java on the Mac always lags behind a little. Java 6 is only available as a beta for 10.5 (Leopard) right now, because Apple implements the JVM itself, not Sun.

And then there’s the issue about maximizing applications. To me, maximizing means “let it take up the entire screen”. To Mac users, it apparently means “give it the space the application thinks it needs”, which may be less than the entire screen.

As a summary, I’m very glad that I have the MacBook, because I tend to do nearly everything on it: casual web browsing, writing emails, anything that requires a command line, most development work (except major refactoring, etc.).

I have never spent much time on Apple computers, but I have found myself increasingly liking Apple products. The iPhone is quite nice and I would probably get one if I were richer;

I’ve tried the iPhone a couple of times, and I don’t like it. I like the stylus and touch screen on my Palms, but I wouldn’t want to go without any buttons. I’m not gonna get an iPhone, even if I were richer ;-)

I just got the new Apple USB keyboard which is *amazing*, best keyboard I have ever used;

I don’t know about Apple keyboards, I still like my MS Natural Keyboard Pros. One thing I’d never get from Appe is a mouse, though ;-)

the latest iPods all look sick, etc.

Never had an iPod either, but I’ve been successfully using my Palms as MP3 players for years.

I guess my conclusion is this: As desktop, I’d probably still buy a Windows or Linux PC, not an Apple. Maybe this is just lack of experience, but price also plays a role, and I have a feeling that Macs won’t play as nicely with dual displays. As a notebook, I would definitely buy a MacBook again if I had to. If Corky took the MacBook he loaned me away from me, I’d have to bite the bullet and buy one right now. I had to live without one when the power supply crapped out
on me, and it wasn’t pleasant.

On that note, I have had two hard drive failures, a power supply failure, and there are small cracks at the very edge of the keyboard, just below the touch pad. I don’t know, I may be responsible for the hard drive failures, although I do take good care of my MacBook — it’s always in a neoprene sleeve, and I’ve never dropped it — but cracks and the power supply problems are very common. It’s probably an issue with the first generation of x86 MacBooks, notebooks that aren’t iBooks (stupidly rugged) or titanium PowerBooks (ruggedly stylish). As as summary, I’d definitely shell out the $249 for three years of AppleCare. All of the problems I’ve had have been taken care of either within a day or over night. It’s not good that MacBooks have these
problems, but I’m very happy with how they are being taken care of.

Share
Posted in Ramblings | Leave a comment

Print This Post Print This Post  

Longest Bugfix Ever

I’m going through the DrJava bug reports and close those that are no longer relevant. I found this gem:

[ 1123221 ] Debug mode blown away on System.exit(0)
Date Submitted:1906-01-18 11:08
Closed as of: 2008-01-18 01:28

It took us 102 years to close the bug. That’s quite possibly the longest bugfix ever.

Share
Posted in DrJava, Ramblings | Leave a comment

Print This Post Print This Post  

DrJava Recap of the Last Two Weeks

By now, we’re already two weeks into the new year. Only 50 weeks left… geez.

I have to admit that I wasn’t doing very much during the first few days of the year. It wasn’t that I was hung over from our wild CS grad student board game New Year’s party (which was very nice, thank you, Mary), I was just… sleepy. And I ate a lot. Green bell peppers went on sale, so I ate about four beef-stuffed bell peppers for the first few days of the year.

At some point I made a new stable release of DrJava, but apparently something went wrong and the files got corrupted. This was only on a few servers, though, because my test downloads all worked. Believe me, when I make a release, I’m very thorough. I fixed this a couple of days later by re-uploading the files. I was told I should have made a completely new release, to get different version numbers, but it wasn’t that the release was problematic, the copies on some of the servers were. So I ended up just posting a news release.

After a very interesting talk by Nat Ayewah of the University of Maryland, I also integrated FindBugs into DrJava’s build script. I filtered out a few warnings that we weren’t interested in, but in general the FindBugs results were useful. I already made several changes based on the results.

I also re-integrated Clover into DrJava’s build script and updated the Clover reports for the main part of DrJava and the PLT utilities. All of this is kind of in support of Corky’s COMP 312 class, a class that I’m neither enrolled in nor assigned to as a teaching assistant. But I just feel some (probably counterproductive) obligation to help.

I made several bug fixes: I made a temporary fix so that the “@” from a package annotation would not make DrJava throw an exception anymore. I addressed a problem with the Project Properties dialog when the Main Document did not exist. And I fixed an error introduced by refactoring that was so far inconsequential because the feature was never used.

Another fix didn’t make it into the new stable: When “Run” is pressed, the focus goes back to the Interactions Pane. I also began adding two new features, “Follow Files” and “Execute External Process”.

With the latter, I was having some problems, though, because the very useful class ProcessBuilder was only introduced in Java 5.0, and we’re still trying to maintain 1.4 compatibility. I had to replicate that capability. All done now, though.

Share
Posted in DrJava, Ramblings | Leave a comment

Print This Post Print This Post  

Happy New Year

I’d like to wish a happy new year to everyone who might be reading this, but since quite likely that’s just me, I want to extend those wishes to all my friends, in particular to those who were kind enough to invite me to spend the past few hours, the end of the old year, and the beginning of the new year together with them. I wish a happy new year to everyone I work with, and I wish as happy a year as possible to my mother. If there is anyone who deserves a happy year, it is her.

May the new year bring good to all of you.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

this() vs. super()

This is just going to be another rambling about an inconvenient situation that occurs often in Java. Nothing concrete, no plans of mine to do anything about it any time soon.

Constructors are quite special: They can initialize final fields. You may call another method, a special method only called in the constructor, yet in that method, final methods cannot be initialized anymore. Such a method would be tremendously useful to increase code reuse:

class A {
private final Object _something = null;
public A() {
/* do something */
}
public A(Object o) {
/* do something */
_something = o;
}
}

It would be nice to get the /* do something */ factored out into a method. In this case, of course, a this() call can help:

class A {
private final Object _something = null;
public A() {
/* do something */
}
public A(Object o) {
this();
_something = o;
}
}

The situation I ran into now is similar, except that I had a super class and needed to make a super() call as well:

class S {
protected final Object _something = null;
public S() { }
public S(Object o) {
_something = o;
}
}

class A extends S{
public A() {
/* do something */
}
public A(Object o) {
super();
this(); // error: this() must be first statement
}
}

If I still want to use this() to factor code out, I have to put the super() call second, that’s not allowed, and vice versa.

Besides removing some restrictions for methods called from the constructor, are there any good reasons why this() could not be called after the super() call?

Share
Posted in Ramblings | 1 Comment

Print This Post Print This Post  

Subtyping for Annotations Discussion

After talking to Michael Ernst about subtyping for annotations and learning of strong opposition against it from Sun and Google, I looked through the archives of the JSR 308 to see if there was a discussion about subtyping that I missed or that occurred before I started reading some time in May. Maybe I still missed it, but there was really only one post by Bill Pugh, entitled “Ideas for Java annotation extension (independent of JSR-30[58])”, that dealt with exactly what I am doing, but also indicating that it wasn’t directly relevant to JSR-308. I think it may be useful to compare Bill’s proposals to mine.

After talking with Josh, I’ve decided to live within one design
constraint of the existing framework: for any annotation location and
annotation class, there is either zero or one matching annotations.
This forbids some things like subtyping between annotations, and
multiple instances of the same annotation on an element.

In my current implementation of xajavac, I have relaxed this requirement, and there can be any number of repeated annotations on a location. With subtyping, however, I believe this becomes less of an issue, since a programmer can always write an annotation that groups certain annotations together, thus in a way allowing repeated instances.

* Proposal 1: An annotation is allowed to extend/implement any number of interfaces.

In xajavac, any annotation is allowed to extend any other annotation (excluding cycles and the usual Java rules). An annotation is really just like an interface: An interface can extend other interfaces; an annotation can extend other annotations. If an interface doesn’t extend anything, its implicit superclass is Object; if an annotation doesn’t extend anything, its implicit superclass is java.lang.annotation.Annotation, as with any annotation right now. Neither an interface nor an annotation cannot extend a class; an interface can extend an annotation, but an annotation cannot extend an interface in my implementation. Classes can implement both interfaces and annotations.

You might want to use this for marker interfaces, or define an interface that defines several elements/methods, and any annotation that implements that interface would be required to implement those methods.

Note that the interface would just be a normal interface that could be implemented by classes as well (although this wouldn’t be recommended practice). interfaces can’t define default values.

This would allow you to define a standard set of element names that were used by by set of specific annotations, and allow internal API’s that worked with any annotation from that set.

I never really thought about interfaces extending annotations, although that’s clearly allowed in my implementation. The interface then can’t use as an annotation anymore, though. I don’t see much of a use here, but on the other hand, I don’t see a reason to forbid this either.

* Proposal 2 (requires proposal 1):

An annotation can define an element that returns an interface that extends java.lang.annotation.Annotation. When applying such an annotation in the source code, the value used there must be some concrete annotation that extends that interface.

Right now, the only values allowed for annotation elements are: primitives, String, Class, enums, specific annotation classes, and arrays.

This proposal would allow you to define annotations that, when applied in source code, accepted as an element value any one of a number of specific annotations. By defining the element to return a value of type Annotation, you can define an element where an arbitrary Annotation can be provided.

I think this explanation is overly complicated. I don’t think it is necessary to achieve what annotations aim to do: annotating parts of a program with data available at compile time.

For example, consider example where the Baz annotation can be applied with either a Foo or a Baz annotation as an element:

public interface AnnotationWithId extends Annotation {
int id();
}
public @interface Foo extends AnnotationWithId {
int id(); // this could be omitted, since it is defined in the interface
String msg();
}
public @interface Bar extends AnnotationWithId {
int id() default 0; // couldn't be omitted, since the interface can't give a default value
String date();
}
public @interface Baz {
AnnotationWithId annotation(); // can supply a @Foo or @Bar here
String reason();
}
public Test {
@Baz(annotation=@Foo(id=17, msg="testing"), reason="because")
public int test() { return 17; }
}

In my implementation, I don’t allow annotations to extend Annotation, because that is an interface. This extension is implicit, however, as it is with any annotations currently. Other than that, everything in this example can be done with my example, as long as all the “interfaces” that are extended are annotations, and all the members are primitives, String, Class, enums, annotation classes — now including subclassing, of course — and arrays.

I considered allowing Annotation as one of the members in an annotation, in addition to String, Class, enums, annotations, and arrays, but I don’t think this is all that necessary. It would allow to have an array of any kind of annotation, but I’m not sure how useful that is. It is more likely that a programmer wants a certain kind of annotation, e.g. any kind of InvariantAnnotation, as in my invariant checker.

I suspect there may be issues I hadn’t considered, so I’d appreciate
your feedback on this.

My current thought is to not make this part of JSR-308, but directly
submit it to the JSE7 effort.

I’m starting to realize what bureaucracy is involved in making any changes to a programming language, even if it is Java, which is not standardized by an official international organization like ISO. So I guess I share Bill’s sentiment of including these changes some time in the future.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Still Working on Subtyped Annotation API

Just when I thought I had a complete working API for my annotations with subtyping, and after I had written a special version of my invariant checker that uses annotations with subtyping, I ran into some trouble with more complicated annotations that contain other annotations. For example:

@Not(@And({@Or({@ThreadWithName("foo"),
@ThreadWithName("bar")}),
@And({@EventThread,@SynchronizedThis})}))
public void testNotAndOrTwoAndTwo() {
System.out.println("testNotAndOrTwoAndTwo!");
}

Internally, the JVM instantiates these annotation classes using proxies, just like I do. These proxies are created at runtime and therefore, of course, do not have any associated class files. My API was still trying to find them and failing. I think I’ve got most of those issues fixed now, but the holidays have taken over, and I was also busy with DrJava for a few days.

I still need to write a few more tests. I’m already very happy with the way these invariant annotations look like. The annotation expressed above would probably have been several hundred lines of code before, just because there was no general way to perform Boolean AND and OR operations on any kind of invariant annotation. They pretty much had to be custom-written.

Now that I have been working a bit with proxies, I remembered the idea about the @DelegatesTo annotation that I had a while back. I think proxies would make the implementation of that really simple. I still have to generate the interface, and the type checker of the Java compiler is still a problem, as explained in the original posting, but proxies would probably make all bytecode rewriting unnecessary. I could do it all using proxies and reflection. Again, I think it’s worth investigating.

Share
Posted in Concurrent Unit Testing, Research, xajavac | Leave a comment

Print This Post Print This Post  

New Beta of DrJava

Yesterday, on my birthday, I released a new beta version of DrJava. If you have any time, please take a look at it.

After some discussion on December 19, which was a bit limited because only Dan chimed in, I decided to create a branch based on revision 4268, the last version before Dan integrated the new interpreter. Then I merged the last changes I made in revision 4286 into the branch, so the beta has all the bugfixes and features of our latest internal version, but not the new interpreter.

If I don’t hear of any major problems, I will make a new stable release based on the same branch during the first few days of the new year. In mid-January, we will then make a new beta release that also includes the interpreter.

I looked at the release notes for our new beta again, and I think it was very necessary to release a new version. It may not seem like we did much in the last half year, except for Dan’s work on the interpreter, looks can be deceiving. Since the last released stable (and even beta!), we’ve added the
following features:

Drag-and-drop for Java files. It’s really incredibly convenient. If you haven’t tried it yet, do! You’ll be amazed.

Connecting to a running DrJava instance to open files in an that instance. This may not be important for most of you, but it enables me (and perhaps others) to use DrJava as a highly-functional IDE to display code. The deadlock checker I wrote loads the file into DrJava and jumps to the right line at the click of a button. Why write a new display tool when we have DrJava?

‘Automatic import’ dialog to the Interactions Pane. We’re all lazy, and this makes being lazy so much more convenient ;-)

Just two days ago, I made it work with user-defined classes too. It works very well if “Scan Class Files” in Preferences/Display is enabled (by default disabled, because it takes some time on network drives), because then the actual class files that are generated are scanned. If that is disabled, then it uses the names of the Java files, which may not contain all publicly accessible classes. And outside of project mode, if the working directory is set incorrectly, then the package names may be wrong, but there’s not much I can do
about that.

I also do not allow static imports of static inner classes, because that would require me to check for “public static” visibility, and at least with our current reduced model, it’s not easy to do that quickly. I could add that feature by scanning class files internally (the ASM library we now include can certainly do that, and the library I wrote for Concutest can definitely do it as well, and of course I’m very familiar with it), but again, that takes time, especially on network drives.

I hope you agree that drag-and-drop and automatic import are very important convenience features. But we also performed a few bug fixes:

  • [ 1773173 ] Find All results with similarly-named files. If the files were named similarly, they were merged incorrectly in the “regions display panel”-type panes.
  • [ 1792359 ] when exiting, cancel button does not behave as expected. There was a mismatch among the return types, and users could lose their changes when DrJava quit unexpectedly.
  • [ 1831946 ] Error after compilation. This was another concurrency problem, and by changing the way listeners are removed, we hopefully addressed this.

Please try out the new version, and definitely let me know if you run into any problems.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

@Inherited for Invariant Annotations?

When I wrote the API code for xajavac, my Java compiler variant that allows subtyping for annotations, I discovered the @Inherited annotation for the first time. This annotation is used on another annotation and indicates that the other annotation should be inherited from superclasses to subclasses. Specifically, annotations with @Inherited also appear in the array of annotations returned by Class.getAnnotations() if they annotated any of the superclasses of the class in question; in contrast, the array returned by Class.getDeclaredAnnotations only returns the annotations that are actually annotation the class itself.

When I wrote the implementation of the invariant checker outlined in my Master’s thesis, I implemented and described an inheritance mechanism for these invariant annotations that didn’t rely on the @Inherited annotation. I introduced separates meta-annotation, @PredicateLink and @Combine, which I needed anyway and which also incorporated the meaning of @Inherited.

Now that I have discovered @Inherited, I’m wondering whether I could or even should use it. That would mean making non-inheritance the default behavior, and letting @Inherited imply the inheriting case. I don’t think that’s the behavior I want. A @NotInherited meta-annotation would be better.

Share
Posted in Concurrent Unit Testing, xajavac | Leave a comment

Print This Post Print This Post  

Small Things

In the last few days, I’ve worked on a few small things: I have created a compiler adapter for Ant that allows me to use my xajavac compiler — once you have annotations with subtyping it’s hard to let go of them again. On Monday, I made a bugfix for the remote control feature of DrJava, and today I tried to address another issue that came up in a bug report.

I’ve also started on a version of the invariant checker that uses annotations with subtyping, but that hasn’t progressed too far yet; I first had to solve the Ant problem.

Share
Posted in Concurrent Unit Testing, DrJava, xajavac | Leave a comment

Print This Post Print This Post  

Multiple Annotations of the Same Type

Since I already made one small modification today, I also looked at allowing multiple annotations of the same type on an annotated element. Again, it was a very simple change in the compiler.

Both the modified compiler and the extended annotation framework now allow you to repeat the same annotation multiple times. Unfortunately, if the original reflection API is used, Java throws a java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface TestMulti$MultiAnnotation: @TestMulti$MultiAnnotation(value=bar) exception (or similar), so make sure to use the new API in subannot.jar if you use this feature.

Since I couldn’t rely on Java’s reflection API anymore (because of the exception), I had to rework my framework a bit. The most complicated change involved the distinction between getAnnotations() and getDeclaredAnnotations(). I now have to inherit annotations to subclasses myself.

All that is done now, though. I still need to make a more thorough write-up and announce xajavac on several discussion boards. I don’t know when I’ll do that, though; I’ve had an incredibly productive day, but I’ve been working for 12 hours straight already. On the other hand, I’m rained in at the office and everyone else has left for Thanksgiving…

Share
Posted in xajavac | Leave a comment

Print This Post Print This Post  

Final Modifier for Annotations with Subtyping

The JSR 308 proposal mentioned that there might be trust issues for annotations that can be subclassed outside a trusted framework. I contend that this is not a severe problem since it occurs with normal classes already.

To still address this issue, I decided to allow the final modifier for annotations: An annotation that is final cannot be subclassed, just like a final class cannot be extended.

final @interface FinalAnnotation {
String value();
}

// ERROR: cannot inherit from final FinalAnnotation
@interface SubAnnotation extends FinalAnnotation {
int i();
}

Again, the change involved only half a dozen lines.

Share
Posted in xajavac | Leave a comment

Print This Post Print This Post  

Better Explanation of @OverrideOnly

I think I may not have done such a good job explaining @OverrideOnly and the problems with visitors with the template method pattern a few days ago.

Here’s where the situation comes up: Let’s say you have a binary tree, realized using the union and composite patterns. It can either be a leaf, have one child or two children.

interface IBinTree {
public R execute(IBinTreeVisitor visitor, P param);
}

interface IBinTree {
public R leafCase(Leaf host, P param);
public R oneCase(OneNode host, P param);
public R twoCase(TwoNode host, P param);
}

class Leaf implements IBinTree {
public R execute(IBinTreeVisitor visitor, P param) {
return visitor.leafCase(this, param);
}
}

class OneNode implements IBinTree {
public R execute(IBinTreeVisitor visitor, P param) {
return visitor.oneCase(this, param);
}
}

class TwoNode implements IBinTree {
public R execute(IBinTreeVisitor visitor, P param) {
return visitor.twoCase(this, param);
}
}

Let’s say we’re now checking a structure like this, and we know we expect a OneNode, and in all other cases it should throw an exception. This comes up very often, for example when working with Java class files: I know that the referenced item should be a class, but what if it’s not?

Since this is so common, we define an abstract class using the template method pattern:

abstract class ADefaultBinTreeVisitor implements IBinTreeVisitor {
public R leafCase(Leaf host, P param) { return defaultCase(host, param); }
public R oneCase(OneNode host, P param) { return defaultCase(host, param); }
public R twoCase(TwoNode host, P param) { return defaultCase(host, param); }
public abstract R defaultCase(IBinTree host, P param);
}

This class delegates all calls to a default method that has to be overridden. To do the checking for OneNode, we would write something like this:

myTree.execute(new ADefaultBinTreeVisitor() {
public Void defaultCase(IBinTree host, Void param) {
throw new RuntimeException("OneNode expected!");
}
public Void oneCase(OneNode host, Void param) {
// do whatever we have to do
return Void.TYPE;
}
}, Void.TYPE);

Let’s say we’re lazy and we copy and paste this class so that we check for TwoNode. It’s very easy to incorrectly change the signature of the oneCase method above:

myTree.execute(new ADefaultBinTreeVisitor() {
public Void defaultCase(IBinTree host, Void param) {
throw new RuntimeException("TwoNode expected!");
}
public Void twoCase(OneNode host, Void param) {
// do whatever we have to do
return Void.TYPE;
}
}, Void.TYPE);

In this anonymous inner class, we have not overridden the twoCase method as intended; the twoCase method still calls defaultCase and throws an exception. Instead, we have added a new method twoCase that takes a OneNode as first parameter. This method is useless and will never called, but the compiler does not complain.

If we told the Java compiler or some checking tool that classes extending ADefaultBinTreeVisitor have to override or implement one of the methods already defined, and that they may not introduce new methods like we accidentally did above, this problem could be avoided:

@OverrideOnly
abstract class ADefaultBinTreeVisitor implements IBinTreeVisitor {
public R leafCase(Leaf host, P param) { return defaultCase(host, param); }
public R oneCase(OneNode host, P param) { return defaultCase(host, param); }
public R twoCase(TwoNode host, P param) { return defaultCase(host, param); }
public abstract R defaultCase(IBinTree host, P param);
}

myTree.execute(new ADefaultBinTreeVisitor() {
public Void defaultCase(IBinTree host, Void param) {
throw new RuntimeException("TwoNode expected!");
}
// ERROR: this method does not occur in the superclass
public Void twoCase(OneNode host, Void param) {
// do whatever we have to do
return Void.TYPE;
}
}, Void.TYPE);

This is the one error that I run into the most often with visitors and the template method pattern, and this would be really easy to check for a compiler.

Share
Posted in Research | Leave a comment

Print This Post Print This Post  

Installing an Operating System is Incredibly Annoying

For the last four days, I’ve been working on re-installing the operating system and all the application programs on my second computer at home, the one I use as media and web server. I’ve finally decided to upgrade it from Windows 2000 to Windows XP, and despite my skepticism, so far it looks acceptable. Not too much of a candy interface.

The only reason why I upgraded from Windows 2000 to XP (both legacy OSes now) was the lack of Bluetooth support in Windows 2000: I attached the TV-out of my computer to my TV so I can watch movies from my couch, and I got a fancy Bluetooth mouse to control the PC, only to realize that Windows 2000 doesn’t really handle Bluetooth. It was something as trivial as that that made it necessary to upgrade. Not the Aqua interface or some feature that was supposed to be in Vista but got canned.

I hate installing software. The last time I did this, I made Ghost images so I could just reset my computer to a clean state. Unfortunately, those Ghost images have Windows 2000 on it. I guess I’ll have to fight my way through this for a few more days and then make new Ghost images. I should be safe then until Microsoft releases Windows 7 and I decide to upgrade to Vista ;)

Share
Posted in Ramblings | Leave a comment

Print This Post Print This Post  

Referenced in JSR 308 Proposal

I just noticed that the Related Work section of the JSR 308 proposal references my LAPT-javac modification for local variable annotations.

At last! I was a little bit disappointed by the original feedback I received for LAPT-javac.

Share
Posted in Ramblings, xajavac | Leave a comment

Print This Post Print This Post  

Added Formal Grammar Changes and API Description to xajavac Website

I finally finished modifying the Java grammar to faithfully represent my changes that enable subtyping for annotations. I also added a description of the extended API I had to develop to allow reflection for annotations with subtyping. I have also decided to remove the treatment for local variable annotations, originally implemented in LAPT-javac, from xajavac now that the JSR 308 proposal provides a different format.

All of this information, along with the binaries for the modified compiler and the API, is available on the xajavac website.

Now I should write a more formal tech report about this, I should contact Michael Ernst of the JSR 308: Annotations on Types project, and I should modify the code I wrote to for my MS thesis to take advantage of annotations with subtyping.

Share
Posted in xajavac | Leave a comment

Print This Post Print This Post  

Automatic Import in DrJava’s Interactions Pane

Today we had our weekly lab meeting again, and one of the topics was COMP 312, the class that develops DrJava. We decided we needed to start setting goals for the semester. I will probably work on a general tools interface that will allow my tools to interact with DrJava.

After that discussion, I was in the mood for doing a little DrJava work, and I decided to take a look at a feature that had come to my mind a while ago: One of the common problems in the Interactions Pane is a forgotten import statement. There have been several feature requests asking for this to be automated, and I thought my trusted old predictive input dialog was the right tool for this.

Whenever the “Error: Undefined class ‘Foo'” error appears after an interaction, DrJava now opens a dialog with all the standard Java API classes and lets the user select a class to import. If the user chooses one, then the import will be performed and the erroneous line re-executed. If it works, great. If there is another “undefined class” error, the dialog will appear again. The user can also press cancel to abort automatic import.

It’s not perfect, and not perfectly automatic, but it’s much better than what was there. That’s my mantra for DrJava. The predictive input dialog must be the paramount example of Extreme Programming: Written for a “Go To File” function, I’ve also used it for simple auto-completion, to display Javadoc pages, and now to import classes. About 1,500 lines of well-designed code that keep paying off…

Share
Posted in DrJava | Leave a comment

Print This Post Print This Post  

JSR 308 Proposal Available

The proposal for JSR 308, “Annotations on Java Types”, is available now. I’ve read it diagonally once, and it looks pretty nice. They’re finally adding class and runtime retention for local variables, something my LAPT-javac already did in October 2006. xajavac also incorporates my own non-standard representation for local variable annotations. Now that a standard representation is emerging, I’ll either have to change my implementation to make it adhere to the JSR 308 proposal, or I’ll have to drop it. That’s not a surprise, though; when I wrote LAPT-javac, I fully expected that it would become obsolete soon.

Subtyping for annotations is also mentioned, but to my delight only under “Out-of-scope issues”, a.k.a. suggestions. So at least in the near future, xajavac seems to be the only project to incorporate annotations with subtyping into Java.

Share
Posted in xajavac | Leave a comment

Print This Post Print This Post  

Work Website Redesign and Miscellaneous To Do

I just finished redesigning my work website. It’s now in the same style as the DrJava and the Concutest websites. I liked the other design, but for lengthy text documents, the new design is just more practical.

While all tests of annotations with subtyping that I have tried so far have succeeded, I have realized that I need to test all my programs, not only the new subannot software, with primitive types. It’s embarrassing, but until a couple of days ago, I didn’t know that int.class existed. I think now I have to put a switch statement in front of every line that uses a type name so I can filter out 'I's and 'J's, etc. and replace them properly with int.class and long.class.

And I need to start writing that tech report about annotations with subtyping.

Share
Posted in Ramblings, Research, xajavac | Leave a comment

Print This Post Print This Post  

Subtyping for Array Annotations Now Working

I’m creating more and more tests for annotations with subtyping, and while most of it seems to work, I ran into one very important problem: Right now, my arrays do not support polymorphism yet. Consider the following:

@interface TopLevel { }
@interface Leaf extends TopLevel {
String value();
}
@interface Interior extends TopLevel {
TopLevel[] value();
}

@Interior({@Leaf("foo"),
@Interior({@Leaf("bar"),@Leaf("fee")}),
@Leaf("fum")})
class Something { ... }

I definitely want polymorphic arrays. In the example above, the @Interior declares an array of @TopLevel interfaces, but since @Interior and @Leaf are both subclasses of @TopLevel, I should be able to store them in the array as well.

The type checker and compilers don’t have a problem with this, and everything gets encoded correctly in the class file, but my runtime library has a bug: It creates an array of type TopLevel, which is correct, but then also imposes the type TopLevel for all its members! That means all members get “sliced” down to type TopLevel, so they don’t have any of their additional members present.

I have to use the type from the array declaration and use it to create the array. Then I have to use the type of each annotation for the annotation instance. Unfortunately, this information isn’t conveniently present. But I’ll work it out.

Update

I just fixed the problem with subtyping in arrays as described above.

Share
Posted in xajavac | Leave a comment

Print This Post Print This Post