ForkedBooter steals window focus on Mac OS while Maven is running

This is about running Maven, specifically.

For most Java applications, any of the solutions from this question on StackOverflow should work.

It’s a matter of passing -Djava.awt.headless=true to the Java process, which can be done for all Java processes by saving that option to a variable named JAVA_TOOL_OPTIONS in your .bashrc.

That’s fine as long as you have direct control over the Java process, which is not the case with Maven.

In my case, it was the Failsafe Maven Plugin that caused that annoyance, but some were experiencing the same behavior with an old version of Surefire. The following snippet fixes both.

In your pom.xml, change your existing <plugin> definitions so that they look like this (the important lines are highlighted):

<!-- this is inside your <project><build><plugins> block -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven.surefire.plugin.version}</version>
    <configuration>
      <includes>
        <include>**/unit/**/*Test*.java</include>
      </includes>
      <!-- prevent the annoying ForkedBooter process from stealing 
        window focus on Mac OS -->
      <argLine>-Djava.awt.headless=true</argLine>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>${maven.failsafe.plugin.version}</version>
    <configuration>
      <!-- prevent the annoying ForkedBooter process from stealing 
        window focus on Mac OS -->
      <argLine>-Djava.awt.headless=true</argLine>
      <includes>
        <include>**/integration/**/*Test*</include>
      </includes>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>integration-test</goal>
          <goal>verify</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Done!

I added this reply to stack exchange as well, but maybe this post will be easier to find (as that question already already had an accepted answer when I replied, and it doesn’t work for Maven). We’ll see!

Could not open the requested socket: Address already in use. Restart Jetty from Eclipse on Mac OSX

I am used to hit on the Play button in Eclipse like hell when developing server apps, so I ran into this issue pretty quickly.

When you’re working with Google App Engine on Mac OSX, pressing that familiar green button after having deployed the app once makes Eclipse complain as in the title. The stop button is grayed out (as it’s controlling the latest instance of Jetty, which didn’t start) and you can’t launch your app without restarting Eclipse.

So, to kill the old Jetty instance you just open a terminal and type:

lsof -i TCP:8888 | grep java | grep LISTEN

Where 8888 is the port on which Jetty is listening (it could be 8080 or something else depending on your configuration), and the first grep is just to stay on the safe side (you don’t want to kill something else). If you’re sure that there’s nothing else listening on that port, just omit it.

The output will be something like

java    33873 myusername   68u  IPv6 0xffffff801a2c1510      0t0  TCP localhost:ddi-tcp-1 (LISTEN)

Then, just type

kill -15 33873

where 33873 is the number in the second column in the output of the previous command.

You can then run the project from Eclipse.

My routine is to keep a terminal window open and just run this one-liner when I run into the error:

kill -15 $(lsof -i TCP:8888 | grep java | grep LISTEN | awk '{ print $2 }')

which does exactly the same thing, but in an automated fashion… it’s just an arrow_up away! 🙂

Change default date range in Google Analytics

I don’t know the reason why Google chose to set the default date range to the last 30 days excluding the current date (maybe I’m the only one interested in today’s stats), but it’s definitely annoying not having the option to change that default.

There used to be a bookmarklet to overcome the issue, but I’ve not been able to find an update for that after Google’s changed how URLs are managed in Analytics.

So, here’s the update 🙂

The “easiest” way I found to make a bookmarklet works like this:

  1. Log in to your Google Analytics account
  2. Look at the URL, it should be something like https://www.google.com/analytics/web/?hl=en&#home/a12345678w12345678p12345678/
  3. Copy the last portion of the URL, in the example it’s a12345678w12345678p12345678
  4. Open a text editor, copy & paste this code on a new file you can call analytics.html
    <html>
    <head></head>
    <body><a target="_blank" href="javascript:(function(){function d(a){a=String(a);a.length<2&&(a='0'+a);return a}var c=new Date,b='';b+=c.getFullYear();b+=d(c.getMonth()+1);b+=d(c.getDate());location.href='https://www.google.com/analytics/web/?#report/visitors-overview/a12345678w12345678p12345678/%3F_u.date00%3D'+b+'%26_u.date01%3D'+b+'/=';})();">Google Analytics</a></body>
    </html>
    
  5. Replace a12345678w12345678p12345678 in the file with the code you copied at step 3
  6. Save the file and open it with your browser (tested with Chrome, Firefox and Safari on Mac OSX)
  7. Drag the link to your bookmarks bar

Don’t delete/move/rename the HTML file if you’re using Chrome or Firefox, for some reason they need it even after you’ve added the bookmarklet.

This bookmarklet sets the date range to today only, you can play with the javascript to change that (now only b is used, you’d need to create a new Date and set it at the end of the URL). Also, it takes you to the visitors overview page, you can change that by looking at the other pages’ URLs.

