Monday, November 10, 2008

My synergy settings

I have multiple laptops and computers, and sometimes use them at the same time - it is convenient to use a single keyboard
and mouse. The problem is that the config is not fixed - and synergy is quite hard to reconfigure dynamically.

I start a synergys server on each computer whose keyboard I may use, and use a couple of scripts to create tunnels and
restart the clients.

The trick is to not use specific hostnames - but dummy ones, and explicitly set the "-c clientname" param. Then all real
config is done using ssh tunnels - with the extra benefit of

  synergys -n localhost -a

  # optional: ssh to shared server ( if the keyboard host is behind another firewall ):
  ssh -f -N -R 24800:  public_computer_with_sshd

Server config: ~/.synergy.conf

section: screens<br />      localhost:<br />      up:<br />      down:<br />      left:<br />      right:<br />end<br /><br />section: links<br />      localhost:<br />        down = down<br />        up = up<br />        left = left<br />        right = right<br />     up:<br />        down = localhost<br />     down:<br />       up = localhost<br />     left:<br />       right = localhost<br />     right:<br />       left = localhost<br />end<br /><br /><br />
On client:
   ssh -N 24800: server &
   echo $! > ~/  

   killall -9 synergyc
   synergyc -n down localhost

I have few client scripts, pointing to different keyboard servers and layouts.

Thursday, August 14, 2008

Intercepting SIGTERM

The 'proper' way to terminate a java process on unix is by sending SIGTERM, waiting a bit, and then sending SIGKILL. This gives java a chance to clean - using Runtime.getRuntime().getShutdownHook().

If you want to intercept this and do some early cleanup, before letting the others do theirs you need to use sun.misc.Signal - which can also be used to intercept other signals.

Things to do in a shutdownHook ? Flush the logs, finish important background processes and much more.

Code to intercept the signal:

oldSigTERM = Signal.handle(new Signal("TERM"),
new SignalHandler() {
public void handle(Signal signal) {
System.err.println("Quit using SIGTERM hook");
if (oldSigTERM != null) {

Thursday, March 20, 2008

Using FutureTask

This is what I typically use to convert a sync method to a background Future. The benefit is that it avoids a lot of custom code (creating threads, locks, etc ) and seems simple enough, and it's relatively easy to cut&paste.


Result1 slowMethod1(Param1 p1, Param2 p2) throws Exception1 {
Result2 slowMethod2() throws Exception2 {

void caller() throws Exception1, Exception2 {
// slowMethod1 and slowMethod2 are independent of each other
Result1 r1 = slowMethod1(p1, p2); // first expensive operation
Result2 r2 = slowMethod2(); // other slow method, not using the result or side-effects of the first

New code:

Executor bgTasks = Executors.newCachedThreadPool();

Future slowMethod1Future(final Param1 p1, Param2 p2) {
FutureTask fr = new FutureTask(new Callable() {
public Result1 call() {
return slowMethod1(p1, p2);
return fr;

void caller() {
Future fr = slowMethod1Future(p1, p2);
Result2 r2 = slowMethod2();
try {
Result1 r1 = fr.get();
} catch(InterruptedException e) {
throw new RuntimeException(...);
} catch (ExecutionException e) {
Throwable t = e.getCause();
if (t intanceof Exception1) {
throw (Exception1) t;
} else {
throw new RuntimeException(t);

Wednesday, February 27, 2008

JConsole in local mode and tomcat

After some debugging found that Jconsole will connect locally to a new MBeanServer created via ManagementFactory.getPlatformMBeanServer(). Tomcat will look for an existing MBeanServer and create one if needed - but this will be different than what jconsole uses.

The fix is 2 lines - benefit is that you can start tomcat normally, without any special flag, then connect with jconsole and inspect/modify settings. It looks like they use some signal or other form of communication on Linux, which opens a TCP port.

I'm not sure why someone would ever want to use MBeanServerFactory.findMBeanServer() and createMBeanServer. Sure, in the rarely used sandbox mode, if you want to strongly isolate apps it may be needed - assuming you want each untrusted app to have access to its own server, and grant it create mbean server rights.

Time to send a patch - long time since I haven't done that...