Header Ads Widget

Responsive Advertisement

Hot Swap tool understanding

Java Debugging Options

Running a Java program with the -Xdebug and -Xrunjdwp options enables remote debugging capabilities. Here's a breakdown of the command you provided:

bash

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y Test

 

  • -Xdebug: This option is deprecated and no longer required in newer versions of Java (since Java 5). The debug options are configured via the -Xrunjdwp argument.
  • -Xrunjdwp: This argument configures the Java Debug Wire Protocol (JDWP).
    • transport=dt_socket: Specifies the transport mechanism (socket-based communication).
    • address=8787: Specifies the port number for the debugger to attach.
    • server=y: Indicates that the JVM should act as a debug server, waiting for a debugger to attach.
    • suspend=y: Causes the JVM to pause execution until a debugger attaches. This is useful for ensuring that you don't miss any early breakpoints.

This setup is useful for debugging applications running in different environments, such as development, testing, or even production, with caution.

Java Debugger (jdb)

Features:

  1. Command-Line Interface:
    • jdb is a command-line tool that provides basic debugging capabilities.
  2. Breakpoint Management:
    • You can set, clear, and list breakpoints in your code.
  3. Step Execution:
    • You can step through code line by line, step into methods, and step out of methods.
  4. Variable Inspection:
    • You can inspect variables, evaluate expressions, and monitor changes in variable values.
  5. Thread Management:
    • You can list threads, inspect their states, and control their execution.

Basic Usage:

  1. Starting jdb:
    • Attach jdb to a running JVM:

bash

jdb -attach 8787

 

  1. Setting Breakpoints:
    • Set a breakpoint at the beginning of a method:

jdb

stop in com.example.MyClass.myMethod

 

  1. Running and Controlling Execution:
    • Continue execution until the next breakpoint:

jdb

cont

 

    • Step to the next line:

jdb

step

 

  1. Inspecting Variables:
    • Print the value of a variable:

jdb

print myVariable

 

  1. Thread Management:
    • List all threads:

jdb

threads

 

Drawbacks:

  1. Limited Features:
    • Compared to modern IDEs, jdb lacks advanced debugging features such as visual breakpoints, integrated variable inspection [Simple variable, Existing static variable with-out changes, Existing method change business logic, Existing static method change business logic, Existing inner class changes business logic, Existing inner class business logic], and memory analysis tools.
    • Drawback: which is integrated variable inspection not support [Existing static variable with value changes, new method adds, New static method, add new Enum, existing new enum change business value, add inner class, add new class]
  2. Steep Learning Curve:
    • Command-line debugging can be cumbersome and requires familiarity with jdb commands.
  3. Manual Effort:
    • Managing breakpoints, stepping through code, and inspecting variables is more labor-intensive without the convenience of a graphical interface.
  4. Usability:
    • For large-scale applications, debugging with jdb can be less efficient and more error-prone.

Modern Alternatives

Modern Integrated Development Environments (IDEs) like IntelliJ IDEA, Eclipse, and NetBeans offer robust debugging tools with graphical interfaces that overcome the limitations of jdb:

  • Breakpoints: Set and manage breakpoints visually.
  • Step Execution: Step through code with buttons and keyboard shortcuts.
  • Variable Inspection: Hover over variables to inspect their values and see evaluations.
  • Thread Management: Manage and inspect threads with an intuitive interface.
  • Advanced Features: Memory analysis, performance profiling, and other tools are integrated into the IDE.

New tools how to run:

·       Create A Project give the example hotswaptool

              Add two jar file hotswaptool

                   bcel-5.2.jar (this should be download from google)

                   tools.jar (this is coming from your jdk path like D:\Software\java\jdk1.8.0_05\lib)

·       Copy the below code and add in your source directory.

·       Run this program in java application

·       see the open window.

·       Now java hotswaptool is ready

·       Enabling the Debug Mode in your remote machine project where you put the hot .class file

·       To run a regular serverless Java class Test with debugging enabled in the Oracle HotSpot JVM, you need to use the following command:

 

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y Test

·       Start the server and call api.

·       If you need any business changes .class file in remote machine without restart your server goto below step

·       Go to your local machine and change the business logic and compile

·       Run the hot swap tool

·       Give the remote machine IP address

·       Give the remote machine debug port number like 8787

·       Browse the .class file from your local

·       Click the hotswap

·       Done

