Automated native2ascii character conversion for internationalisation of Atlassian add-ons


Normally, I write my internationalisation (i18n) files in UTF-8 format. This means that they are human readable.

Java i18n files however must be ISO-8859-1. If you don’t process them using something like native2ascii, accented and multibyte characters will return gobbledegook at best.

You can manually convert a single file manually using this command:

native2ascii -encoding utf-8 ./src/main/resources/ ./target/classes/

That’s tedious, so why not automate the process during the build?

Using native2ascii-maven-plugin

Luckily, there’s a maven plugin called native2ascii-maven-plugin. Its old, but does the job.

For Atlassian SDK p2 add-ons, use something like this:


            <!-- For Java 7+ compilation: -->

Your source files will be in sweet UTF-8 format and your target files will be mangled into ISO-8859-1 as Java requires.

How do you do this? Please add a comment below with details.

Releasing a locked port on a Mac / OS X

Sometimes a port doesn’t release properly resulting in servers staring on non-standard ports.

How do you release the port? Easy, use this:

lsof -i :portnumber

Grab the resulting PID and kill the process. Use -9 if you really have to.

Here’s a “worked example”:

$ lsof -i :1990
java    2857 david   39u  IPv6 0x23ed6292526f5971      0t0  TCP *:stun-p1 (LISTEN)
$ kill -9 2857

Customising Atlassian Confluence with header photos


Header photos are all the rage (as my mother might say). Twitter has them. So does Facebook. Yup, even LinkedIn has them.

Confluence is a great platform for documentation, but what if you want to add extra some flare to your pages? Would a custom header photo be a good idea? Maybe so.

This post gives a simple method to do just that for pages that use the Default Theme.

In Confluence Admin | Configuration | User Macros create a new user macro:

## Macro: header-photo
## Author: David Simpson
## @param Photo:title=Header Photo|type=enum|enumValues=akabilk,captain_oblivion,rikpiks,renateflynn,grotan|default=red|desc=Choose a photo from one of these Flickr users
<script>AJS.toInit(function($){ $('body').addClass('header-photo photo-${paramPhoto}'); }); </script>

This gives you a user macro with some options to swap the background image between these images:

In Confluence Admin | Look and Feel | Stylesheet add the following:

 *  Uses the {header-photo} user macro to trigger the styles:

.header-photo #main-header {
	margin: -20px;
	padding: 20px;
	background: #69c;

.header-photo #title-text {
	padding-top: 40px

.header-photo #breadcrumbs a,
.header-photo #title-text a,
.header-photo .page-metadata,
.header-photo .page-metadata ul li a
	color: #fff;
	text-shadow: 2px 2px 5px #000;

