Getting a call hierarchy in java - java

I am having real trouble tracking down a bug and it would help be a lot to know which method called a certain method. Is there an easy way to get a call hierarchy from java? Java is a small part of the app so I cannot compile and run the whole app in eclipse/net beans so I don't have access to an IDE debugger's call hierarchy.

Thread.currentThread().getStackTrace();
or
Exception ex = new Exception();
ex.printStackTrace();
It's fairly slow, but fine for debugging purposes. API docs here.

Java is a small part of the app so I cannot compile and run the whole app in eclipse/net beans so I don't have access to an IDE debugger's call hierarchy.
You dont need to run the app at all. If you make a project in Eclipse, you can use its built-in Call Hierarchy tool to find all of the possible places that call a method.
There is a trade off: The Call Hierarchy tool will give you ALL of the places from where a method is called. This is a good if you want/need to know all the possibilities. Neslson's suggestion of Thread.currentThread().getStackTrace() will give you the places from where a method is invoked during the process of you program for this invocation. The nuance is that you might not run through every code path during this invocation. If you are seeing specific behavior and want to know how you got there, use the getStackTrace() option.

Have you tried using Java's remote debugging capability?
Google search to get you started if you haven't

The best thing to do is throw an exception, immediately catch it and analyze the stack trace.
I believe that is how Log4J is capable of logging the calling method.

Related

How to see when the last time a specific block of code or if condition was used in Java

I'd like to find redundant blocks of code in my service. Is there a way to check when that last time this code was used runtime? The service is running on GCP.
I don't think there's a great solution to your problem but you could instrument, perhaps via Aspect-Oriented Programming (AOP), selected places in your code with simple logging statements and then monitor those.
You should avoid including any "hot code" which is executed very frequently because you can slow down your service and produce an overwhelming amount of logs (harder to manage and costly).
There's a lot of way to do this, but personally, I would use logging into this function and then let this app running normally. Then, you'll just have to check you log files and check for your logging message occurrences.
However, I'm not sure if it is possible to get this information without any action of your part to see previous usages of your code block.

Block instances of a class at the JVM level?

Is there a way to configure the JVM to block instances of a class being created?
I'd like to do this to ensure no service running in the JVM is allowed to create instances of a class that has been identified as a security risk in a CVE, lets call that class BadClass.
NOTE: I'm looking for a general solution, so the following is purely additional information. I would normally address this by switching the library out, or upgrading it to a version that doesn't have the exploit, but it's part of a larger library that wont be addressing the issue for some time. So I'm not even using BadClass anywhere, but want to completely block it.
I do not know a JVM parameter, but here's some alternatives that might pout you in a position that solve your requirements:
You can write a CustomClassLoader that gives you fine control on what to do. Normal use cases would be plugin loading etc. In your case this is more security governance on devops level.
If you have a CICD pipeline with integration tests you could also start the JVM with -verbose:class parameter and see which classes are loaded when running your tests. Seem a bit hacky, but maybe suits your use case. Just throwing everything into the game, it's up to you judging about the best fit.
Depending on your build system (Maven?) you could restrict building applications just on your private cached libs. So you should have full control on it and put a library - review layer in between. This would also share responsibility between devs and the repository admins.
A distinct non-answer: Do not even try!
What if that larger library that has this dependency wants to call that method? What should happen then?
In other words, what is your blocking supposed to do?
Throw some Error instance, that leads to a teardown of the JVM?
Return null, so that (maybe much later) other code runs into a NPE?
Remember: that class doesn't exist in a void. There is other code invoking it. That code isn't prepared for you coming in, and well, doing what again?!
I think there are no good answers to these questions.
So, if you really want to "manipulate" things:
Try sneaking in a different version of that specific class into your classpath instead. Either an official one, that doesn't have the security issue, or something that complies to the required interface and that does something less harmful. Or, if you dare going down that path, do as the other answer suggests and get into "my own classloader" business.
In any case, your first objective: get clean on your requirements here. What does blocking mean?!
Have you considered using Java Agent?
It can intercept class loading in any classloader, and manipulate it's content before the class is actually loaded. Then, you may either modify the class to remove/fix it's bugs, or return dummy class that would throw error in static initializer.

