BeansBinding Performance (Issue 37) 5


Since the release of NetBeans 6.0, BeansBinding (JSR 295) framework popularity has increased. Personally I’m using it now in all my projects. Ease of development and the increase of productivity are worth it. The counterpart is that this project looks dead and hasn’t been updated for more than a year now. Even more, recent news about Swing core is not very encouraging.

In my opinion I believe that Sun’s budget is very limited and their recent javaFx has consumed all their resources in the past year. Bearing in mind that BeansBinding is now included in netbeans and that javaFx is based in swing, I don’t think that neither of the projects is going to be abandoned.

Getting into the subject, BeansBinding has not been updated for a while now, and has some bugs that are really annoying. If you use beans binding to bind a form with more than 20 fields you’ll notice how the form takes a lot to load. If you profile your application, you’ll quickly notice that the bottleneck is in the statement bindingGroup.bind() in the initComponents() section of your code (if you are using Netbeans + matisse). Taking a deeper look with the netbeans profiler tool we get to our point. If you examine carefully BeanPropery or ElPropery class, the method getBeanInfo(Object object) is calling Introspector.getBeanInfo(object.getClass(), Introspector.IGNORE_ALL_BEANINFO); which takes a lot of time. I Googled to see if I could get any clue about what was happening and if someone else was experiencing the same problem. I found a 2 mail message thread. Not very popular for such a big performance problem. The thread informs of the created Issue (Issue 37) the and suggest a possible solution using USE_ALL_BEANINFO (which by the way is the default flag used if you call the Introspector.getBeanInfo(Class class) directly).

The slow dialog opening is really pissing me, so I’ve implemented a solution. Your first approach can be by getting the source code and replacing the code fragment you need and then recompile the library. There is a great tutorial (Hacking Java Libraries) which teaches you how to do this if you don’t know how to do it by yourself. The article is an exception of “Covert Java” by Alex Kalinovsky (Sams Publishing, May 2004) (recommended reading).

I don’t really like the approach above. With these technique you can’t keep track of the changes you’ve made and further updates of the library will need to be modified and recompiled again (until the bug is corrected). I prefer to manipulate the bytecode at runtime to reflect the changes I need (BCEL). For this purpose I’m going to use the javassist library which is very light and straightforward. In the next code fragment you have the code needed to get the modification working.

What the above code does is replace the method body of getBeanInfo in ElPropery and BeanPropery with the modified code that suits our needs. In this case, instead of calling Introspector.getBeaninfo(Class class, int flag) it calls Introspector.getBeanInfo(Class class) which by default uses the cached information, improving performance. For all of this to work it’s very important to run this code before any other code which uses the beansbinding library is called. If you can’t do that, read the javassist tutorial to build a loader or use HotSwapper.

I don’t know why Shannon decided to use the Introspector.IGNORE_ALL_BEANINFO flag in the first place, maybe there’s a good reason. I can’t really think why we shouldn’t use the cached info, there’s no reason why a bean should change its structure during runtime (Unless someone is using dynamic bytecode engineering BCEL).

I hope this code helps you. Please if you have any comments, suggestions or improvements, please post them. Thank you.

Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+Pin on PinterestEmail this to someone

Leave a comment

Your email address will not be published. Required fields are marked *

5 thoughts on “BeansBinding Performance (Issue 37)

  • Laird Nelson

    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.

  • Marc

    @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.

  • heavyrail

    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.

  • Dusan Kovacevic

    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!!!!!!!!

  • Roberto

    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?