Thursday, November 17, 2005

Capturing Screenshots in GNOME on Solaris

Ever tried capturing a screen shot of a menu in an UI application on GNOME? Notice how the menu gets de-selected (or loses focus & disappears) as soon as you hit the print-screen button. The way to get around this is to use the gnome-panel-screenshot command at the console with the --delay= option. This switch makes the screen capture occur automatically after the specified delay, by which time you can "prepare" your application UI for the screen shot.

Technorati tags: , ,

Monday, November 14, 2005

22 Dell Boxes = 2 Galaxies

That's right. A former dell shop just replaced 22 of it's servers with 2 four core galaxy boxes.

Technorati tags: Sun, Galaxy,Dell

Created a new technorati profile

This is my profile. Go fetch!

Monday, November 07, 2005

"Titanic" Itanium

Itanium's "titanic" characteristic - of going down in cold waters - is becoming more obvious by the day.
Sun responds .

Technorati tags: Sun, Itanium,HP

Thursday, November 03, 2005

netbeans 5.0:What's cooking?

Charles ditzel writes about some cool new additions to netbeans 5.0

Friday, October 28, 2005

Fleeing temptation..

"Those who flee temptation generally leave a forwarding address."
- Lane Olinghouse

Brilliant quote, isn't it? :-)

Thursday, October 27, 2005

Meeting Geoff Arnold

This is why i just love working at Sun. If you swear by distributed computing, could you ask for anything more than a meeting with one of the Jini Engineers? That's right, I got to meet Geoff Arnold. I mustered enough courage to ask him about decentralized discovery in Jini and querying/aggregating partial results in a distributed computing system (like project neuromancer). He was in Bangalore to talk the JBI folks, and set aside some time for a talk on "the future of distributed computing". Need i say that it was nothing short of enlightening and inspiring? And does someone have to tell me that I'm working at exactly the right place? :-)

Correction: I had previously (erroneously) stated that Geoff Arnold was one of the *original* Jini team members. (See the comments.)
Sorry about the gaffe, Geoff. :-)

Update: Geoff Arnold has since moved to Amazon

Monday, October 24, 2005

Cool quotes

Found these on my (custom) google home page -

The only thing that sustains one through life is the consciousness of the immense inferiority of everybody else, and this is a feeling that I have always cultivated.
- Oscar Wilde
My definition of a free society is a society where it is safe to be unpopular.
- Adlai E. Stevenson Jr.
Preserving health by too severe a rule is a worrisome malady.
- Francois de La Rochefoucauld
The best car safety device is a rear-view mirror with a cop in it.
- Dudley Moore

Friday, October 21, 2005

Town hall with John Fowler

Just came back from a town meeting with John Fowler at the cafeteria. Man, does he speak fast. He probably provides a stiff competition to Bryan Cantrill in speed of speech. And he really is earning is salary - every cent of it. The fact that he's an Engineer-turned-manager showed up on several occasions when he answered technical questions in the Q&A with great ease (including a rebuttal to HP's claims on cache pollution in the Niagara). He must've been a good engineer. But is he a good orator ! He had the audience in a trance during the whole session, treating us to delightful technical tidbits, interesting stats, marketing theories and an amusing old story on how he first me Andy Bechtolsheim.
Sun is in good hands - you can be sure of that.

Thursday, September 22, 2005

The Sun cares for Planet Earth

Some environment friendly initiatives by Sun highlighted here

Friday, September 02, 2005

Java trivia

Brilliant piece of Java trivia
I could figure out the answer (wink wink). Could you?

Tuesday, August 30, 2005

Feel the power (outage) of Dell

Good analysis of power consumption by Dell machines.

Tuesday, August 23, 2005

A verse very relevant to me

Found the complete text of Robert Frost's "Stopping by Woods on a Snowy Evening" here:

Whose woods these are I think I know.
His house is in the village though;
He will not see me stopping here
To watch his woods fill up with snow.

My little horse must think it queer
To stop without a farmhouse near
Between the woods and frozen lake
The darkest evening of the year.

He gives his harness bells a shake
To ask if there is some mistake.
The only other sound's the sweep
Of easy wind and downy flake.

The woods are lovely, dark and deep.
But I have promises to keep,
And miles to go before I sleep,
And miles to go before I sleep.

Monday, August 22, 2005

Linux trademarked

I hope this isn't a rumour.
Cry, my dear zealots on slashdot :-)

Tuesday, August 16, 2005

If you can't join them

"If you can't join them, beat them." - They didn't want me to join them. Granted. I'll now beat them whenever we face-off. That's a promise. I'll make them regret this. Promises to be fun.

Thursday, July 21, 2005

Good Quote

Found this excellent quote on the google home page:

"Getting ahead in a difficult profession requires avid faith in yourself. That is why some people with mediocre talent, but with great inner drive, go much further than people with vastly superior talent."
- Sophia Loren

Friday, July 15, 2005

Application Versioning

Tom ball explains how class loading can be used to achieve simple application versioning -

Versioning, which I'm defining for this entry as how a Java application manages its external library dependencies, has been a tough issue ever since Java first released. Back when Java was born, the vision was that each machine would have a single Java runtime and standard libraries which would always be fully backwards-compatible. The reality has been that for most apps, the only reasonable alternative to testing a full matrix of released JREs and libraries is to instead package everything the app needs, install the whole hairball on each customer's system and use a custom classpath to access it. The problem with a custom classpath is that it is easy for your customers to break in subtle (and not so subtle) ways, which makes them cranky and can drive your tech support engineers crazy. Some work has been done in the JDK via its Package Versioning Specification and API, but there are still times when your app really needs to keep specific libraries under tight control.

