Monday, August 27, 2012

Recover Eclipse from Crash on Ubuntu

Motivation: Sometimes, Eclipse on Ubuntu (specifically, 11.10) hangs beyond recovery. It eventually crashes or I have to kill -9 it. When, I start it again, the splash screen gets stuck at about 70%.

The only solution till now was to create a new workspace which leads to reconfiguring the plugins, downloading code from repository -- a complete waste of time.

Requisites: Access to corrupted workspace directory.

Steps: Since changing workspace fixed the problem. I knew that something has got corrupted in the workspace. With a little poking around in $WORKSPACE/.metadata, I came to realize that at least one plugin's (with .ui in its name) metadata has gone bad. So, I started hit and trial by moving files from $WORKSPACE/.metadata/.plugins to another location and starting Eclipse. (starting Eclipse causes recreation of the moved plugin metadata file).

Long story short,
  1. look into Eclipse log file in the workspace, find out which plugin is doing the mischief.
  2. Delete/move the corresponding file from $WORKSPACE/.metadata/.plugins directory.
Most likely, you will hit the same plugin as mine, so likely you will have to just delete the org.eclipse.ui.workbench and org.eclipse.ui.ide from $WORKSPACE/.metadata/.plugins. And start Eclipse.

Hope this helps. 

Wednesday, August 15, 2012

Remote Debug Your Application in Jetty on Remote Machine

Motivation: Something weird happened today, I was asked to setup remote debug mechanism on our test server so that developers can step through code in their machine while execution takes place on test environment sitting in other city.

I never imagined need of remote debug to actually debug a code on remote machine.

Prerequisite: 
  1. Standalone Jetty installation
  2. Eclipse (or your favorite Java IDE that has remote debug facility)
Steps: $JETTY_HOME denotes the directory where Jetty is installed/copied/extracted.

Edit ini file: Open $JETTY_HOME/start.ini file in your favorite text editor. uncomment --exec and after that add the debug setup. Here is a snippet of that file:
--exec
-Xmx1194m
-Xmn256m
-Xdebug
-Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n
# -verbose:gc
Uncommenting --exec basically makes content of this file gets passed as VM parameters when Jetty is launched. Which is nothing special -- in bare minimum form this is what gets executed:
java -Xdebug -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n -jar start.jar

Start Jetty as usual: start Jetty by $JETTY_HOME/bin/jetty.sh start

How do I confirm if these parameters are passed? If you are on Unix, just run ps -ef | grep  -v grep | grep jetty, you will see long description with the parameters above in it:
root     30320 30308  0 17:53 pts/0    00:00:07 /usr/java/jdk1.6.0_30/jre/bin/java -Xmx1194m -Xmn256m \
-Xdebug -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n \
 -Djetty.home=/opt/apps/jetty-hightide-7.5.0.v20110901 -cp \
/opt/apps/jetty-hightide-7.5.0.v20110901/lib/jetty-xml-7.5.0.v20110901.jar: \
/opt/apps/jetty-hightide-7.5.0.v20110901/lib/servlet-api-2.5.jar: \
/opt/apps/jetty-hightide-7.5.0.v20110901/lib/jetty-http-7.5.0.v20110901.jar:
...
Connecting to Remote Debugger: In Eclipse, go to Run > Debug Configurations... menu. Double click Remote Java Application, give an appropriate name, link to relevant project, provide the host-name, mention the port that you have started your remote debugger on. So, from step#1, in my case this will be 4000.

Here is the screen shot:

Apply and start debugging.

A word about firewall: Since it makes TCP connection to your Jetty make sure, you have debug port -- 4000, open on the host machine. In AWS EC2, you can allow port 4000 in your security group.

Friday, August 3, 2012

Running Shell Script on Remote Machine

Motivation: Most of the time running a command or a group of commands on a remote machine is a thoughtless process -- ssh username@remoteIP.or.dns "command1 param1 param2; command2 param3;". What throws you out is when you have 40 lines of convoluted script to be run on 37 machines! You won't use this approach. You'd probably scp the script to remote machine and then call it using ssh as mentioned earlier, and then probably delete this file. It's three step process. If you haven't automated stuff, it's a pain.

A better way is to automate this process and do it in a single connection.

Prerequisites:
  1. Executable access to the remote machine.
  2. Some knowledge of shell script.
Steps: It's just one line command. I will write the breakdown.
  1. Keep the shell script that you wanted to execute remotely, on your local machine. cat this file.
  2. The cated file is piped to ssh command that...
  3. Writes this file to a location of your choice on remote machine, say /tmp/remote.sh  and...
  4. Changes mode chmod to executable then...
  5. Calls this script with parameters, if any, and finally...
  6. Deletes this file from remote location. 
The most interesting part is that all this is done in a single connection. Here is the code. The \ is continue command to next line. You may want to keep the whole command in a single line.

cat runremote.sh | ssh -i /home/naishe/.keys/remotekey.pem \
root@server1.naishe.in "cat > /tmp/remote.sh ; chmod 755 /tmp/remote.sh ; \
/tmp/remote.sh param1 param2 ; rm -f /tp/remote.sh " 

You see, it's pretty simple.