We use interceptors to measure the execution time of a bean's public method invocation. nonetheless, when a bean's method invoke other private methods, it seems to ignore the audit interceptor.
How can we measure the execution time of private methods as well?
Using AOP
You could implement a benchmarker using an Aspect-Oriented Programming library like AspectJ.
For instance, see:
this SO question on Catching Private or Inner Methods with AspectJ,
or this article on Profiling with AspectJ.
Using a Profiler
You could implement your own agent extension (for instance, for JProfiler).
Or you could give up on your interceptors and simply inspect from any profiler allow to capture snapshots and to record execution times.
Using JVMTI
Which is what some profilers do, actually.
You could resort to using the JVMTI API (not entirely sure this would fly, to be honest) to implement your own code inspector and directly hook yourself into the JVM.
The Sneaky and Evil Inlining Issue
Regarding jb's (valid) concern in his answer that private methods might be inlined at either compilation time or runtime, some JVMs may not do it or allow to disable this feature.
Oracle's JRockit has a -XnoOpt option that would disable optimizations (including this particular one).
Oracle/Sun's HotSpot at least used to have -XX:-Inline (not sure it still exists or does anything).
However, it means you don't measure exactly what you'd have in production when the inlining is activated. Still, probably handy for inspecting your code.
Interceptors are applied by EJB container on invocation of interface methods - your private methods are invisible to it. What about using profiling tool instead?
Well AFAIK private methods can be inlined at JVM lesiure (even at compilation time), so they can't be profiled since they might not exist in bytecode.
I suppose you could mark your methods protected --- so they will not be inlined even in production, and then profile it.
If you want to profile your test instance you might try visualvm --- visualvm is a very nice alternative. VisualVM is a graphical tool to profile JVM istances that does all the instrumentation needed. http://visualvm.java.net/. Moreover it is a standard tool in most jdk distros.
Related
I'm currently working on optimizing a particular method, which is unfortunately inlined by the JVM, which prevents it from being properly vectorized. I've noticed that there is an annotation to forbid inlining, namely jdk.internal.vm.annotation.DontInline . However, it cannot be accessed from the default module.
Is there a clean way of gaining access to this annotation or to prevent the inlining of the offending method some other way?
DontInline, ForceInline, etc. are JDK internal annotations, they cannot be applied to user code. Even if you somehow manage to open these annotations, HotSpot JVM has an explicit check to disallow them for non-privileged classes.
The reasons are understandable. These annotations are the implementation detail of the particular JVM version; JDK developers are free to add/remove/change meaning of such annotations without notice, even in a minor JDK update.
Using #DontInline to force vectorization does not seem a good approach anyway. In general, inlining should not prevent from other optimizations. If you encounter such problem, it's better to report an issue on hotspot-compiler-dev mailing list.
Now the good news.
Since JDK 9, there is a public supported API to manually tune JIT compiler. This is JEP 165: Compiler Control.
The idea is to provide compiler directives in a separate JSON file, and start the JVM with -XX:CompilerDirectivesFile=<file> option. If your application is sensitive to certain compiler decisions, you may provide the directives file along with the application.
{
match: "*::*",
inline: "-org/package/MyClass::hotMethod"
}
It is even possible to apply compiler directives programmatically in runtime using DiagnosticCommand API:
ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"compilerDirectivesAdd",
new Object[]{new String[]{"compiler.json"}},
new String[]{"[Ljava.lang.String;"}
);
By the way, there is Vectorize: true option among the directives list, which may probably help in vectorizing the particular method.
Currently I'm trying to modify method bodies residing in classes already loaded by the JVM. I'm aware of the JVM actually not allowing to change the definition of classes that have already been loaded. But my researches brought me to implementations like JRebel or Java Instrumentation API, both using an agent-based approach. I know how to do it right before a class is loaded o behalf of Javassist. But considering e.g. JRebel in an EJB environment where class definitions are loaded on application startup, shouldn't bytecode modification be possible on JVM-loaded classes?
Well, you learned that the Instrumentation API exists and it offers redefinition of classes as an operation. So then it is time to rethink you initial premise of “the JVM actually not allowing to change the definition of classes that have already been loaded”.
You should note that
as the links show, the Instrumentation API is part of the standard API
the support of redefinition of classes is, however, optional. You may ask whether the current JVM supports this feature
it might be limited to not support every class; you may ask whether it’s possible for a particular class
Even if it is supported, the changes may be limited, to cite the documentation:
The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions.
at the time you perform the redefinition, there might be threads executing code of methods of these classes; these executions will complete using the old code then
So the Instrumentation is merely useful for debugging and profiling, etc.
But other frameworks, like EJB containers, offering class reloading in production code, usually resort to creating new ClassLoaders which create different versions of the classes which then are entirely independent to the older versions.
In a Java runtime environment, the identity of a class consists of a pair of <ClassLoader, Qualified Name> rather than just a qualified name…
I wasn't aware that you can use the instrumentation API to redefine classes (see #Holger's answer). However, as he notes, there are some significant limitations on that approach. Furthermore, the javadoc says:
"This method is intended for use in instrumentation, as described in the class specification."
Using it to materially change the semantics of a class is ... all sorts of bad from the perspective of the Java type system.
I am trying to wrap my head around this concept. My questions are:
Is this operation costly from a performance point of view, and if so, why?
If I am trying to intercept some parameters being passed to a method by injecting some code after the method is called, does this injection happen once or does it happen every time the method is called?
Where does this injection code reside? In the application source itself or somewhere else?
You can achieve bytecode injection with Java Agents.
A java Agent is a library that intercepts the bytecode loading at the classloader, and enhances it before it is loaded in the JVM. Of course, such a library usually relies on bytecode manipulation librairies such as Javassist, ASM or CGLib.
So the bytecode manipulation is only done once, when the class is loaded.
See the official Javadoc :
http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html
This article explains how to do pretty much what you want to:
http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html
Also, if you're really interested in bytecode fundamentals, this article from one of the JRebel developers should please you:
http://arhipov.blogspot.com/2011/01/java-bytecode-fundamentals.html
Finally, you can take a look at Seren, a librairy I just began to write. It is a Java Agent that enhances serializable classes. It's just the beginning, but it works.
https://github.com/oliviercroisier/seren
Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.
Why at runtime is anyone interested in knowing that a method is deprecated? Can some provide me with some examples?
There are some frameworks and tools that instantiate objects to work with them.
For example, many JavaBean UI editors create instances of the beans and interact with them as the user manipulates the UI they're designing.
Having the #Deprecated annotation available at runtime allows tools such as this to flag deprecated methods, events, properties for the user.
You're assuming that #deprecated is only of interest in the compile phase (IDE, compiler), but its not a stretch to imaging instrumentation scenarios where you require that information.
For example, an IDE can inform you of the number of call sites for a deprecated method, but how would you go about determining the percentage of time your application spends in deprecated methods?
One's runtime is another one's design time, e.g. when writing code that uses an API.
Good question, and I'm stretching to come up with a convincing scenario. All I've got is that I could imagine a application which used a classloader which didn't allow the use of deprecated code. This would require RetentionPolicy.RUNTIME.
That's all I've got...
Couple practical uses that come to mind:
With Velocity you can have a custom Uberspector which logs the actual calls from Velocity templates to any deprecated method and then just by reading the log you can see where the method is used and you can go and edit it out.
With Wicket you can have a security policy which disallows instantiating any class based on the .class contents so it could be possible to make a system which prevents the instantiation of #Deprecated classes if you're not an admin.
Imagine you compile MyClass.class with deprecated methods. If your #Deprecated annotations got lost, your IDE or compiler couldn't warn you when you call those methods from another class.