·       Again call api see the result it will effected

 

Java

package com.kartik.org;

 

import javax.swing.JFrame;

/**

 *

 * @author kmandal

 *

 */

public class SwapDemo {

 public static void main(String[] a) {

  Swap frame = new Swap();

  frame.setTitle("Hot Swap Tool");

  frame.setVisible(true);

  frame.setBounds(10, 10, 500, 500);

  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  frame.setResizable(false);

  frame.setLocationRelativeTo(null);

 }

 

}

 

Java

package com.kartik.org;

 

import java.awt.Container;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.FocusEvent;

import java.awt.event.FocusListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.File;

import java.io.IOException;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JTextField;

import javax.swing.SwingUtilities;

 

import org.apache.bcel.classfile.ClassParser;

import org.apache.bcel.classfile.JavaClass;

 

/**

 *

 * @author kmandal

 *

 */

public class Swap extends JFrame implements ActionListener,Runnable {

 private static final long serialVersionUID = 1L;

 private String ipAddress;

 private String portNumber;

 private String absoulatePath;

 private String realPath;

 private File file;

 

    public String getIpAddress() {

  return ipAddress;

 }

 public void setIpAddress(String ipAddress) {

  this.ipAddress = ipAddress;

 }

 public String getPortNumber() {

  return portNumber;

 }

 public void setPortNumber(String portNumber) {

  this.portNumber = portNumber;

 }

 public String getAbsoulatePath() {

  return absoulatePath;

 }

 public void setAbsoulatePath(String absoulatePath) {

  this.absoulatePath = absoulatePath;

 }

 public String getRealPath() {

  return realPath;

 }

 public void setRealPath(String realPath) {

  this.realPath = realPath;

 }

 public File getFile() {

  return file;

 }

 public void setFile(File file) {

  this.file = file;

 }

 

 

 

 

 Container container=getContentPane();

    //JPanel panel = new JPanel(new GridLayout(0, 1));

 

 JButton headerLabel=new JButton("Swap Tool ");

 

 

 

    JLabel ipLabel=new JLabel("Ip Address: *");

    JLabel portNoLabel=new JLabel("Port number: *");

    JLabel fileChooseLabel=new JLabel("Choose File: *");

   

   

    JTextField ipTextField=new JTextField();

    JTextField portTextField=new JTextField();

    JTextField fileName = new JTextField();

 

    JButton browse = new JButton("Browse");

    JButton loginButton=new JButton("Swap File");

    JButton resetButton=new JButton("Re-set");

 

 

    Swap()

    {

       //Calling methods inside constructor.

        setLayoutManager();

        setLocationAndSize();

        addComponentsToContainer();

 

    }

   public void setLayoutManager()

   {

       container.setLayout(null);

   }

   public void setLocationAndSize()

   {

    headerLabel.setBounds(50,100,430,30);

    headerLabel.setOpaque(true);

   // headerLabel.setBackground(Color.GREEN);

       //Setting location and Size of each components using setBounds() method.

       ipLabel.setBounds(50,150,100,20);

       portNoLabel.setBounds(50,200,100,20);

       fileChooseLabel.setBounds(50,250,100,20);

      

       ipTextField.setBounds(150,150,200,20);

       portTextField.setBounds(150,200,100,20);

       fileName.setEditable(false);

       fileName.setBounds(150,250,220,20);

      

       browse.setBounds(380,250,100,20);

       loginButton.setBounds(50,300,100,25);

       resetButton.setBounds(200,300,100,25);

 

 

   }

   public void addComponentsToContainer()

