A logo showing the text blog.marcnuri.com
Español
Home»Java»BeansBinding Performance (Issue 37)

Recent Posts

  • Fabric8 Kubernetes Client 7.2 is now available!
  • Connecting to an MCP Server from JavaScript using AI SDK
  • Connecting to an MCP Server from JavaScript using LangChain.js
  • The Future of Developer Tools: Adapting to Machine-Based Developers
  • Connecting to a Model Context Protocol (MCP) Server from Java using LangChain4j

Categories

  • Artificial Intelligence
  • Front-end
  • Go
  • Industry and business
  • Java
  • JavaScript
  • Legacy
  • Operations
  • Personal
  • Pet projects
  • Tools

Archives

  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • August 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • February 2020
  • January 2020
  • December 2019
  • October 2019
  • September 2019
  • July 2019
  • March 2019
  • November 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • December 2017
  • July 2017
  • January 2017
  • December 2015
  • November 2015
  • December 2014
  • March 2014
  • February 2011
  • November 2008
  • June 2008
  • May 2008
  • April 2008
  • January 2008
  • November 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007

BeansBinding Performance (Issue 37)

2008-11-18 in Java / Legacy tagged Beans Binding / Bytecode / Injection / Java / Performance by Marc Nuri | Last updated: 2025-01-10

Since the release of NetBeans 6.0, the BeansBinding (JSR 295) framework has gained popularity. Personally, I've adopted it in all my projects due to its ease of use and productivity benefits. However, it's not without issues. The project has been stagnant for over a year, and recent news about Swing's future (here's an example) has only added to the uncertainty.

Despite this, the inclusion of BeansBinding in NetBeans and its foundational role in JavaFx suggests it isn't going away anytime soon. Yet, one issue with BeansBinding can be particularly frustrating: performance bottlenecks.

The Problem: Slow Form Loading

Getting into the subject, BeansBinding has not been updated for a while now and has some bugs that are really annoying.

When binding a form with 20+ fields using BeansBinding (via NetBeans + Matisse), you might notice sluggish load times. Profiling reveals that the culprit lies in the bindingGroup.bind() call during initComponents(). A deeper dive into the BeanProperty and ElProperty classes uncovers the root cause: the getBeanInfo(Object object) method, which invokes Introspector.getBeanInfo(object.getClass(), Introspector.IGNORE_ALL_BEANINFO), a time-consuming operation.

Investigating the Issue

A brief search led me to a mail thread discussing this very issue. The thread references Issue 37 and suggests using Introspector.getBeanInfo(Class class) directly, which leverages cached metadata and significantly boosts performance.

The Solution: Runtime Bytecode Injection with Javassist

Your initial approach could be to get the source code and replace the code fragment you need and then recompile the library. There is a great tutorial (Hacking Java Libraries) that teaches you how to do this if you don't know how to do it by yourself. The article is an excerpt of "Covert Java" by Alex Kalinovsky (Sams Publishing, May 2004) (recommended reading).

Rather than modifying and recompiling the library, an approach that's cumbersome and hard to maintain, I opted for runtime bytecode manipulation using the Javassist library. Javassist provides a lightweight and flexible way to modify classes on the fly.

Here’s the code to patch the getBeanInfo method in ElProperty and BeanProperty:

try {
  ClassPool cp = ClassPool.getDefault();
  CtClass cc = cp.get("org.jdesktop.beansbinding.ELProperty");
  CtMethod m = cc.getDeclaredMethod("getBeanInfo");
  m.setBody("{" +
    //"assert $1 != null;"
    "try {" +
      "return java.beans.Introspector.getBeanInfo($1.getClass());" +
    "} catch (java.beans.IntrospectionException ie) {" +
      "throw new org.jdesktop.beansbinding.PropertyResolutionException(\\"Exception while introspecting \\" + $1.getClass().getName(), ie);" +
    "} }");
  Class c = cc.toClass();
  cc = cp.get("org.jdesktop.beansbinding.BeanProperty");
  m = cc.getDeclaredMethod("getBeanInfo");
  m.setBody("{" +
    //"assert $1 != null;" +
    "try {" +
      "return java.beans.Introspector.getBeanInfo($1.getClass());" +
    "} catch (java.beans.IntrospectionException ie) {" +
      "throw new org.jdesktop.beansbinding.PropertyResolutionException(\\"Exception while introspecting \\" + $1.getClass().getName(), ie);" +
    "} }");
  c = cc.toClass();
} catch (NotFoundException ex) {
  // log exception
} catch (CannotCompileException ex) {
  // log exception
}

This replacement modifies the getBeanInfo method to use the cached Introspector.getBeanInfo(Class class) by default, significantly improving performance.

Important Notes

  1. Ensure this code runs before any BeansBinding classes are loaded, or it won't have any effect. If needed, refer to the Javassist tutorial for tips on building a class loader.
  2. For advanced scenarios, HotSwapper can be used to swap classes dynamically.

Closing Thoughts

It's unclear why Shannon Hickey chose Introspector.IGNORE_ALL_BEANINFO initially. However, for most use cases, using cached metadata is both safe and efficient.

I hope this solution helps you enhance your BeansBinding applications. Feel free to share comments, suggestions, or improvements!

Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Comments in "BeansBinding Performance (Issue 37)"

  • Avatar for Laird Nelson
    Laird Nelson
    2008-11-18 14:46
    I think very quietly Shannon rose from the dead to fix the issue you're talking about. At least it's the only source code that has been modified in the last umpteen months. So try refreshing beansbinding from version control.
  • Avatar for Marc Nuri
    Marc Nuri
    2008-11-18 14:58
    @Laird:

    Thanks for the note. I hadn't even noticed,the issue appears as unfixed. I used to check the subversion, but since there was no point (everything remains the same) I don't check in a regular basis.

    As you say, the issue was fixed 4 weeks ago ELPropery

    In either case, this is a good example showing how to use javassist.
  • Avatar for heavyrail
    heavyrail
    2010-06-09 16:13
    Hi,

    Thank you for your patch! I've got dialog with nearly 70 items and it took more than 3 seconds to show it, but after I've applied your patch the time has been reduced to just around a second.
  • Avatar for Dusan Kovacevic
    Dusan Kovacevic
    2012-09-01 12:49
    Marc, I have several projects using beans binding. I have to say that my customers suffered HUGE performance issues before...

    But today after finding and implementing your hack , everything works much much much faster and smoother.

    Thank you very much for sharing this with all of us.

    I really really owe you a lot. A beer??? No. The whole supermarket of beers!!!!!!!!!!!

    Cheers!!!!!!!!
  • Avatar for Roberto
    Roberto
    2013-01-06 11:42
    Hi Mkyong,Can you help me with my mapping? I am in doubt on whats the best aparopch?I have an insurance table and user could change the rate plan associated with it.Table Insurance: id long; accountHolder varchar; ratePlanId int; -->Rate Plan Id is Foreign Key to the RatePlanTable Table RatePlan: ratePlanId int; ratePlanDesc varchar; discountRate double;I have a class structure like this:public class Insurance private long id; private String accountHolder; private int ratePlanId; public class RatePlan private int ratePlanId; private String ratePlanDesc; private double discountRate; Is my table-class hierarchy correct? or should I change my Insurance class to this?public class Insurance private long id; private String accountHolder; private RatePlan plan; What should be the proper mapping? Is this a one-to-many mapping also?

Post navigation
What is an Immediately Invoked Function Expression (IIFE)?Windows XP: How to enable the built-in Administrator account
© 2007 - 2025 Marc Nuri