Steps 2, 3 and 5 are not technically needed, in that if you leave the bogus URL I put in the code, Analytics is going to tell you that something’s wrong with your credentials, but will set the date anyway (and update that part of the URL). I guess that’s your session ID, so I’m not sure if it’s better to use an existing one or just leave the dummy and let Analytics generate a new one every time. It’s probably hackish to use an old session ID, but it gets rid of the warning dialog and it works!

Ok, this was to create a bookmarklet, but what I actually did was create a Chrome Extension that does the same thing, but has an icon and most of all is listed on the new tab page. If anybody is interested in that, let me know in the comments and I’ll add a new post to explain how it’s done :).

[Edit – June 27]: so here’s the promised extension

HttpPost requests executed multiple times (Apache HttpClient)

This is something I noticed on Android, but from what I read it also involves the desktop Java version.

I was sending POST requests to an API server, and I was getting some random 400 Bad Request responses from time to time. I wish Apache provided an easy way to log the plain text version of Http requests, but I couldn’t find a better way to see what the app was sending than sending the same request to my PC when failing.

So to log requests I start netcat (sudo nc -l 80 on a mac) or a very minimal server in python (it’s more or less the same as the example on Twisted’s front page) and route them there whenever an error occurs.

try {
   response = client.execute(post,
                  new BasicResponseHandler());
} catch (IOException e) {
   if (DEBUG_FAILED_REQUESTS) {
      post.setURI(URI.create(DEBUG_FAILED_REQUESTS_SERVER));
      try {
         client.execute(post, new BasicResponseHandler());
      } catch (IOException e1) {
         e1.printStackTrace();
      }
   }
}

I don’t know if it’s my router, but sometimes connections from the Android device to my PC get blocked: to make them work I just open a browser on the Android, go to some website and then try again with my internal IP (192.168.0.whatever). It always works, no idea why.

Using this code I discovered that my post requests were executed 4 times each, nearly at the same time. I discovered that it’s the default behavior, and you must provide your own RetryHandler if you want the HttpClient to work otherwise.

In my case, my calls are sent to Google’s shortener service, and for some reason sometimes it just rejects requests. If you wait a little bit between attempts you increase your chance of getting valid responses. So this is what I did:

HttpPost post = new HttpPost(SHORTENER_URL);
String shortURL = null;
int tries = 0;
try {
    post.setEntity(new StringEntity(String.format(
            "{\"longUrl\": \"%s\"}",
            getURL(encodedID, encodedAssignedID))));
    post.setHeader("Content-Type", "application/json");
    DefaultHttpClient client = new DefaultHttpClient();
    // disable default behavior of retrying 4 times in a burst
    client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(
            0, false));
    String response = null;
    while (response == null && tries < RETRY_COUNT) {
        try {
            response = client.execute(post,
                    new BasicResponseHandler());
        } catch (IOException e) {
            // maybe just try again...
            tries++;
            Utils.debug("attempt %d failed... waiting", tries);
            try {
                // life is too short for exponential backoff
                Thread.sleep(RETRY_SLEEP_TIME * tries);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
    Utils.debug("response is %s", response);
    if (response != null) {
        JSONObject jsonResponse = new JSONObject(response);
        shortURL = jsonResponse.getString("id");
    } else if (DEBUG_FAILED_REQUESTS) {
        Utils.debug("attempt %d failed, giving up", RETRY_COUNT);
        debugPost(post, client);
    }
} catch (JSONException e) {
    e.printStackTrace();
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

where debugPost() is a method that calls my PC to log the request, and Utils.debug() is just a small utility method I wrote to log messages with logcat using String.format() if format args are passed to it (it also takes care of splitting messages that would be truncated by logcat itself).

You could choose to implement exponential backoff very easily, but since it’s a blocking operation for the user in my case I preferred not to.

Ant stopped working after Eclipse update on Mac OSX (<terminated> is shown with no explanation)

After updating Eclipse on my laptop, all of a sudden the built-in version of Ant that ships with Eclipse stopped working.

I right-click on a build.xml files, run it as Ant build but… nothing happens! I don’t get any message in the Eclipse Console (you know, the usual red ones telling you that you screwed up somewhere in the XML file). The only thing I get is a mysterious <terminated> message in the view’s title, followed by the path to the Java executable on my machine.

I kept just using Ant from a shell until I decided it was time for some googling. After searching through bugs I found this comment on a bug, so here’s what you need to do:

  1. go to your Eclipse preferences
  2. go to Ant/Runtime
  3. in the “Classpath” tab, expand the “Ant Home Entries (Default)” list
  4. you should see a bunch of entries like Applications/eclipse/plugins/org.apache.ant_x.y.z.v.../lib/ant*.jar: if you go check, that folder doesn’t exist!
  5. press “Add External JARs” and go to /Applications/eclipse/plugins/, where you should find an org.apache.ant_ folder with a different version than that of the listed entries (in my case I have an org.apache.ant_1.8.3.v20120321-1730 folder)
  6. select and add all jars in the lib folder inside the org.apache.ant_x.y.z folder (the one from the previous step)
  7. select and remove all old jars (those from the non-existing folder), hit apply

now Ant should work again!

By the way, this should be the open bug that tracks this issue if you want to follow it.

Remove (bogus) recent workspaces from Eclipse Juno in Mac OS

I never used more than one workspace until Android forced me to do so (you can’t configure debug keystores on a project basis, so you really need different workspaces).

I’ve seen two bad things about working with several workspaces thus far:

  1. you lose all your settings when creating a new workspace (Eclipse only asks to copy perspectives from the current workspace, which is something but not enough)
  2. Eclipse kept showing me a bogus workspace that I never created in the File/Switch Workspace menu, plus it didn’t understand when I renamed one, so it started showing that workspace with both names (old and new)

The first issue can be solved by following these steps (which of course I discovered after doing them by hand… silly me).

As for the second, on MacOS go to your Eclipse installation folder (I have it in Applications), then open configuration/.settings/org.eclipse.ui.ide.prefs with a text editor.

The variable you’re looking for is called RECENT_WORKSPACES, where workspaces are listed one for each line (I can actually see the ‘\n’ as line separators). Delete the silly ones, restart Eclipse, done!

Show/hide hidden files in Mac OS with a keyboard shortcut

I usually need to see all hidden files in Finder, so I used to just have them showing all the time. Being a long time Gnome user (and an Ubuntu one) I learned to love the joy of Ctrl-H to toggle between visible and invisible hidden files, so I thought that Cmd-H would do the same, which it doesn’t.

Seeing hidden files all the time wouldn’t be bad if not for the behated .DS_Store files showing up in every folder and, worst of all, in my Desktop! I try to keep my Desktop clean, no icons at all, just beautiful pictures I get from the nice Kuvva app. I don’t use Desktop shortcuts anyway, Spotlight is my friend.

So, there is a way to add the Ctrl-H behavior to Mac OS, kinda-sorta, and this is the best I could get so far.

Step 1: create a simple shell script
The command to show/hide hidden files is defaults write com.apple.Finder AppleShowAllFiles YES, changing the last word to NO if you want to hide hidden files again.
To make the shortcut behave as a toggle, we just create a “sentinel” hidden file (we created a hidden file for your hidden files so you can hide your hidden files etc..) to save the current state.

Here’s the script

if [[ -f .hiddenindeed ]]; then
	rm .hiddenindeed
	defaults write com.apple.Finder AppleShowAllFiles NO
else
	touch .hiddenindeed
	defaults write com.apple.Finder AppleShowAllFiles YES
fi
killall Finder

As you may have noticed, we kill Finder so it reloads the defaults, otherwise it looks like nothing happens. Finder reloads itself, so it’s safe to kill it. There’s a little gotcha: at least in Lion it looks like it doesn’t save its current state all the time, so run the script only when you don’t care about the currently open windows. Results may vary, and even in Lion as I said the behavior is not 100% consistent.

Step 2: save the script with a .command extension and make it executable
I’m not entirely sure that this is needed in Mac OS, but I’m too lazy to check. Plus, it’s super easy and it’s the same thing you would do in Linux.

To make it executable, just open a terminal and type

chmod a+x your_script_name.command

Of course you need to cd into the same folder as your script, or use the absolute path of your script from whatever folder.

Step 3: choose your preferred keyboard shortcut tool
Ok so this is where you can choose how to launch the script. I strongly prefer the OSX-ified Ubuntu-esque way of just pressing Cmd-H (Cmd being OSX’s Ctrl in most cases) since I never use the shortcut to hide windows, and it’s what comes most natural to me. However, this requires using a third-party tool to launch apps using shortcuts; my weapon of choice is the awesome Better Touch Tool, which I already use to enable 3-finger-click gestures to open links in new background browser tabs (again, this is the equivalent of Gnome’s middle-button click with an external mouse).

There are several alternatives, the most popular being Alfred, I guess. I never felt the need for leaving spotlight thus far, so I don’t know much about how you configure shortcuts for that, but I read it’s one of its features.

Step 3a: using Better Touch Tool
This is very easy: open BTT’s preferences, go to Global (left column, should be selected by default), Keyboard tab, click on the “Add new shortcut” button, click on the Keyboard Shortcut field, press your shortcut of choice and choose “Open Application/File/Script…” from the rightmost menu. Then, select your script.

Step 3b: using Spotlight
You can always type the name of your script in spotlight and select it; the downside to this is that it may never become the Top Hit, or at least it didn’t when I tried, so you’d have to select it with the arrow keys..

Step 4: hide the terminal once the script is done
I don’t want the terminal to stick around even after the script is done, so I have it close automatically when done.

Open a terminal window, go to Terminal/Preferences/Settings tab/Shell sub-tab and change the value for “When the shell exits”. I chose “Close if the shell exited cleanly”, but you can also choose “Close the window”. I like to see error messages if something goes wrong, though..