Using synergy as a pure KVM solution

I have often used Synergy as a solution to extend my mouse and keyboard input to multiple computers at the same time. At this time however I want to present a solution to using Synergy as a pure KVM ( well, KM to be pedantic ) switch, which means changing input on -demand from one computer to another.

My need was driven by the fact that I often use one desktop, one laptop and one monitor. The desktop and the laptop are connected simultaneously to the monitor, and I can quickly switch between them. The keyboard and mouse however need to be physically moved between machines. I’ve tried a physical KVM solution, but it caused erratic behaviour in my keyboard, so I looked for something else.

As in the classic synergy setup, there will be one client, and one server. The server will be the computer in which the keyboard and mouse are plugged in. To start off, we define the screens section, where the two computers are listed. For simplicity, we’ll call them server and client.

section: screens
    server:
    client:
end

Next up, we define a options section, which maps keystroke combinations to switching to certain screens. I chose something unlikely to be used like Super+Alt+<NUMBER>, but you can change this as you see fit.

section: options
    keystroke(Super+alt+1) = switchToScreen(server)
    keystroke(Super+alt+2) = switchToScreen(client)
end

Another point to note is that there is no links section, which means that synergy will not try to transfer input between screens, which does not make sense in a pure KVM setup where we want on-demand switching only.

With this configuration, synergy works beautifully as a KVM switch. Something to be aware of is that in my experience quick strokes for the hotkeys were not recognized, so you might need to type a bit slower to help synergy recognize the switch.

Advertisements

A cautionary tale on thread locals, pooling and reflection

Most non-trivial Java applications use thread pools to improve performance by avoiding thread creation and optionally by limiting the maximum numbers of threads in use.

The end goal is for each task to execute in a dedicated thread, without it being aware that the thread is not a fresh one, but was used before. Starting with Java 5 the Java runtime libraries offer a wealth of options for creating thread pools in the java.util.concurrent package.

So far, all is well – we have a simple, robust way of adding thread pooling to our application. That is, unless we are running code which is out of our control and is misbehaving. One kind of particularly subtle misbehaviour is using ThreadLocal storage and never cleaning that up. If you’re not familiar with thread-local storage in Java, this kind of access allows each thread to store its own value for a certain variable. The example below comes straight from the javadoc.

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {
  // Atomic integer containing the next thread ID to be assigned
  private static final AtomicInteger nextId = new AtomicInteger(0);

  // Thread local variable containing each thread's ID
  private static final ThreadLocal threadId =
    new ThreadLocal() {
      @Override protected Integer initialValue() {
        return nextId.getAndIncrement();
      }
    };

  // Returns the current thread's unique ID, assigning it if necessary
  public static int get() {
    return threadId.get();
   }
 }

This kind of usage is fine when working on new threads each time, but when threads are reused as part of a thread pool, all thread local storage must be cleaned up. Failing to do so has the potential to trigger hard-to-find memory leaks. A quick google search on thread local memory leak brings up enough examples to make us wary of leaving dangling ThreadLocal instances behind.

For application code, it’s critical to use ThreadLocal#remove when a value is no longer needed, to make sure there are no leaks.

For infrastructure code providing the thread pool, an added safety is the ability to warn and recover from misbehaving application behaviour.

Apache Tomcat does so by logging warnings when applications leave behind ThreadLocal values, and extensively document it via their MemoryLeakProtection wiki page .

In Apache Sling, as web application framework, we aim to be as robust as possible by preventing any memory leaks due to leftover thread-local storage. To that end, we recycled threads by throwing an exception in the thread pool’s afterExecute method when the thread was too old.  You can see the details in our ThreadExpiringThreadPool, but the gist of it is

public class ExpiringThreadPool extends ThreadPoolExecutor {
  @Override
  protected void afterExecute(Runnable r, Throwable t) {
    super.afterExecute(r, t);
    if ( isExpired(t) ) {
      throw new RuntimeException("Expired");
    }
  }
}

There are some tricks that you can use to make sure the exception is not logged, but the details are in the Sling code linked above.

