Oc-windows.ru

IT Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java remote debug

Java Application Remote Debugging

Last modified: November 7, 2019

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

In the 9 years of running Baeldung, I’ve never, ever done a «sale».
But. we’ve also not been through anything like this pandemic either.
And, if making my courses more affordable for a while is going to help a company stay in business, or a developer land a new job, make rent or be able to provide for their family — then it’s well worth doing.
Effective immediately, all Baeldung courses are 33% off their normal prices!
You’ll find all three courses in the menu, above, or here.

1. Overview

Debugging a remote Java Application can be handy in more than one case.

In this tutorial, we’ll discover how to do that using JDK’s tooling.

2. The Application

Let’s start by writing an application. We’ll run it on a remote location and debug it locally through this article:

3. JDWP: The Java Debug Wire Protocol

The Java Debug Wire Protocol is a protocol used in Java for the communication between a debuggee and a debugger. The debuggee is the application being debugged while the debugger is an application or a process connecting to the application being debugged.

Both applications either run on the same machine or on different machines. We’ll focus on the latter.

3.1. JDWP’s Options

We’ll use JDWP in the JVM command-line arguments when launching the debuggee application.

Its invocation requires a list of options:

  • transport is the only fully required option. It defines which transport mechanism to use. dt_shmem only works on Windows and if both processes run on the same machine while dt_socket is compatible with all platforms and allows the processes to run on different machines
  • server is not a mandatory option. This flag, when on, defines the way it attaches to the debugger. It either exposes the process through the address defined in the address option. Otherwise, JDWP exposes a default one
  • suspend defines whether the JVM should suspend and wait for a debugger to attach or not
  • address is the option containing the address, generally a port, exposed by the debuggee. It can also represent an address translated as a string of characters (like javadebug if we use server=y without prov >

Let’s start by launching the remote application. We’ll provide all the options listed earlier:

Until Java 5, the JVM argument runjdwp had to be used together with the other option debug:

This way of using JDWP is still supported but will be dropped in future releases. We’ll prefer the usage of the newer notation when possible.

3.3. Since Java 9

Finally, one of the options of JDWP has changed with the release of version 9 of Java. This is quite a minor change since it only concerns one option but will make a difference if we’re trying to debug a remote application.

This change impacts the way address behaves for remote applications. The older notation address=8000 only applies to localhost. To achieve the old behavior, we’ll use an asterisk with a colon as a prefix for the address (e.g address=*:8000).

According to the documentation, this is not secure and it’s recommended to specify the debugger’s IP address whenever possible:

4. JDB: The Java Debugger

JDB, the Java Debugger, is a tool included in the JDK conceived to provide a convenient debugger client from the command-line.

To launch JDB, we’ll use the attach mode. This mode attaches JDB to a running JVM. Other running modes exist, such as listen or run but are mostly convenient when debugging a locally running application:

4.1. Breakpoints

Let’s continue by putting some breakpoints in the application presented in section 1.

We’ll set a breakpoint on the constructor:

We’ll set another one in the static method main, using the fully-qualified name of the String class:

Finally, we’ll set the last one on the instance method buildInstanceString:

We should now notice the server application stopping and the following being printed in our debugger console:

Let’s now add a breakpoint on a specific line, the one where the variable app.instanceString is being printed:

We notice that at is used after stop instead of in when the breakpoint is defined on a specific line.

4.2. Navigate and Evaluate

Now that we’ve set our breakpoints, let’s use cont to continue the execution of our thread until we reach the breakpoint on line 7.

We should see the following printed in the console:

As a reminder, we’ve stopped on the line containing the following piece of code:

Stopping on this line could have also been done by stopping on the main method and typing step twice. step executes the current line of code and stops the debugger directly on the next line.

Now that we’ve stopped, the debugee is evaluating our staticString, the app‘s instanceString, the local variable i and finally taking a look at how to evaluate other expressions.

Let’s print staticField to the console:

We explicitly put the name of the class before the static field.

Let’s now print the instance field of app:

Next, let’s see the variable i:

Unlike the other variables, local variables don’t require to specify a class or an instance. We can also see that print has exactly the same behavior as eval: they both evaluate an expression or a variable.

We’ll evaluate a new instance of OurApplication for which we’ve passed an integer as a constructor parameter:

Now that we’ve evaluated all the variables we needed to, we’ll want to delete the breakpoints set earlier and let the thread continue its processing. To achieve this, we’ll use the command clear followed by the breakpoint’s identifier.

The identifier is exactly the same as the one used earlier with the command stop:

To verify whether the breakpoint has correctly been removed, we’ll use clear without arguments. This will display the list of existing breakpoints without the one we just deleted:

5. Conclusion

I:n this quick article, we’ve discovered how to use JDWP together with JDB, both JDK tools.

More information on the tooling can, of course, be found in their respective references: JDWP’s and JDB’s – to go deeper into the tooling.

Java Remote Debug with Eclipse

Debugging a remotely running Java application using Eclipse IDE is an important skill in our Java debug arsenal. Eclipse IDE is what I use mostly and so I took it for example. Configuring the same for debug with other IDEs like NetBeans, IntelliJ should be similar.

We will need this remote debug mechanism when the application is running separately outside of IDE. Mostly when the application might be in different system in the network. We will have the source or project configured in IDE in our system. Scenarios include, issue coming only in some X system and application working good in other systems. In that case, we want to remotely debug the application running in that X system.

This is a how-to tutorial and if you know how to remote debug a Java application using Eclipse, please terminate reading this, you may not find anything interesting and finally you will blame me, saying you didn’t expect a so basic article from me. If you are looking for Eclipse debugging tips in general, you can refer to this earlier written super hit article.

To debug remote Java application

Step 1: Start the application in debugging mode

java -Xdebug -runjdwp:transport=dt_socket, server=y, suspend=n, address=

  • server=y – Java application should be a TCP/IP server and wait for connections
  • suspend=y – the Java application (now server) will pause on start up and wait for debugger to join. If ‘n‘, application will not wait for debugger at start up, instead it will run as usual and when > – a port number on which the debugger will join to debug the application. Remember, this should be a port that is not already in use.
  • ClassName – Java application main-class name. If we have a jar we can include that with appropriate classpath.

Step 2: Configure and Start Eclipse in Remote Debugging Mode

  1. First we should have the project source in place. Keep the breakpoints wherever necessary.
  2. Go to Run –> Debug Configurations –> Remote Java Application
  3. Create ‘New’ remote java application and give the Host and Port. Host is the IP of the machine where the remote java application is running. If the application is running in the same machine, then we can give localhost. Then the port which we have given while starting the application in remote mode.
  4. Now click ‘Debug’ to start debugging the remote java application.

Example Remote Java Application Debugging

I am running the above program in Java remote debug mode.

Example remote debug application start:
java -Xdebug -runjdwp:transport=dt_socket, server=y, suspend=n, address=6666 com.javapapers.java.DebugRemote

Now, I have kept the break point inside the action listener method and so on click of the button, Eclipse wakes up on debug mode and I get control for remote debugging.

Java Remote Debugging Issues

  • If the project source and the running application is not in sync, the remote debugging may not work as expected. Breakpoints will not pause as we expect.
  • Avo >

    Popular Articles

    Comments on «Java Remote Debug with Eclipse»

    I know how to remote debug in Java. I read your warning not to read this, I ignored and proceeded.

    This topic is all about a single line command and nothing great in it.

    But still above all, the way you have built an article around it is master class. Going through it is like reading an entertainment magazine. Technology made simple and lively!

    Thanks and keep writing forever.

    Is the remote debugging supplied in-build in tomcat server? I have to debug my web-application on remote computer. Please let me know.

    Very informative and nice way of explaining things.
    Waiting for more such articles.

    Hi Joe,
    Could you please explain how to do remote debug for web application which is running in web application server.

    @Venkat Bandi I too have the same question.

    Hi Joe, Can you please post the steps for the same .

    All the Humour Origin is the Keithy Sierra and Bert Bates

    No, you need to pass debug parameters while launching tomcat server in catalina.sh

    Nice Article Joe

    in which file this entry need to go ” java -Xdebug -runjdwp:transport=dt_socket, server=y, suspend=n, address= “

    Comments are closed for «Java Remote Debug with Eclipse».

    How to debug a Java application running on Linux from Eclipse using Remote debugging — Step by Step Gu >

    The remote debugging of Java program is an ultimate tool in the arsenal of a Java developer, which is often become the last and only tool to investigate a bug on a Java application running on the remote host like on Linux server or Windows server. Almost all major Java IDE provides remote debugging like NetBeans, Eclipse, and IntelliJ IDEA, but I mostly use Eclipse for Java coding and so it’s my preferred tool to remote debug a Java program. In order to set up remote debugging in Eclipse, you need to do a couple of tasks like you need to start your JVM with debugging parameters or arguments and then you need to create a «remote debug configuration» in Eclipse IDE itself.

    I have been sharing a lot of Eclipses tips and tricks in this blog like how to escaping JSON string in Eclipse to easily create JSON for testing and debugging purposes.

    In this article, I’ll not only teach you how to set up remote debugging in Eclipse by walking through a step by step guide but also teach you how to actually debug a Java program running on a remote Linux server.

    I’ll also tell you how to use essential debugging commands like Step Into, Step Over, and how to watch variables while debugging, which will not only helpful during remote debugging but also on during local debugging, right from Eclipse.

    Btw, before starting this tutorial, I expect that you are familiar with both Java, JVM, and Eclipse IDE itself because when we talk about Run and Debug configuration, you should understand what we are talking about.

    I’ll show you every step using the screenshot and explain to you what we are doing and why we are doing but some basic knowledge of Eclipse is required. If you don’t know Eclipse or never used Eclipse before, you won’t be able to understand whatever I say.

    That’s why, If you are a complete beginner then I suggest you first go through a comprehensive Java course like The Java MasterClass and Beginners Eclipse Java IDE Training Course to learn Java and Eclipse little bit better before starting with remote debugging. That will help you to use Eclipse IDE effectively for Java development.


    3 Steps to Setup Remote debugging of a Java appliation in Eclipse > 1) Start JVM with debug arguments

    In order to debug a Java application running on a remote host(Linus or Windowx), you first need to start the JVM with debugging arguments, as shown by following command:

    $ /oracle/jre/v1.6.0_18-64bit/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,address=11001,server=y,suspend=y -jar app.jar

    Though there are different JVM options to start your JVM in debug mode, depending upon which version of JRE you are using.

    If you’re using Java 1.4 JRE then you need to use -Xdebug and -Xrunjdwp arguments. These options will also work in later versions, but it will run in interpreted mode instead of JIT, which will be slower.

    Btw, I really hope Eclipse should have something similar to IntelliJ IDEA which makes it easy to remember the JVM debugging options as shown below:

    From Java 5.0, it is better to use the -agentlib:jdwp as single option e.g. :

    Options on -Xrunjdwp or agentlib:jdwp arguments are almost the same:

    transport=dt_socket: means the way used to connect to JVM (the socket is a good choice, it can be used to debug a distant computer)

    address=11001: TCP/IP port exposed, to connect from the debugger,

    suspend=y: if ‘y’, tells the JVM to wait until the debugger is attached to begin execution, otherwise (if ‘n’), starts execution right away.

    If you are debugging for an event that happens during startup then you can use the suspend=»y» to go through startup sequence step by step. On the other hand, if the issue is happening after it receives a message or request then you can start with suspend=»n» and connect it later. See Eclipse Debugging Techniques And Tricks for more of such tips.

    2) Create a Remote Debug Configuration in Eclipse IDE

    You also need to create a remote debug configuration in Eclipse IDE before you start debugging. In order to do so, just follow steps:

    2.1) Go to debug configuration from Run menu as shown below:

    2.2) Go to remote Java application

    2.3) Configure details e.g. name, project, the Eclipse project which contains the code of Java application you are trying to debug. Connection type should be «socket attach» and then specify host and port in Connection properties as shown below. Always specify a fully qualified domain name for the host

    2.4) Hit apply after making change

    You are done with setting up remote debugging in Eclipse. In the next part of this article, I’ll show you how to remotely debug a Java application step by step.

    How to Remote debug Java Program in Eclipse

    Once you are done with setting up remote debugging in Eclipse IDE, you can follow these steps to start debugging your remote Java program:

    1. Setup a Breakpoint in Your Code

    In order to start debugging, you first need to set up a breakpoint in your code. You can set up breakpoint at any line by the just left click of mouse i.e. go to your Java code and left-click on any line where you want to stop the JVM.

    This is also known as line breakpoint, btw, don’t put line breakpoint on empty lines. Also, if you are just starting with debugging, you can start by putting a breakpoint in the main() method which is the entry point of Java application.

    2. Start JVM with Debug Arguments

    Before you launch your Eclipse remote debugging configuration, you need to start the JVM on the remote host as shown in following command:

    $ /oracle/jre/v1.6.0_18-64bit/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,address=11001,server=y,suspend=y -jar app.jar

    A couple of things to note here, we are starting JVM on server mode and asking it to suspend until the debugger connects it, which means it will not start execution until you start your Eclipse IDE and launch remote debug.

    It is also listening for the debugger on port 11001, which means your Eclipse remote debugging setting should also use the same port.

    Once you start the JVM, it will print the following line the log file or command line, depending upon where you are redirecting the output stream:

    Listening for transport dt_socket at address: 11001

    This means JVM is ready to attach the debugger and now it’s time to start remote debugging in Eclipse IDE. Btw, if you are not familiar with Java Virtual machine then I suggest you go through the Understanding the Java Virtual Machine series on Pluralsight, which explores JVM Memory Management, Classloading, Security and other important details.

    3. Launch your Remote Debug Configuration in Eclipse

    Once JVM is started in debug mode and you can see the above line the log file, you can just go and launch the remote debug configuration and double-clicking the configuration you have just created. If JVM is running then it will try to connect it using host and port details given in the configuration i.e. 1001 but if JVM is not running then it will show the following error:

    This error means either your JVM is not running but if you are sure that JVM is indeed started and ready to connect then maybe your host and port configuration is incorrect e.g. any typo on fully qualified domain name or any network issue which preventing your local machine to connect to the remote host.

    If your Eclipse IDE is successful to establish a connection to debugger running on remote JVM then Eclipse will open a debug perspective and you could see where exactly JVM has stopped, a full stack trace starting from loading the classes.

    Now, you got the control of flight and it’s up to you how you move.

    When you first time debugs a Java program, Eclipse will ask you to open the Debug Perspective and then next time it will automatically do so.

    Here is how Eclipse’ Debug Perspective look like:

    In Debug Perspective, you have a lot of debugging tools like you can execute code step by step, can see where you have put breakpoints, can watch values of variables and can see which thread you are debugging and can terminate the debugging session. The debug perspective is the same for both local and remote debugging.

    4. Move Step by Step in your Java Code

    There are a couple of option to move in your code you can use either Step Into for step by step executing code, which means if the code contains a method call then your code will go inside a method and then initialize variable and other code and finally come back to where you were.

    Alternatively, you can use Step Over to just go over the method call and move to the new line. You can use a combination of these two commands to effectively move around an interesting read to find any bug or observer the output in the log file. The button to Step Over is just next to Step Into as seen in the above screenshot.

    5. Watch values of Variables

    6. Terminate the JVM

    Once you are done with remote debugging and find the root cause of your problem you can terminate the remote Java application right from the Eclipse IDE. This will stop the JVM as well Eclipse remote debug console, but if you don’t want to stop the JVM on the remote host then just click the disconnect button and it will stop the debugging process in Eclipse.

    That’s all about how to setup remote debugging in Eclipse IDE and how to remote debug a Java application running on the Linux server. The key is that you should have the same version of a class file and Java source file on both remote and local machines.

    If your Java source code is not in sync with the class file on the remote host then the debugging will be inaccurate i.e. you will set a breakpoint at line 5 but your code will be running line 10, hence it is an absolute must that both code and binary running on the remote host must be of the same version.

    Thanks for reading this article so far. If your like this article then please share with your friends and colleagues. If you have any question or feedback or facing any problem while setting up Eclipse for remote debugging then please drop a comment and I’ll try to help you out.

    What is Remote Debugging in Java?

    Consider a scenario where you can’t run the application in your development environment, e.g. say your application can run only on a server machine (because it is dependent on some third party interface that are not accessible in your development machine) and you have to resolve a problem (bug). What you can do?

    Java Remote Debug

    The solution is Java Remote debugging. Remote debugging is debugging an application by connecting the remotely running application with your development environment ( i.e. you can say to connect with code in your IDE).

    How remote debugging works?

    Remote debugging feature is provided by Java specification itself. Java provides this feature using listener binding mechanism. Basic concept is pretty simple and straightforward:

    • Application to be debugged would attach a socket to itself and then would listen debug instructions on that socket.
    • Debugger would bind itself to that socket and then send instructions on that socket.

    Running an java application in debug mode

    As I said earlier, for remote debugging, you need to run that application in debug mode. To run an application in debug mode requires to provide specific jvm arguments to “java” command.

    JVM arguments for DEBUGGING

    For JVMs prior to 1.5

    One need to supply two arguments, -Xdebug and -Xrunjdwp. -Xdebug tells JVM to run the application in debug mode, while -Xrunjdwp is used to supply debug parameters (It can also be used in JVM 1.5 or 1.6 as well)

    e.g. -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

    For JVMs 1.5 and 1.6

    Debug library is passed as -agentlib argument, along with debug paramters. Native library name for debugging is jdwp, so one need to supply -agentlib:jdwp along with debug paramters.

    Detail of debug parameters

    • Name: help
      Is Optional : Yes
      Default Value: N/A. This parameter doesn’t have any value at all.
      Description: It prints all the available options on the console and exits the JVM.
      Example: java -agentlib:jdwp=help
    • Name: transport
      Is Optional: No (It is a required field)
      Default Value: No default value specified in specifications. Totally depends upon native lib provided by JVM implementation.
      Description: Transport protocol implementation used for communication between debugger and application. Sun JVM ships two implementations, Socket Transport and Shared Memory Transport. Value for Socket Transport is “dt_socket”, while that of Shared Memory Transport is “dt_shmem”.
      Shared Memory is available only on Microsoft Windows.
    • Name: serverIs Optional: Yes
      Default Value: n
      Description: Tells whether JVM will be used as Server or as client in reference to JVM-Debugger communication. If JVM will act as server, then debugger will attach itself to this JVM, otherwise if JVM will act as a client, then it will attach itself to debugger.
    • Name: addressIs Optional: Optional when JVM acts as server and Required when JVM acts as client.
      Description: Specifies the socket address.
      If JVM is server (i.e. server argument is set to ‘y’): Then JVM listens the debugger at this socket. If address is not specified, then JVM picks any of available socket, starts listening on this socket and prints its address on console.
      If JVM is client (i.e. server argument is set to ‘n’): JVM attaches itself to this address to connect itself to debugger.
    • Name: timeoutIs Optional: Yes
      Description: As its name signifies, it is the wait time for JVM. If JVM is server, then JVM will wait for “timeout” amount of time for debugger to attach to its socket and if JVM is client, then it will exit if fail to attach to debugger in timeout time.
    • Name: suspendIs Optional: yes
      Default Value: y
      Description: Tells JVM to suspend the invocation of application(s) until the debugger and JVM are attached together.

    Apart these there are launch, onthrow, onuncaught options as well, details of which can be find at JPDA. But these options are seldom used.

    Now, lets take simple example to debug a program using eclipse.

    Steps

    • Select from eclipse menu, Run->Debug Configuration, It will open Debug Configuration setup.
    • On Debug configuration window, create a new “Remote Java Application” configuration.
    • Select the project to be debugged and provide a Name.
    • Select connection type, Socket Attach or Socket Listen. Select Socket Attach, if you want to attach the debugger to application, i.e. application is running in Server mode. On the other hand, select Socket Listen, in case you want debugger to listen for JVM to connect, i.e. JVM is running in client mode and debugger is running as server.
    • If JVM to be run in Server mode, then first start JVM in debug mode and then start the newly created debugger,
    • And if Debugger to be run in Server mode, then first start the debugger and then start JVM.

    Debugging in Action

    In this way one can debug any java application using any standard java debugger.

    Читать еще:  Integer compare java
Ссылка на основную публикацию
Adblock
detector