/*** Hide these until mouseover/hover ***/
.header-photo #page-metadata-banner,
.header-photo #breadcrumbs,
.header-photo #navigation,
.header-photo .page-metadata {
	transition         : opacity .25s ease-in-out;
	-moz-transition    : opacity .25s ease-in-out;
	-webkit-transition : opacity .25s ease-in-out;
	opacity: 0;

/*** Display on mouseover/hover ***/
.header-photo #breadcrumbs:hover,
.header-photo #navigation:hover,
.header-photo .page-metadata:hover {
	opacity: 1;

.header-photo #main-header {
	background-size: cover;
	background-color: #000;
	background-position: 50% 50%;

/*** Each of these backgrounds has been selected from Flicker and uses a Creative Commons license ***/

/* From: */ #main-header {
	background: #000 url(//  no-repeat  ; 

/* From: */ #main-header {
	background-image:  url(//; 

/* From: */ #main-header {
	background-image: url(//; 

/* From: */ #main-header {
	background-image: url(//; 

/* From: */ #main-header {
	background-image: url(//; 

This is a simple bit of CSS that adds a different background to the page header based on the body class added in the user macro. I’ve purposefully chosen only dark backgrounds so that I can use a single text colour. Yes, that was quite lazy. You can embellish with more styles as required.

Here’s the macro configuration screen:


The macro parameter values in the dropdown match the CSS classes in the custom global stylesheet. It’s pretty straightforward.

I’ve really restricted the number of photos available here. This is just an example of how you could implement a feature like this. You could easily adapt this for custom photos on every space or every page if you really feel like it.

Perhaps random photos is the way forward for you? If so, you could do worse than

Secure development on Atlassian SDK using useHttps

Check the <useHttps>true</useHttps> configuration item. It appears to be a bit of a secret that could handle some more exposure. It starts Atlassian SDK running over HTTPS/SSL on port 443 without the need for a proxy server. Nice.

You can add it here:


You’ll need to start the server like so:

sudo atlas-run

Otherwise, you’ll likely get the following error trying to bind to port 443 as a non-root user:

[INFO] [talledLocalContainer] SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-443"]
[INFO] [talledLocalContainer] Permission denied <null>:443
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at org.apache.coyote.AbstractProtocol.init(
[INFO] [talledLocalContainer] 	at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(
[INFO] [talledLocalContainer] 	at org.apache.catalina.connector.Connector.initInternal(
[INFO] [talledLocalContainer] 	at org.apache.catalina.util.LifecycleBase.init(
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.StandardService.initInternal(
[INFO] [talledLocalContainer] 	at org.apache.catalina.util.LifecycleBase.init(
[INFO] [talledLocalContainer] 	at org.apache.catalina.core.StandardServer.initInternal(
[INFO] [talledLocalContainer] 	at org.apache.catalina.util.LifecycleBase.init(
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.Catalina.load(
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.Catalina.load(
[INFO] [talledLocalContainer] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[INFO] [talledLocalContainer] 	at sun.reflect.NativeMethodAccessorImpl.invoke(
[INFO] [talledLocalContainer] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(
[INFO] [talledLocalContainer] 	at java.lang.reflect.Method.invoke(
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.Bootstrap.load(
[INFO] [talledLocalContainer] 	at org.apache.catalina.startup.Bootstrap.main(
[INFO] [talledLocalContainer] Caused by: Permission denied
[INFO] [talledLocalContainer] 	at Method)
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at<init>(
[INFO] [talledLocalContainer] 	at<init>(
[INFO] [talledLocalContainer] 	at<init>(
[INFO] [talledLocalContainer] 	at<init>(
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	at
[INFO] [talledLocalContainer] 	... 17 more
[INFO] [talledLocalContainer] 

Does this work well?

Yes and no. It’s super easy to get going provided you remember about root permissions, but there are drawbacks.

You have to sudo on redeploys, and well, pretty much everything you do.

This seems like overkill though:

sudo atlas-package

atlas-install-plugin or sudo atlas-install-plugin doesn’t work as it tries to install to port 1990 for Confluence, 2990 for JIRA and so forth.

I ended up uploading the plugin via the UPM each time it was redeployed. That’s just rubbish.

This however, should work nicely:

sudo atlas-install-plugin --http-port 443

Will I continue to use this?

I’m not sure at the moment, unless its just for a very quick test or for JIRA development. Proxying with nginx is so easy. It’s setup and forget easy, at least for Confluence.

Debugging opensocial gadgets in IBM Connections

My standard IBM Connections installation has the following logging settings:


In WebSphere, this is displayed on a single line:

*=info:*=all:*=all:*=all:*=all:*=all:*=all:*=all:*=all:*=all: org.apache.shindig.*=all

Continue reading…

Atlassian Confluence hides create button and top navigation on license expiry


This was driving me crazy. I developed an add-on for Confluence, but sometimes the top navigation bar was missing items.

I was concerned that my add-on was really misbehaving and interfering in some way with the core product. There was no need to worry as Danielle figured it out.

On license expiry, rather than informing you that the license has expired, it simply disables features in the main header such as:

  • Spaces
  • People
  • Create button
  • The search box

If you run a product under the Atlassian SDK, you get a single day license. If you leave it overnight and come back, bits of the product (such as the Create button) get disabled. Restarting the product resets the license, so the disabled parts start working again. This doesn’t seem to be documented anywhere as far as I can tell.
Continue reading…

Entity Conversion Calculator (for CSS and JavaScript)

Filed under note to self.

I have trouble remembering how to convert characters into hex for JavaScript or CSS.

For example, sometimes I like to use » for breadcrumb separators using CSS something like this: ul.breadcrumb a:after {content:'\0064';} but can’t remember the precise hex code.

To fix this, here’s Evolution Technologies’ Entity Conversion Calculator iframed in this page:

I’m not claiming any ownership here, I’ve just embedded it for my own convenience.