However, we found this to not be good enough. The reasons are two:

  1. By throwing away threads we partially negate the performance advantages of thread pools
  2. It made debugging hard as the Eclipse debugger halted whenever such an exception was thrown

So we set out to finder a better way of ensuring thread-local storage is cleaned up between threads. We found some ideas on the JavaSpecialists article on cleaning thread locals , which presented a reflection-based solution. The article shows how you can access the references stores in a ThreadLocalMap and save/restore then whenever a taks starts and ends execution. This way, each starting task gets a fresh set of values and also preserves the values it received when being created. A simplified version of the code is

public class CleaningThreadPool extends ThreadPoolExecutor {

  @Override
  protected void beforeExecute(Thread t, Runnable r) {
    super.beforeExecute(t, r);

    Object threadLocals = threadLocalsField.get(t);
    if (threadLocals == null)
      return null;
    Reference[] table = (Reference[]) tableField.get(threadLocals);
    save(t, table);
  }

  @Override
  protected void afterExecute(Runnable r, Throwable t) {

    Reference[] table = load(Thread.currentThread());
    tableField.set(threadLocalsField.get(t), table);

    super.afterExecute(r, t);
  }
}

We pushed this code but discovered that under certain conditions application threads would lock, with a very implausible stack trace:

"pool-1-thread-1" prio=10 tid=0x00007f47f4374800 nid=0xb19 runnable [0x00007f47e734e000]
 java.lang.Thread.State: RUNNABLE
   at java.lang.ThreadLocal$ThreadLocalMap.set(ThreadLocal.java:429)
   at java.lang.ThreadLocal$ThreadLocalMap.access$100(ThreadLocal.java:261)
   at java.lang.ThreadLocal.set(ThreadLocal.java:183)
   at org.apache.sling.commons.threads.impl.ThreadPoolExecutorCleaningThreadLocalsTest$RunnableImplementation.run(ThreadPoolExecutorCleaningThreadLocalsTest.java:100)
   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
   at java.util.concurrent.FutureTask.run(FutureTask.java:262)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
   at java.lang.Thread.run(Thread.java:745)

An infinite loop in thread-local storage is quite unplausible, and furthermore others should have reported it as well. All things pointed to our implementation, but we did not yet find the fault. To do so, we need to dig in to the ThreadLocal storage implementation.

In the Java standard libraries I’ve studied, thread-local storage is implemented by the ThreadLocalMap inner class. This map is the one we’re altering using reflection, and it is backed by an array of Entry objects named table. Whenever an entry is added or removed the table array is altered. However, what we missed is that there are two more fields that are linked with the table – size and threshold. The size represents the number of entries – non-null values of the table – and the threshold is the next size value which will trigger a resize.

What went wrong with our implementation is that we ignored these fields and instead only saved/restored the table array. Where this went wrong was the following scenario:

  1. Thread A is created
  2. Task 1 is executed, sets thread-local values but does not clean them up. It adds more than the initial capacity of the table, so it forces a resize
  3. Task 1 is executed and attempts to set new thread-local variables. Since the table is full ( no more non-null entries ) but the size and threshold are the default ones the setter methods loop infinitely trying to find an empty slot

Once we realized the issue we fixed it quickly and added a test for it ( link to the commit for the curious ) but discovering it was quite a trip.

With all this behind us, there are some personal takeaways for me

  1.  Keep away from thread-local storage. There is almost always a better solution, and thread-locals should be last resort. If you do use thread locals, make sure you clean them up when done
  2. Accessing private data via reflection is tricky and if not done carefully can lead to invariants being broken and seemingly impossible situations.

As final references, our thread pool implemention can be found on GitHub: ThreadPoolExecutorCleaningThreadLocals , and more information about Sling is on the Apache Sling website.

 

Mylyn-Mantis connector 3.11.0 released

It’s been a long time since I’ve pushed a release of the Mantis connector for Eclipse. I’m happy to say that I’ve gathered some fixes and a new release is now out.

This was mostly prompted by the MantisBT 2.0 release, which needed a small change in the plug-in to work as intended.