change the content of debug view in eclipse

I'm writing a java framework, for a class file, sample.class, it generates a proxy file sample_proxy.class. When sample.testMethod() is called, it excutes sample_proxy.class. I already make an eclipse plugin to make the breakpoint work,
If I start from Main.java, and make a breakpoint in sample.testMethod(), the stack below looks like: Main.main-->sample.proxy_method-->sample_proxy.testMethod.
Is there any way to ingore the proxy to show like: Main.main-->sample.testMethod?
What you want to do is possible but a bit more complicated. First of all there is no way to change the StackTrace of a running program. So Thread.currentThread().getStackTrace() is not the way to go.
I'm writing a java framework, for a class file, sample.class, it
generates a proxy file sample_proxy.class.
When you do that, you have to inline the called method, instead of simply calling it. That is non-trivial technique also being used by ProGuard. You will find that it does different kinds of inlining. Most interested you could be in the functionality of "inlining short methods".
I suggest you copy it from the code there. I good point to start would be http://sourceforge.net/p/proguard/code/ci/default/tree/src/proguard/optimize/Optimizer.java#l156
But be aware that this requires fundamental knowledge about the JVM itself, so there won't be a simple code snippet that does what you want, in the context you expect.
I hope it helps.

Java: Print every method called to console?

I need to understand a quite large Java project. I browse through it with eclipse and use the call hierarchy and all, but that doesnt get me quite the idea on what is happening when the project runs (it's a webservice).
Is there a possibility to print out every method call with parameters to console?
Basically something that puts
System.out.println("methodName, params: " + param1.toString());
in every method for me.
Some kind of framework that provides that for example?
You should try to use Aspect-oriented programming (AOP).
Here is an example that does more or less what you want: How to use AOP with AspectJ for logging?

How do I catch the read and writes in a java program?

I am trying to create a tool that can capture all the read and writes made by a java program. Also, I would like to know what fields of what object is access/modified.
I currently looked at:-
1) java.lang.instrument
I could not do much with that. I could not understand how to write an agent that can get access to the a running program and create a watch on different objects/fields and anything related. I would appreciated if you have any idea or information on that.
2) jvmti
I looked at jvmti and tried to create a jvmti tool, but I figured out that to get the objects, I would need the JVMTI_EVENT_OBJECT_ALLOC be a potential capability. But, I figured that, it is not. Moreover, I read that this event is not called for new command. Hence, at the moment, even this does not seem applicable.
So, I would like to know if you guys know any way to do what I want to do, either using the above mentioned methods or any other technique/tool that you may be aware of?
NOTE: I do not have access to the source code of the application. All, I have are the class files.
Check these out:
http://download.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html
http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html
http://jamonapi.sourceforge.net/
http://www.manageengine.com/products/applications_manager/java-runtime-monitoring.html
It's very easy to do with the ASM lib. Create a new Class Loader that instruments all classes before loading them and use it for loading the target classes. Create a new MethodAdapter and override the visitFieldInsn method. Then look for the PUTFIELD, PUTSTATIC, GETFIELD and GETSTATIC opcodes. Although this might look scary (as my explation is most likely gibberish), it's in fact pretty easy. Just download the ASM manual and you'll know how to do it in no time.
Edit: I was forgetting to tell that in order to be able to intercept the reads and writes of done by the JDK code you have to instrument those classes, save them to files and run the JVM with a modified bootstrap classpath, through command line argument -Xbootclasspath (java.* and some other packages; I believe that at least sun.* and javax.* also need this).
This may also be doable with AspectJ... but I'm not sure.

Categories