Mailing List Message #227
From: Dennis Bliefernicht <>
Subject: Re: [WO-DEV] change toString for some classes?
Date: Wed, 30 Jun 2021 11:56:32 +0200
To: WebObjects & WOnder Development <>



is there some Wonder (or NS- or Java-level) trick to “override” (for the original class; in ObjC I would simply swizzle the method) toString for some classes? Namely, in my current application, I would need that


there are some ways in Java to do this kind of thing, Javassist is something we still use in an older codebase, there is also ByteBuddy which tries to wrap everything in a  neat API. One important thing is that you need to do this _very_ early in your application, before the relevant classes are loaded (because this hooks into the class loading mechanism, once the class is loaded, you can’t modify it that easily anymore). In fact we do this basically first thing in the main method. I don’t have any snippets at hand for ByteBuddy, but below is an outline, how we replaced some methods with Javassist. Basically we prepend the method with “return ApplicationUtility.myReplacementMethod(this)” which makes it easy enough to just code up the replacement method as usual.


Performancewise this seems to be fine, in our case we had to replace a .hashCode() deep in WO, because performance monitoring revealed that our data modelling resulted in wildly bad behaviour of EO objects in HashMaps and after the fix we got good improvements. So I assume generally the JIT compiler will smooth out any extra redirections.


Hope that helps && Greetings



import javassist.ClassPool;

import javassist.CtClass;

import javassist.CtConstructor;

import javassist.CtMethod;

import javassist.LoaderClassPath;


public class ApplicationUtility {

     public static int myReplacementMethod(final NSTimestamp object) {

           // do your magic

           return "TODO";



     public static void patchClasses() {

           try {

                final ClassPool classPool = ClassPool.getDefault();

                classPool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));


                final CtClass classToPatch = classPool.get("");

                final CtMethod toStringMethod = classToPatch.getDeclaredMethod("toString");

                toStringMethod.insertBefore("{ return " + ApplicationUtility.class.getName() + ".myReplacementMethod(this); }");


           } catch (Exception e) {

                // TODO: error handling, probably logging and exit








Dennis Bliefernicht • Head of Backend Development

T +49 40 357 3001 62


XYRALITY GmbH • Friedensallee 290 • 22763 Hamburg

Registergericht: Hamburg HRB 115332
Geschäftsführer: Sven Ossenbrüggen




Subscribe (FEED) Subscribe (DIGEST) Subscribe (INDEX) Unsubscribe Mail to Listmaster