JavaRush /Java Blog /Random EN /IntelliJ IDEA and Debug: not diving, but snorkeling
Viacheslav
Level 3

IntelliJ IDEA and Debug: not diving, but snorkeling

Published in the Random EN group
Writing code is half the battle. It still needs to be made to work correctly. IDEs and debugging tools help us a lot with this.
IntelliJ IDEA and Debug: Not diving, but snorkeling - 1
Using IntelliJ IDEA as an example, I propose to get acquainted with how we can find out what happens to our code when it runs. Debug is a broad topic, so this review does not offer deep diving, like a diver. But I hope snorkeling for sure)

Introduction

Part of writing code is debugging it. And if your tasks include code support, there will be even more debugging. Well, in addition, with the help of debugging, you can examine the work of the libraries and frameworks used as deeply as you can immerse yourself in the jungle of someone else’s code. For our dive we will need: First, unpack the downloaded archive with Quick Start Source Code. Launch IntelliJ Idea and create “ New Project from Existing Sources ”. Select the pom.xml file in the hibernate4 subdirectory . When importing, specify “ Import Maven projects automatically ” and complete the creation of the project, leaving other settings unchanged. While the project is being imported, unzip the downloaded WildFly application server into some directory. We start the server using the file (or standalone.sh for *nix systems). (!) It is important to start with the --debug parameter . We wait for the server to start. They will write to us that it started in and indicate the time. It will look something like this: bin\standalone.bat
IntelliJ IDEA and Debug: Not diving, but snorkeling - 2
Next, we need to run the project we have chosen on the server. This process is described in a small documentation that can be found in the project itself: \hibernate4\README.adoc As indicated in this documentation, we need to run the command in the hibernate4 directory: mvn clean package wildfly:deploy We are waiting for a message that the build was completed successfully:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 3
After this, in the server log we can see how the new project has been “deployed”:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 4
After that, we go to the page http://localhost:8080/wildfly-hibernate4and we should display a page with the “ Member Registration ” form. So, our preparation for the experiments is complete and we can begin)) There will be a lot of pictures ahead for clarity, so get ready)

Remote Debug

So, we need to configure Debug mode so that our IDE controls the execution of code on the application server. IntelliJ Idea comes in two versions: free (Community) and paid (Ultimate). The latter can be officially tried in the form of EAP. In the Ultimate version, everything is simple - the application server can be launched directly from the IDE in debug mode. But in the Community version you need to do a few things manually. Therefore, let's consider a more complicated case, i.e. setting in Community version. The Community version has some limitations. In particular, you cannot run an application server from it. But you can set up remote debugging (Remote Debug), when somewhere separately there is a running server with the application we need. Let's use the description of the setup from here: Remote debug Wildfly in IntelliJ Idea community edition (setting up Remote Run Configuration for port 8787). After configuration, we launch our new configuration in Debug mode:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 5
If all is well, we will see a message about this below:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 6

Debug process

Let's debug saving the record. To do this, we must first decide on the place where we will explore. Judging by the window, we need a “Register” button. Let's find it in the code. So, we need an element, it should have the text: "Register". Or she should have something to do with it. Click Ctrl+Shift+Fand look for Register in quotes. We see that there is one on index.xhtml.
IntelliJ IDEA and Debug: Not diving, but snorkeling - 7
Press Enter to go to the found source:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 8
So, we see that when registering, memberController.register is called. Apparently, this must be some kind of java class. Click Ctrl+Nand search for:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 9
Indeed, there is such a class. Let's go into it. Apparently, there should be a register method. Click Ctrl+F12and look for the register method
IntelliJ IDEA and Debug: Not diving, but snorkeling - 10
Indeed, we found it. Apparently, registration occurs here, in memberRegistration.register . Press Ctrl and click on the method to “fall through” into it:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 11
Let's now set a “break point” or Break Point. This is a marker that tells where code execution should pause. At this moment we will have the opportunity to learn a lot of interesting things. To put it you need to click in the place to the right of the line number.
IntelliJ IDEA and Debug: Not diving, but snorkeling - 12
On the page http://localhost:8080/wildfly-hibernate4 fill in the fields and click the Register button. The idea icon on the panel will blink:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 13
Going to Idea, you can see that there is a lot of interesting information in the debug panel:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 14
Here you can see the value of the object's fields. For example, what does a registered Member consist of:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 15
Great. What else can we do? We can open the context menu and select Evaluate Expression there (or through the menu Run -> Evaluate Expression). Better yet, on the debugger control panel:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 16
This is a super cool ability at a breakpoint, having access to everything that that code point has access to, to execute any code that could be executed at that point. For example:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 17
There are also control buttons on the debugger control panel that are responsible for where you want to move the program flow control. Isn't it magic?) By pressing the F8 (Step Out) button, we walk through the code without entering methods. By pressing F9, we stop walking through the lines of code with the debugger, and give the debugger control over the execution of the program. If we press F7 (Step Into), then we will go through the code, entering each method that we meet along the way. By the way, pay special attention to this information block:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 18
This shows the thread we are in and the methods on the stack of the current thread. But that's not all. For convenience, you can open the frames tab. To do this it must be enabled:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 19
Now on the frames tab we see information about the transition from method to method, because started walking through the code using Step Into.
IntelliJ IDEA and Debug: Not diving, but snorkeling - 20
As we see, we cannot always be transferred to where the program is currently being executed. We are now at "getDelegate:469, AbstractEntityManager(org.jboss.as.jpa.container)". But in fact, we are in implementation. This is evidenced by the class specified by this:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 21
Let's look at this. As we know, it points to the current object. We are at TransactionScopedEntityManager. Why can't Idea show us the code? The fact is that IntelliJ Idea currently does not know about any TransactionScopedEntityManager, because it is not connected to our project (it is not in the project dependencies). When an application server is running, there are many, many different libraries running inside it. But we know very little about them, because... in general, we don’t need to delve into the internals, we just need it to work. But sometimes work or sporting interest requires it. Then, you need to inform Idea about this library so that it knows where to get the class code.

