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

Hi,

 

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

Dennis

 

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("com.webobjects.foundation.NSTimestamp");

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

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

                classToPatch.toClass();

           } catch (Exception e) {

                // TODO: error handling, probably logging and exit

           }

     }

}

 

 

 

-- 

signature_2094861619
-----------------------------------------------------
Dennis Bliefernicht • Head of Backend Development

T +49 40 357 3001 62

dennis.bliefernicht@xyrality.com

 

XYRALITY GmbH • Friedensallee 290 • 22763 Hamburg

www.xyrality.com

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

-----------------------------------------------------

 

 

Image
image001.png
Subscribe (FEED) Subscribe (DIGEST) Subscribe (INDEX) Unsubscribe Mail to Listmaster