Blogbody Rotating Header Image

February, 2006:

IDEA 6.0 Looks Amazing

IntelliJ IDEA 6.0 (Demetra): The EAP has begun!:

When we announced that the EAP for Demetra, the next version of IntelliJ IDEA, would start as soon as the version 5.1 is released, I don’t think people thought ‘as soon as’ meant ‘a’few hours after’. But it did, and the first EAP build of Demetra is now available, along with a list of new features.

(Via Dmitry Jemerov’s Weblog.)

I saw the feature list a while back, but now that the EAP is coming and we are actually going to see those features get created over the next 6-12 months, I can only say that I am extremely excited. Provided they support Ant and Maven enough, the idea of paring a build server with an IDE is extremely appealing.

Now just to make sure they provide a good API for the build server, so that Autoriginate can do some cool things… :)

Of classloader magic…

Anyone know how to do this? I believe it is possible, but others say it isn’t.

Foo foo = new Foo();
Object bar = BeanUtils.create("Bar");
BeanUtils.setProperty(bar, "foo", foo); // call bar.setFoo(foo)
// ... at this point, Bar.java changes and
// ... is recompiled (Commons JCI can do this)
bar = BeanUtils.create("Bar");
BeanUtils.setProperty(bar, "foo", foo); // breaks!!!

This last line is where everything starts to break down. Using commons JCI, I can get up to this line, but when Bar is reloaded, it thinks that Foo is a new class loaded by a different classloader. Setting the old Foo instance on it causes bad things to happen (ClassCastException, etc).

Couldn’t this be done if each class had it’s own ClassLoader? Is this just not possible in Java? A couple things to note:

  • I specifically loaded Foo before Bar, so Foo does not get loaded as a dependency of Bar
  • This code never references the Bar class directly (note the BeanUtils usage)

Update: I decided to put together a real Java program to show the issue.

public static void main(String[] args) throws Exception {
/*
Foo.java:
public class Foo {
static {
System.out.println("Foo initializing...");
}
}

Bar.java:
public class Bar {
static {
System.out.println("Bar initializing...");
}

private Foo foo;

public void setFoo(Foo foo) {
this.foo = foo;
}
}
*/
ClassLoader parent = Test.class.getClassLoader();
File base = new File("jci-test");
CompilingClassLoader ccl = new CompilingClassLoader(parent, base);
ccl.start();

Class fooClass = ccl.loadClass("Foo");
Object foo = fooClass.newInstance();
Class barClass = ccl.loadClass("Bar");
ClassLoader firstBarCL = barClass.getClassLoader();
ClassLoader fooCL = fooClass.getClassLoader();
System.out.println("firstBarCL == fooCL: " + (firstBarCL == fooCL));
Object bar = barClass.newInstance();
Method setter = barClass.getMethod("setFoo", new Class[]{foo.getClass()});
setter.invoke(bar, new Object[]{foo});

System.out.println("*************");
System.out.println("Updating Bar.java...");
new File(base, "Bar.java").setLastModified(System.currentTimeMillis());
Thread.sleep(1000 * 5);
System.out.println("*************");

barClass = ccl.loadClass("Bar");
ClassLoader secondBarCL = barClass.getClassLoader();
System.out.println("firstBarCL == secondBarCL: " + (firstBarCL == secondBarCL));
bar = barClass.newInstance();
setter = barClass.getMethod("setFoo", new Class[]{foo.getClass()});
setter.invoke(bar, new Object[]{foo});

/*
Output:

Foo initializing...
firstBarCL == fooCL: true
Bar initializing...
*************
Updating Bar.java...
*************
firstBarCL == secondBarCL: false
Bar initializing...
Exception in thread "main" java.lang.NoSuchMethodException: Bar.setFoo(Foo)
at java.lang.Class.getMethod(Class.java:1581)
at com.opensymphony.webwork.util.classloader.Test.main(Test.java:54)

*/
}

Selenium IDE 0.7 Released

Selenium IDE released a new version today. This Firefox plugin is the best way to get started with web application testing. It is 100% functional by itself, or it can be used in combination with Selenium and any of the language (Java, Ruby, etc) drivers, provided you are willing to write the output template.

If you’re running Firefox 1.5, try it out. You can also see a flash movie of it in action.

selenium-ide.gif

IDEA Live Templates: more powerful than you think

I am always amazed by how much you can do with the IDEA live templates feature. For those that don’t make their own live templates and share them with your team, you should.

Today I created a nice live template (bound to xa) that lets me easily define new WebWork actions when in xwork.xml:

idea-live-template.gif

The variables are defined as:

  • CLASS: descendantClassesEnum(“com.opensymphony.xwork.Action”, “true”)
  • EXT: enum(“jsp”, “ftl”, “vm”), with the default being jsp

Now I can define a new action by typing xa and I am presented with a list of all WebWork actions in my project. You can download the live template to try out yourself here: webwork.xml

Cygwin/X and VNC: clipboard conflicts on OS X and Win XP

Today I just discovered why I was sometimes having weird clipboard problems when using VNC and Cyngwin/X on my Windows XP machine. See, I VNC in to my OS X machine (it’s an iBook I like to stow away when I’m on my desktop) and also run Cygwin’s X Windows server (I hate the cmd.exe shell, so I use xterm). It seems than when both are running, the clipboard synchronization logic in VNC and Cygwin/X seem to trip each other up after some time (not sure how or why). So for a while copy and paste works, but eventually it stops.

The fix: restart VNC, Cygwin, or both.