With Javassist, is there any way to inject code into a native method?
Never tried it, but I am not surprised it does not work. Native code is - native. It's a bunch of platform specific bits that bears no relation to Java byte code. And Javassist is all about Java byte code.
Have you consider using proxy based AOP? Check out http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies
I'm not recommending you actually use Spring in your program but it might give you some ideas on how to approach the problem. The reason I think proxy-based AOP might work for you is that you leave your OpenGL based class alone and it just uses the normal native methods. You generate a proxy class which is pure Java but has the same methods as your original class. You call methods on the proxy class which contain the desired call tracking code, plus the invocation of the corresponding method on the "plain object" with it's native methods.
The documentation in Spring says they use JDK dynamic proxies or CGLIB under the covers. So ... I'm thinking that you could use one of these technologies directly as a replacement for your javassist solution.
Hope this helps.
[update]
In the text above I thought you were talking about a class written by you which had primarily instance methods. If you are talking about wrapping the entire OpenGL API, which is primarily static methods, then the AOP proxy method is less appealing. How bad do you want to do this? You could:
- create a custom class - a singleton class with a factory method. Your singleton class wraps the entire OpenGL API. No logging/tracking code. Just naked calls to the API.
- modify every single call in your entire app to use your wrapper, instead of calling OpenGL directly
At this point you have an application that works exactly like what you have now.
Now enhance the factory method of your singleton class to return either the bare-bones instance which does nothing except OpenGL calls, or it can return a CGLIB generated proxy which logs every method. Now your app can run in either production mode (fast) or tracking mode depending on some config setting.
And I totally get it if you want to give this up and move on :)