Connecting third-party libraries for debugging

First, we ourselves need to understand what kind of library it is that needs to be connected. The first way is the most difficult - search on the Internet. The speed and result of finding a result greatly depend on how well the project was managed. For example, WildFly has an open repository. So when we Google “TransactionScopedEntityManager” we will go to https://github.com/wildfly/wildfly/tree/master/jpa/subsystem and find that we need wildfly-jpa. The second method is correct. Where the server is, look there. Various means can help with this. For example, on Windows it could be Far Manager . Below is an example of a search algorithm. Having installed and launched it, use Tab to switch to one of the tabs, using Alt+F1the left tab or Alt+F2the right one, and select the partition we need on the hard drive. It is quite possible that the Far Manager directory itself is open in Far Manager after installation. To go to the root of the disk, press Ctrl + \. Using, Alt+Fopen the search window, start typing the name of the directory and press Enter after the directory is found. This search is clever and highlights those directories that match the search text. If you enter characters for which there are no folders, then such characters cannot be entered. This way we go to the application server directory. Let's say we don't know where the modules are located on the server. Perhaps this is the first time in your life that you are hearing about some kind of WildFly. Therefore, click immediately here Alt+F7to search for files. So, logic dictates: we need a file with the library. That is, we need a jar. There should be a TransactionScopedEntityManager class inside. Because class = file, then look for “contains”. That is, something like this:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 22
Now, let's wait for the result. He won't keep you waiting)
IntelliJ IDEA and Debug: Not diving, but snorkeling - 23
Now, we need to find the source code for it somewhere. And there are 2 options: Let's use, perhaps, the second one. Let's find there:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 24
Now let's move on to describing the dependency. On this page you can download the source code. Great, now we have the code downloaded. All that remains is to connect the library. It connects extremely simply. We need to open the project settings:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 25
There we select “Libraries” and add the received source codes to the “Sources” section, and in the “Classes” section we indicate the library jar file itself from the WildFly directory, which we found using Far Manager. After this, when we navigate through F7, we will see the contents of the AbstractEntityManager and TransactionScopedEntityManager class, and will also become available through a search by class using Ctrl+N.

Break Points with conditions

Let's return now to Break Points. Sometimes, we don’t always want to stop, but only under some condition. What to do? And here our IDE will also help us. By placing a Break Point, we can assign a condition to it. For example, put a point and right-click on it:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 26
Now the breakpoint will only fire when the name is Maximilian. By clicking the More button, an expanded set of settings for Break Points will be available to you.

Break Points on exceptions

Sometimes we may receive an error and we want to trace where it comes from. Then we can add a breakpoint not at a specific line of code, but at the place where the exception will be thrown. To do this, you need to expand the list of all breakpoints:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 27
And create a new rule for the selected exception type:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 28
For example, for NPE:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 29

HotSwap classes

Debugger is an amazing thing. In addition to debugging, it allows you to change classes! Yes, resources (such as xhtml pages, for example) cannot be changed so easily. But the code of java classes can be replaced on the fly (this is called Hot Swap). To do this, just change the class with the debugger attached and execute Run -> Reload Changed Classes. Useful review on this topic: 4 free ways to hot-swap code on the JVM

Conclusion

A debugger is a powerful tool that allows a developer to penetrate into the very depths of the executing code and study it in every detail. This allows you to correct the most confusing errors. It also allows you to better understand how certain libraries work. Even such a brief review turned out to be quite impressive, but I hope it will be useful and interesting. If anyone is interested in this material, you can continue the dive using the following links:
IntelliJ IDEA and Debug: Not diving, but snorkeling - 30
#Viacheslav
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION