Project Escher
Tags: showdev, java, x11
Published: 2020-04-13 10:36:14

I'm really interested in x11 but I am a java developer. Java covers most desktop application development with [swing](https://en.wikipedia.org/wiki/Swing_(Java)) and [javafx](https://en.wikipedia.org/wiki/JavaFX). As a result, using x11 directly in java is not very common. While researching my options I started looking into an old project called [escher](https://sourceforge.net/projects/escher/). Escher started on sourceforge but there is a [fork](https://github.com/rjolly/escher) on github which is also published to maven central. Over the past few days I have done quite a bit of work on my own [fork](https://github.com/moaxcp/escher).

# Converted mercurial history

The fork on gihub was based off version 0.3 sources but there were a few years of development after 0.3 in the mercurial repository. I was able to convert the mercurial history to git and start my fork with it. I followed [this guide](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git).

# Added demo code

The 0.3 sources had demo code that was apparently removed from the mercurial repository. This code is important because there are no tests and the only way to know the library really works is to run the demos. I was able to add the missing demo code and get it to compile after a while of refactoring. At this point I believe I have all the code from the original project.

# Fixed major bug from mercurial repository

After getting all of the code together and compiling there was a bug. Every `Input` event returned from X11 was `LAST_EVENT`. This is a special code that seems to mean null. I was able to debug this and found it was a simple `==` that should have been a `!=`.

# Added XephyrRunner

XephyrRunner is a test helper I made which handles starting and stopping an x11 server for integration tests. I am also using it for the "demoTest" which is a way to automate running the demo code.

# Added unix socket support

Escher didn't have a way to connect to a unix socket. It appeared to only support tcp connections. Most deployments of X11 never support tcp connections due to security concerns. I found another library called [junixsocket](https://github.com/kohlschutter/junixsocket) and used it to connect escher to x11 through a unix socket.

# Added github actions

In all of my other projects I use [travis-ci](https://travis-ci.org/github/moaxcp). For escher I used [github actions](https://github.com/features/actions). Github Actions are nicely integrated into github and allow the community to share CI more easily. I still need to figure out how to run x11 tests on it though.

# Added project to sonarcube

I added automated static analysis to the project using [sonarcloud](https://sonarcloud.io/dashboard?id=com.github.moaxcp%3Aescher). As a legacy project without tests there are some bad practices and bugs in escher. Being able to perform static analysis on the whole project enables a more strategic approach to refactoring and testing the code.

# Final thoughts

Why would someone go through this trouble to bring a mostly dead project back from its sourceforge grave? Like I said I want to work on X11 in java. I have an idea for a window manager and I think java has a lot to offer in this space.

Legacy code is everywhere. I like to define it as code without tests but this is a simplification. It is very common at work. A trend I have noticed is the pattern of creating legacy code is practiced between different projects. Legacy code is also copied between projects. Sometimes tests are added and code is refactored to better standards but there may be other copies that live on while the "good" code dies. Even new ideas are developed with legacy code. Because of this trend and my desire to "own" the code and have confidence in it, I spend as much time as permitted testing and refactoring code. I like to find better patterns and build nice APIs out of old code.

Escher may still end up as dead code in my github repo but this has been a gread experience so far.

Bye for now!