   {

    container.add(headerLabel);

      //Adding each components to the Container

       container.add(ipLabel);

       container.add(portNoLabel);

       container.add(fileChooseLabel);

      

       ipTextField.addFocusListener(new FocusListener() {

   public void focusLost(FocusEvent fe) {

    setIpAddress(ipTextField.getText());

   }

   public void focusGained(FocusEvent fe) {

 

   }

  });

 

       ipTextField.addKeyListener(new KeyAdapter() {

   public void keyTyped(KeyEvent e) {

    if (ipTextField.getText().length() >= 50)

     e.consume();

   }

  });

      

       container.add(ipTextField);

      

      

       portTextField.addFocusListener(new FocusListener() {

   public void focusLost(FocusEvent fe) {

    setPortNumber(portTextField.getText());

   }

   public void focusGained(FocusEvent fe) {

   }

  });

 

       portTextField.addKeyListener(new KeyAdapter() {

   public void keyTyped(KeyEvent e) {

    char letter = e.getKeyChar();

    if (portTextField.getText().length() >= 15) {

     e.consume();

    } else if (!Character.isDigit(letter)) {

     e.consume();

    }

   }

  });

      

       container.add(portTextField);

      

       container.add(fileName);

       browse.addMouseListener(new MouseAdapter() {

   public void mouseClicked(MouseEvent evt) {

    if (SwingUtilities.isLeftMouseButton(evt)) {

     Chooser frame = new Chooser();

     fileName.setText(frame.fileName);

     setRealPath(frame.fileName);

     setFile(frame.file);

    }

   }

  });

      

       container.add(browse);

      

       loginButton.addMouseListener(new MouseAdapter() {

   public void mouseClicked(MouseEvent evt) {

    if (SwingUtilities.isLeftMouseButton(evt)) {

     boolean flag=validation();

     if(flag){

      /*Thread swapThread = new Thread();

            swapThread.start();

            try {

             System.out.println("Start the First Sleep");

             Thread.sleep(5000);

             System.out.println("Start the hot swap");*/

             hotSwap();

             /*System.out.println("Start the Second Sleep");

                Thread.sleep(5000);

                System.out.println("End the sleep");

            } catch (InterruptedException e) {

                e.printStackTrace();

            }*/

    

     }

    }

   }

  });

       container.add(loginButton);

      

       container.add(resetButton);

   }

 

  

   /**

  *

  * @param fullStr

  * @return

  */

 private void hotSwap() {

  StringBuffer br = new StringBuffer();

  generateComand(br);

  String command = br.toString();

  System.out.println(command);

  StringBuffer br2 = new StringBuffer();

 

  String packageName = null;

  File f = getFile();

  String aa = f.getName();

  String[] arrOfStr = aa.split("\\.", -1);

 

  String filePath = filePathMethod(getRealPath());

  if (f.exists()) {

 

   ClassParser classParser = null;

   try {

    classParser = new ClassParser(filePath);

   } catch (IOException e) {

    e.printStackTrace();

   }

 

   JavaClass javaClass = null;

   try {

    javaClass = classParser.parse();

   } catch (IOException ioe) {

    System.out.println(filePath);

   }

 

   packageName = javaClass.getPackageName();

   writeMethodInCommand(br2, packageName, arrOfStr, filePath);

   HotSwap h = new HotSwap();

   boolean isRunning = h.isProcessRunning(command,

     br2.toString());

   String processName = "java.exe";

   if (isRunning) {

    h.killProcess(processName);

   } else {

    System.out.println("Not able to find the process : "

      + processName);

   }

  } else {

   System.out.println("\nFile Path not exist ");

  }

 }

 

 /**

  * This is find out the absoluteFilePath of a file for any server

  *

  * @param fileName

  *            fileName

  * @param pathName

  *            pathName

  * @return absoluteFilePath

  */

 public String filePathMethod(String pathName) {

  String absoluteFilePath = "";

  // String workingDir = System.getProperty("user.dir");

  String runnigServerOs = System.getProperty("os.name").toLowerCase();

  if (runnigServerOs.indexOf("win") >= 0) {

   // if windows

   absoluteFilePath = pathName.replaceAll("\\\\", "\\\\\\\\");

  } else if (runnigServerOs.indexOf("nix") >= 0

    || runnigServerOs.indexOf("nux") >= 0

    || runnigServerOs.indexOf("mac") >= 0) {

   // if unix or mac

   // absoluteFilePath = workingDir + "/" + fileName;

   absoluteFilePath = pathName;

  } else {

   // unknow os?

   // absoluteFilePath = workingDir + "/" + fileName;

   absoluteFilePath = pathName;

  }

  System.out.println("Final filepath : " + absoluteFilePath);

  return absoluteFilePath;

 }

 

 /**

  *

  * @param br

  */

 private void generateComand(StringBuffer br) {

  br.append("jdb -connect com.sun.jdi.SocketAttach:hostname=");

  br.append(getIpAddress());

  br.append(",port=");

  br.append(getPortNumber());

 }

 /**

  *

  * @param br2

  * @param packageName

  * @param arrOfStr

  * @param filePath

  */