The full list of changes is below

  • Consider all versions older than 2.0 as valid
  • Add support for MantisBT 2.0
  • Add support for MantisBT version 2.0
  • Current version 3.10.1 cannot be installed with Eclipse Mars (4.5) Build id: 20150621-1200
  • Remove references to JBoss Tools from the update site
  • Investigate implementing new repository validation API for Mylyn >= 3.11

Another issue worth mentioning is that starting with this release you’ll see this warning dialog before completing the installation

mylyn-mantis-unsigned-content

Since I am no longer able to use a code signing certificate the plug-ins are not signed anymore. But that will not impact your experience besides this dialog.

As always, upgrade, have fun, and let me know if any issues appear via the user’s forum or by reporting bugs.

Going to talk about Sling IDE Tooling at adaptTo 2014

I’m happy to say that in September I’ll be going back to Berlin for adaptTo 2014 . adaptTo is a conference which gathers developers from the Apache Sling and friends community.

I’m going to talk about the progress that we’ve made the last year with the Sling IDE Tooling and show how quickly you can develop Sling-based applications. Whether you’re working with OSGi bundles, frontend files, backend scripts or unstructured content, we have something to make you more productive.

I hope I’ll see you at adaptTo in Berlin this September.

Announcing Desktop Notifier for Maven 1.0

We all know that builds are supposed to be fast. Otherwise, we just end up swordfighting. But sometimes the build just takes too long, either because you have an empty ~/.m2/repository, or the integration tests take a lot of time to run, or … . But you get the point.

For this very reason I ( as the saying goes, with a little help from my friends ) built a Maven extension which shows desktop notifications whenever a build is complete. It’s smart enough to notify you at the end of the reactor build for multi-module projects and it distinguishes between success and failure.

The notifier support Linux, OS X and Windows with specific notification senders, with a fallback on the AWT APIs whenever we do not find a preferred sender.

The 1.0 version is available for download in the Github downloads area. To install it, just drop the jar file under lib/ext in your Maven installation.

Apache Sling: viewing bundles by start level

When packaging an Apache Sling application it is useful to see the final list of bundles included in your launchpad grouped by their start levels. This is especially true if the bundle list is configured using sensible defaults, for instance using the default bundle list as a start.

When the launchpad is packaged using the maven-bundle-plugin, the bundles are placed grouped by their start level under target/classes/resources/bundles . The ever-useful tree command allows us to inspect this directory ( I’ve removed some of the bundles to make the output easier to understand )

target/classes/resources/bundles/
├── 0
│   ├── org.apache.sling.scripting.jsp-2.0.14.jar
│   ├── org.apache.sling.scripting.jsp.taglib-2.1.0.jar
│   ├── org.apache.sling.servlets.get-2.1.2.jar
│   ├── org.apache.sling.servlets.post-2.1.0.jar
│   ├── org.apache.sling.servlets.resolver-2.1.0.jar
│   └── org.apache.sling.settings-1.0.2.jar
├── 1
│   └── org.apache.sling.commons.log-2.1.2.jar
├── 10
│   ├── org.apache.felix.configadmin-1.2.8.jar
│   ├── org.apache.felix.eventadmin-1.2.10.jar
│   ├── org.apache.felix.metatype-1.0.4.jar
│   └── org.apache.felix.scr-1.6.0.jar
├── 15
│   ├── commons-discovery-0.5.jar
│   ├── derby-10.5.3.0_1.jar
│   ├── guava-12.0.jar
│   ├── jackrabbit-api-2.1.1.jar
│   ├── jackrabbit-jcr-commons-2.1.1.jar
│   ├── jackrabbit-jcr-rmi-2.1.1.jar
│   └── tika-bundle-0.6.jar
└── 5
    ├── org.apache.sling.extensions.threaddump-0.2.0.jar
    ├── org.apache.sling.extensions.webconsolebranding-1.0.0.jar
    ├── org.apache.sling.extensions.webconsolesecurityprovider-1.0.0.jar
    └── org.apache.sling.jcr.webconsole-1.0.0.jar

Although the directories are not ordered numerically – an option which I have not found in my version of the tree command – the output is easy to understand and offers an overview of the start levels and bundles associated with them.