NetBeans has this problem with its javac bridge, which allows its editor and refactoring modules access to javac's error checking and parsing support. The problem is that javac doesn't have a public API, so while a tool can leverage a specific version of javac, it cannot rely on whatever is on the customer's machine since its internal API may be radically different. We have a recent version of javac that works with our bridge, but just adding it to the NetBeans classpath won't work for two reasons:
  • NetBeans supports many different JDKs, each of which have their own version of javac; and
  • The Mac OS X includes the javac classes in its bootclasspath (and supportable products shouldn't whack the bootclasspath if possible).
The solution proved fairly trivial to implement while being quite robust: define a ClassLoader to isolate the bridge's use of javac classes from the rest of the IDE. Here is the ClassLoader implementation we use; NetBeans has several similar loaders for specific modules, but Tomas Hurka wrote this Factory class for the javac bridge:

    private static class GJASTClassLoader extends URLClassLoader {
private final PermissionCollection permissions = new Permissions();

public GJASTClassLoader(URL gjastJar) {
super(new URL[] {gjastJar}, Factory.class.getClassLoader());
permissions.add(new AllPermission());
}

protected Class loadClass(String n, boolean r) throws ClassNotFoundException {
if (n.startsWith("com.sun.tools.javac") || n.startsWith("org.netbeans.lib.gjast")) {
// Do not proxy to parent!
Class c = findLoadedClass(n);
if (c != null) return c;
c = findClass(n);
if (r) resolveClass(c);
return c;
} else {
return super.loadClass(n, r);
}
}

protected PermissionCollection getPermissions(CodeSource codesource) {
return permissions;
}
}
As you can see, we rely on URLClassLoader to do all the heavy lifting. Our version isolation support is in loadClass(), where a test is made of the requested class name to see if it is in one of the packages to be isolated (here, we test whether the class is a javac or bridge class). If it is an isolated class, URLClassLoader.findLoadedClass() and findClass() look it up in the jar file we supplied in the constructor; otherwise we let URLClassLoader.loadClass() delegate to the parent classloader.

Now, we need to interact with classes loaded by this classloader. What works best for us is to define a simple interface which the versioned classes and their client code shares, and a factory class that uses reflection to load the class which implements that interface (in 1.0, you needed a default constructor and used Class.newInstance()). Here's a simplified example (from the same Factory class):

public interface ErrorChecker {
int parse() throws CompilerException;
}

public final class Factory {
private static Factory instance = null;
private static Constructor newErrorChecker;

public static synchronized Factory getDefault() {
if (instance == null) {
instance = new Factory();
Class[] newCheckerTypes = new Class[] {
ECRequestDesc.class
};

File gjastJar = InstalledFileLocator.getDefault().locate("modules/ext/gjast.jar", "org.netbeans.modules.javacore", false);
try {
ClassLoader loader = new GJASTClassLoader(gjastJar.toURI().toURL());
Class c = Class.forName("org.netbeans.lib.gjast.ASErrorChecker", true, loader);
newErrorChecker = c.getConstructor(newCheckerTypes);
} catch (Exception e) {
}
}
return instance;
}

public ErrorChecker getErrorChecker(ECRequestDesc desc) {
try {
return (ErrorChecker) newErrorChecker.newInstance(new Object[] { desc });
} catch (Exception e) {
Throwable t = e.getCause();
throw new RuntimeException("Cannot create errorChecker: " +
t != null ? t : e);
}
}
}
In the above, we fetch the ASTErrorChecker constructor via reflection, then use it whenever the client requests a new ErrorChecker implementation. Because the interface doesn't directly or indirectly reference any class types in our private javac copy (CompilerException is also shared), objects created using its classes can interact with the client without conflict.

There is one thing to watch for (there always is), however: sometimes you can find yourself pondering the impossible, like I did yesterday:

debugshot.png

What caught me off-guard is that the debugger shows the type of "ex" is EmptyScriptException, but if it were that type then it should have been caught by previous catch block. Worse, a "(ex instanceof EmptyScriptException)" watchpoint returns "false", when it "obviously" should be true. The issue is that a class isn't just defined by its bytecode (the classfile's contents), but by the combination of bytecode and classloader. Here, there were two copies of EmptyScriptException loaded: once by Jackpot's private classloader, and once by the NetBeans one. Instances of one class copy will fail instanceof and catch tests with the other. I frequently forget this subtlety until reminded by a few head bangs against my monitor. The fix is to add the class to your list of classes which your classloader ignores and therefore shares with its parent classloader.

Over time, I have learned the value of this behavior (the classes not mixing, not the head banging). Since I'm pretty lazy, the extra work required to share classes between classloaders means that my designs do as little class sharing as possible. It is easier to maintain a really strict isolation with only a few, simple interfaces, than it is to maintain a big list of shared classes and deal with the headaches of managing their dependencies. A nice bonus is that this sort of isolation lends itself to distributed and parallel designs, where the more lightly coupled remote objects are to each other, the better they work together. Besides, it's hard to convince your manager you need the latest fire-breathing multi-processor workstation if your design is hopelessly interlocked.

This blog entry is way too long. I hope however that it dispells the idea that writing a classloader is rocket-science or limited to a few obscure uses. Managing application versioning is a problem many application teams face, and some judicious classloading can make it much easier.

Remember, no rocket science, this. :-)

Tuesday, July 12, 2005

Eclipse craves for matisse

Eclipse users are desperate for an answer to netBeans' "Matisse" gui builder. But there's no solace and no respite in sight.
I want to hear the eclipse zealots respond to this one.
Here's the bug report that begs for it. (Sadistic pleasure, this.)
The old order changeth. :-)

Friday, July 08, 2005

Task queues in Solaris

Good blog on deferred processing of kernel level tasks in Solaris.