Hot Swap tool understanding





Step 1>Create A Project give the example hotswaptool
 Add two jar file hotswaptool 
  1>bcel-5.2.jar (this should be download from google)
  2>tools.jar (this is coming from your jdk path like D:\Software\java\jdk1.8.0_05\lib)
Step 2>Copy the below code and add in your source directory.
Step 3>Run this program in java application
Step 4>see the open window.
Step 5>Now java hotswaptool is ready
Step 6>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
Step 7>Start the server and call api.
Step 8>If you need any business changes .class file in remote machine without restart your server goto below step
 Step 1>Go to your local machine and change the business logic and compile 
 Step 2>Run the hot swap tool 
 step 3>give the remote machine IP address
 step 4>give the remote machine debug port number like 8787
 Step 5>browse the .class file from your local
 Step 6>Click the hotswap 
 Step 7>Done
 Step 8>again call api see the result it will effected 
Step 9>Draw back of the jdb.
    Which is working 
   1>Simple variable          --working
   2>Existing static variable with out changes   --working
   3>Existing method change business logic   --working
   4>Existing static method change business logic  --working
   5>Existing inner class changes business logic   --working
   6>Existing inner class business logic    --working
 
 Which is not working
  1>Existing static variable with value changes   --Not working
  2>new method add      --Not working
  3>New static method     --Not working
  4>add new Enum       --Not working
  5>existing new enum change business value  --Not working
  6>add inner class      --Not working
  7>add new class      --Not working
Step 10>Suggestion from my understanding
        1>Please add all  .java a default serialization id. for avoid the compiler to compiler no new serialization id createion.
  
Step 11>Thanks for your time spent :)
For more understanding : click




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);
 }

}



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
  
 }
}
 






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();
  }

 }
}





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();

  }
 }
}





       








Previous
Next Post »