Friday, May 26, 2006

Java Tip #10 - Constructor Exceptions are Evil

I saw this in the Secure Coding Antipatterns session at JavaOne 2006. It might scare the hell out of you.

Suppose I have the following class Foo and the constructor of Foo throws an exception. This might be due to some kind of security constraint or an invalid state. Suppose we don't anyone unauthorized to call the doEvil() method.

public class Foo {
public Foo() {
System.out.println("constructing foo: " + this);
throw new RuntimeException();
}
public void doEvil() {
System.out.println("Evil!Evil!Evil");
}
}

In the following code, is there anyway for me to get access to Foo if the constructor throws an exception?

try {
Foo x = new Foo(); // <-- exception thrown here }
catch Exception(e)
{ ... }


I didn't see it at 1st, but there at least one way to do it. If Foo isn't final, I can subclass Foo and get access to the instance.

public class MyFoo extends Foo {
public static Foo x;
@Override
protected void finalize() throws Throwable {
x = this;
}
}

Now I construct a MyFoo instance, call System.gc() and runFinalization().

try {
Foo x = new MyFoo();
} catch(Exception e) {
System.out.println(""+e);
}
System.gc();
System.runFinalization();
System.out.println("MyFoo instance: " + MyFoo.x);
MyFoo.x.doEvil();

I get the following output.

constructing foo: MyFoo@923e30
java.lang.RuntimeException
MyFoo instance: MyFoo@923e30
Evil!Evil!Evil

The moral of this story is to use the final keyword if you want to prevent incomplete instances from being accessible. The presenters of the session also suggested using a "initialized" field that is set as the last line of the constructor. A critical method could validate this field before doing work. I think final is a better solution.

Enjoy.

BBB

Friday, May 12, 2006

Contributing Tapestry POC to Eclipse RSP-UI

I spent some time developing a proof of concept for Tapestry and RSP-UI for others to review. I've forwarded the POC directly to Wolfgang Gehner at Infonoia for possible integration into the sample application.

Information on RSP-UI can be found here.
http://www.eclipse.org/proposals/rsp/

The POC can be downloaded from here.
http://www.babbleknot.com/stuff/tapestry-rsp-workspaces.zip

The zip file contains two workspaces that can be saved to your c:\rsp\workspace folder & imported into eclipse. The org.apache.tapestry plug-in contains the latest tapestry jars & dependencies. The org.rsp.sample.usage.tapestry plug-in implements the Tapestry "DirectLink" quick start application. You'll have to add a "link" file to the rsp web app that references the plug-ins. If you don't understand what I just wrote, review the article at Infonoia to get the RSP-UI development environment setup.

A few points:
- The tapestry servlet path in app.application is set to account for the "platform" node.
<meta key="org.apache.tapestry.servlet-path" value="/platform/app"/>
- A servlet that extends org.apache.tapestry.ApplicationServlet is used but only overrides one method. This helps hivemind & tapestry find everything.
@Override
protected ClassResolver createClassResolver() {
return new DefaultClassResolver(this.getClass().getClassLoader());
}

- We are interested in using RSP-UI in our application framework if it makes it as a full eclipse project.

I will try to answer questions on the POC, but I am not really a tapestry expert. Enjoy.

BBB