Getting rid of the dreaded o.e.c.i.r.AssertionFailedException

It you have ever written even the smallest standalone app using SWT and Jface library, then you must know (and hate!) org.eclipse.core.internal.runtime.AssertionFailedException. This exception has the very bad habit of substituting the initial one without keeping any trace of it. The official explanation is the following :

“Jface is not guaranteed to work in standalone mode. As a matter of fact, Jface tries to report different errors using the Eclipse plugin mechanism, thus provoking a fatal assertion failure which is the only exception being reported.”

Ryan Lowe suggests wrapping [the code] in a try/catch block temporarily. Yeah sure this might just work if you know WHAT to wrap. What do you do when, after multiple commits and updates of the same source file modified by different people, you have the failed assertion ? Wrap in a try/catch every slice of code committed in the last few hours ? Hmmm … don’t think so.

An interesting solution would be (as proposed by Ryan) to use aspects in order to wrap automatically each and every SWT call. But this might bring serious performance issues and I also have some doubts that it will catch everything.

But boy, aren’t we lucky that Eclipse is opensourced ? Just by looking at the stack trace (which is the same over and over no matter where your real error is) you can spot the guilty : org.eclipse.core.internal.runtime.InternalPlatform (found in runtime.jar/runtimesrc.zip). The little bugger is Mr. private static boolean initialized. Putting it on true involves starting the platform, which is a quite complex process judging by the loaderStartup(URL[] pluginPath, String locationString, Properties bootOptions, String[] args, Runnable handler) throws CoreException method. Unfortunately, being a private variable means that reflection won’t work and dynamic proxying won’t work, either*. AKA Out Of Ideas (TM)

So, it’s time to stop trying to be smart. I’ll just be a rude dumb programmer and simply modify the source, recompile and replace the .class files in the runtime.jar. It’s extremely simple yet sharply efficient:

- initialize “initialized” on true - in the method private static void handleException(ISafeRunnable code, Throwable e) replace all the content with the following line : e.printStackTrace();code.handleException(e);. A stack in the console is enough for me at this stage, but of course you may use your favorite logging infrastructure classes to report the exception. The code.handleException call has (at least in my app) the effect of displaying an innocuous dialog box telling the user that something went wrong. Just the right dose of details aka nothing at all (don’t scare the poor user, please).

Well, what’s more to say ? This stupid trick simply works.

On second thought, I might use RCP. Maybe, in a future episode.

*AFAIK Please correct me if I’m mistaking here.

PS That was quick “Setting the accessible flag in a reflected object of java.lang.reflect.AccessibleObject class allows reading/modifying a private variable that normally wouldn’t have permission to. However, the access check can only be supressed if approved by installed SecurityManager.”. Humm, ok, so there IS a smarter solution after all. Left as an exercise for the reader :)

Comments

Tags