 private void writeMethodInCommand(StringBuffer br2,

   String packageName, String[] arrOfStr, String filePath) {

  br2.append("redefine");

  br2.append(" ");

  br2.append(packageName);

  br2.append(".");

  br2.append(arrOfStr[0]);

  br2.append(" ");

  br2.append(filePath);

 }

 

  

  

 

    @Override

    public void actionPerformed(ActionEvent e) {

    }

   

   

    public boolean validation() {

 

     if(getIpAddress().equals(""))

     {

      String message = "Please enter ip address properly\n";

          JOptionPane.showMessageDialog(container, message, "Dialog",

              JOptionPane.ERROR_MESSAGE);

          return false;

     }

     else if(getPortNumber().equals(""))

     {

      String message = "Please enter port number\n";

      JOptionPane.showMessageDialog(container, message, "Dialog",

          JOptionPane.ERROR_MESSAGE);

      return false;

     }

     else if(Integer.parseInt(getPortNumber())<=0)

     {

      String message = "Please enter port number\n";

      JOptionPane.showMessageDialog(container, message, "Dialog",

          JOptionPane.ERROR_MESSAGE);

      return false;

     }

     else if(getFile().equals(""))

     {

      String message = "Please enter file which you need to swap \n";

      JOptionPane.showMessageDialog(container, message, "Dialog",

          JOptionPane.ERROR_MESSAGE);

      return false;

     }

  return true;

    }

 @Override

 public void run() {

  // TODO Auto-generated method stub

 

 }

}

 

 

 

Java

package com.kartik.org;

 

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

 

public class HotSwap {

 

 

 public boolean isProcessRunning(String command,String write) {

  boolean flag=false;

    try {

        /* String array to execute commands */

        String[] commands = new String[3];

        commands[0] = "cmd";

        commands[1] = "/c";

        /* Command you want to execute */

       // command[2] = "jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.211.180,port=8999";

        //commands[2] = "jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.57.66,port=8999";

        commands[2] = command;

        /* Create process */

        Process p = Runtime.getRuntime().exec(commands);

 

        /* Get OuputStream */

        PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true);

       

        /* Read the output of command prompt */

        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        String line = reader.readLine();

        /* Read upto end of execution */

        int count=0;

        while (line != null) {

            /* Pass the value to command prompt/user input */

           // writer.println("redefine com.journaldev.spring.PersonController  D:\\Kartik\\Karthik\\Spring-Boot-REST\\target\\classes\\com\\journaldev\\spring\\PersonController.class");

            writer.println(write);

            System.out.println(line);

            if(count>=2){

             return true;

            }else{

            line = reader.readLine();

            }

            count=count+1;

           

        }

        /* The stream obtains data from the standard output stream of the process represented by this Process object. */

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

        /* The stream obtains data from the error output stream of the process represented by this Process object. */

        BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

       

        String Input;

        while ((Input = stdInput.readLine()) != null) {

            System.out.println(Input);

        }           

       

        String Error;

        while ((Error = stdError.readLine()) != null) {

            System.out.println(Error);

        }

       

    } catch (Exception e) {

        e.printStackTrace();

    }

 

 return flag;

}

 

 private static final String KILL = "TASKKILL /F /IM ";

 

 public void killProcess(String serviceName) {

  try {

   Runtime.getRuntime().exec(KILL + serviceName);

   System.out.println(serviceName+" killed successfully!");

   System.exit(0);

  } catch (IOException e) {

   e.printStackTrace();

  }

 

 }

}

 

Java

package com.kartik.org;

 

import java.io.File;

 

import javax.swing.JFileChooser;

import javax.swing.JFrame;

/**

 *

 * @author kmandal

 *

 */

public class Chooser extends JFrame {

 

 private static final long serialVersionUID = 1L;

 public JFileChooser chooser;

 public String fileName;

 public File file;

 

 public Chooser() {

  chooser = new JFileChooser();

  int r = chooser.showOpenDialog(new JFrame());

  if (r == JFileChooser.APPROVE_OPTION) {

   fileName = chooser.getSelectedFile().getPath();

   file = chooser.getSelectedFile();

 

  }

 }

}

 

Conclusion

While jdb provides essential debugging capabilities, its command-line interface and limited features can make it less efficient for complex debugging tasks compared to modern IDEs. However, it remains a useful tool for remote debugging and scenarios where an IDE is not available.

 

 

 

Hot Swap tool
Hot Swap tool






Post a Comment

0 Comments