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.

How can I set environment variables for GUI apps in OS X Mavericks?

Adapted from a SuperUser answer:

/etc/launchd.conf does not exist by default, but it does still work in 10.9.

  1. Run for example sudo nano /etc/launchd.conf.
  2. Add a line like 
    setenv M2_HOME /opt/boxen/homebrew/Cellar/atlassian-plugin-sdk/5.0.0/libexec/apache-maven-3.2.1/
  3. Run 
    launchctl < /etc/launchd.conf
    sudo launchctl < /etc/launchd.conf

     and relaunch processes.

Nginx as a secure front to JIRA and Confluence under the Atlassian SDK

Sometimes, you just need to use HTTPS during Atlassian add-on development. Atlassian SDK doesn’t currently cover this, so here’s a tutorial to show you how.

Install & configure nginx

I use Boxen to configure my development environment. Installing nginx is pretty easy. In boxen scripts/site.pp, ensure that this is not commented out:

include nginx

That done, enable SSL. You’ll need keys, secrets & certificates…

Create a key


Davids-MacBook-Pro:nginx david$ sudo openssl genrsa -des3 -out server.key 2048
Password:
Generating RSA private key, 2048 bit long modulus
.........+++
.............................................+++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

Remove the passphase

Davids-MacBook-Pro:nginx david$ sudo cp server.key server.key.org
Davids-MacBook-Pro:nginx david$ sudo openssl rsa -in server.key.org -out server.key
Enter pass phrase for server.key.org:
writing RSA key
Davids-MacBook-Pro:nginx david$

Generate a certificate that’s good for a year

Davids-MacBook-Pro:nginx david$ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Password:
Signature ok
subject=/C=GB/ST=Notts/L=Nottingham/O=AppFusions/OU=EU/CN=localhost/emailAddress=david@davidsimpson.me
Getting Private key
Davids-MacBook-Pro:nginx david$

Configure nginx

I use dvdsmpsn.appfusions.com as the server name and redirect all traffic on port 80 to 443. I’ve also boosted the file upload size so that I can install add-ons easily.

Edit /opt/boxen/config/nginx/nginx.conf

server {
    listen         80;
    server_name    dvdsmpsn.appfusions.com;
    rewrite        ^ https://$server_name$request_uri? permanent;
}

server {
    listen         443 ssl;
    server_name    dvdsmpsn.appfusions.com;
    ssl            on;

    ssl_certificate /opt/boxen/config/nginx/server.crt;
    ssl_certificate_key /opt/boxen/config/nginx/server.key;
    ssl_session_cache shared:SSL:10m;

    location /confluence {
        proxy_pass http://localhost:1990/confluence; # my existing Atlassian SDK tomcat - for Confluence
        proxy_set_header Host $host;
    }

    location /jira {
        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass https://localhost:8443/jira; # We need to configure JIRA to use this port yet
    }

     client_max_body_size 20M; # had problems with uploading plugins - Nginx Error - 413 Request Entity Too Large
 }

Restart nginx

sudo launchctl unload -w /Library/LaunchDaemons/dev.nginx.plist
sudo launchctl load -w /Library/LaunchDaemons/dev.nginx.plist

At this point, a Confluence instance running at http://localhost:1990/confluence will be available on HTTPS at https://dvdsmpsn.appfusions.com/confluence secured by nginx, but for JIRA, you have a bit of extra work.

Configure JIRA

For JIRA, Tomcat needs a little extra configuration. It’s a development system, so I don’t care about strong passwords. In fact, I’m sharing the password with you.

On the command line:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

and specify a password value of change it. — this saves to ${user.home}/.keystore

In Tomcat server.xml somewhere below the target directory, add:

<Connector
            protocol="HTTP/1.1"
            port="8443" maxThreads="200"
            scheme="https" secure="true" SSLEnabled="true"
            keystoreFile="${user.home}/.keystore" keystorePass="changeit"
            clientAuth="false" sslProtocol="TLS"/>

I simply paste this single XML node to the configuration file rather than editing one of the existing nodes just because its very easy. See Further Reading and the end of the post for a different, more production ready approach.

There are 2 copies of server.xml below the target directory. You should change both of them.

Restart JIRA.

That done, you should have a fully working JIRA available at https://dvdsmpsn.appfusions.com/jira

Why the extra configuration for JIRA?

You could try to terminate SSL at nginx, but that won’t give you a fully working JIRA.

If you configured JIRA just like Confluence, you’d use something like this in the nginx configuration file:

    location /jira {
        proxy_pass http://localhost:2990/jira;
        proxy_set_header Host $host;
    }

Accessing JIRA on https://dvdsmpsn.appfusions.com/jira/ would display the following on page error message:

jira-mismatched-scheme

The full error message reads:

We’ve detected a potential problem with JIRA’s Dashboard configuration that your administrator can correct. Hide

Dashboard Diagnostics: Mismatched URL Scheme

JIRA is reporting that it is using the URL scheme ‘http’, which does not match the scheme used to run these diagnostics, ‘https’. This is known to cause JIRA to construct URLs using an incorrect hostname, which will result in errors in the dashboard, among other issues.

The most common cause of this is the use of a reverse-proxy HTTP(S) server (often Apache or IIS) in front of the application server running JIRA. While this configuration is supported, some additional setup might be necessary in order to ensure that JIRA detects the correct scheme.

The following articles describe the issue and the steps you should take to ensure that your web server and app server are configured correctly:

If you believe this diagnosis is in error, or you have any other questions, please contact Atlassian Support.

Detailed Error

com.atlassian.gadgets.dashboard.internal.diagnostics.UrlSchemeMismatchException: Detected URL scheme, 'http', does not match expected scheme 'https'
at com.atlassian.gadgets.dashboard.internal.diagnostics.Diagnostics.checkExpectedScheme(Diagnostics.java:64)
at com.atlassian.gadgets.dashboard.internal.diagnostics.Diagnostics.check(Diagnostics.java:36)
at com.atlassian.gadgets.dashboard.internal.diagnostics.DiagnosticsServlet.executeDiagnostics(DiagnosticsServlet.java:97)
at com.atlassian.gadgets.dashboard.internal.diagnostics.DiagnosticsServlet.doPost(DiagnosticsServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at com.atlassian.plugin.servlet.DelegatingPluginServlet.service(DelegatingPluginServlet.java:42)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at com.atlassian.plugin.servlet.ServletModuleContainerServlet.service(ServletModuleContainerServlet.java:52)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.steps.ChainedFilterStepRunner.doFilter(ChainedFilterStepRunner.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.XContentTypeOptionsNoSniffFilter.doFilter(XContentTypeOptionsNoSniffFilter.java:22)
at com.atlassian.core.filters.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:31)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.core.filters.HeaderSanitisingFilter.doFilter(HeaderSanitisingFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:46)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.jira.tzdetect.IncludeResourcesFilter.doFilter(IncludeResourcesFilter.java:39)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.jira.baseurl.IncludeResourcesFilter.doFilter(IncludeResourcesFilter.java:38)
at com.atlassian.core.filters.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:31)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:25)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.mywork.client.filter.ServingRequestsFilter.doFilter(ServingRequestsFilter.java:37)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsSiteMeshFixupFilter.doFilter(PrettyUrlsSiteMeshFixupFilter.java:36)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsDispatcherFilter.doFilter(PrettyUrlsDispatcherFilter.java:60)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsSiteMeshFilter.doFilter(PrettyUrlsSiteMeshFilter.java:92)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsMatcherFilter.doFilter(PrettyUrlsMatcherFilter.java:56)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.labs.botkiller.BotKillerFilter.doFilter(BotKillerFilter.java:36)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.labs.httpservice.resource.ResourceFilter.doFilter(ResourceFilter.java:59)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:77)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.accesslog.AccessLogFilter.executeRequest(AccessLogFilter.java:103)
at com.atlassian.jira.web.filters.accesslog.AccessLogFilter.doFilter(AccessLogFilter.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.security.xsrf.XsrfTokenAdditionRequestFilter.doFilter(XsrfTokenAdditionRequestFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:181)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:85)
at com.atlassian.jira.web.filters.SitemeshPageFilter.doFilter(SitemeshPageFilter.java:124)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.steps.ChainedFilterStepRunner.doFilter(ChainedFilterStepRunner.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:46)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsCombinedMatchDispatcherFilter.doFilter(PrettyUrlsCombinedMatchDispatcherFilter.java:61)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:77)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.seraph.filter.SecurityFilter.doFilter(SecurityFilter.java:234)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:100)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.seraph.filter.BaseLoginFilter.doFilter(BaseLoginFilter.java:169)
at com.atlassian.jira.web.filters.JiraLoginFilter.doFilter(JiraLoginFilter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:46)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:69)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsCombinedMatchDispatcherFilter.doFilter(PrettyUrlsCombinedMatchDispatcherFilter.java:61)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:77)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.util.profiling.filters.ProfilingFilter.doFilter(ProfilingFilter.java:99)
at com.atlassian.jira.web.filters.JIRAProfilingFilter.doFilter(JIRAProfilingFilter.java:19)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.johnson.filters.AbstractJohnsonFilter.doFilter(AbstractJohnsonFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.gzipfilter.GzipFilter.doFilterInternal(GzipFilter.java:80)
at com.atlassian.gzipfilter.GzipFilter.doFilter(GzipFilter.java:51)
at com.atlassian.jira.web.filters.gzip.JiraGzipFilter.doFilter(JiraGzipFilter.java:55)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:46)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.fastdev.AutoReloadFilter.doFilter(AutoReloadFilter.java:63)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
at com.atlassian.prettyurls.filter.PrettyUrlsCombinedMatchDispatcherFilter.doFilter(PrettyUrlsCombinedMatchDispatcherFilter.java:61)
at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:77)
at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.steps.ChainedFilterStepRunner.doFilter(ChainedFilterStepRunner.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.core.filters.cache.AbstractCachingFilter.doFilter(AbstractCachingFilter.java:33)
at com.atlassian.core.filters.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:31)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.core.filters.encoding.AbstractEncodingFilter.doFilter(AbstractEncodingFilter.java:41)
at com.atlassian.core.filters.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:31)
at com.atlassian.jira.web.filters.PathMatchingEncodingFilter.doFilter(PathMatchingEncodingFilter.java:49)
at com.atlassian.core.filters.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:31)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.startup.JiraStartupChecklistFilter.doFilter(JiraStartupChecklistFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.MultipartBoundaryCheckFilter.doFilter(MultipartBoundaryCheckFilter.java:41)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.atlassian.jira.web.filters.steps.ChainedFilterStepRunner.doFilter(ChainedFilterStepRunner.java:87)
at com.atlassian.jira.web.filters.JiraFirstFilter.doFilter(JiraFirstFilter.java:60)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)

For this reason, I’ve added SSL support to Tomcat as well.

Further reading

Retro AUI Sandbox

Delorean_

Or how to match an Atlassian product and version to a compatible AUI Sandbox.

AUI Sandbox (latest) is really useful when fitting design patterns to Atlassian add-ons.

I keep hitting problems though. Paste some example markup into (say) a Confluence add-on using the latest version of Confluence and the UI doesn’t always look the same.

Why’s that? Well. The latest released version of Confluence doesn’t use the latest version of AUI. That’s expected I suppose, but damn, I want the correct version. How?

In the web console in your Atlassian product type AJS.version then take a look here – https://docs.atlassian.com/aui/ – for the closest fit. You’ll be able to browse down the directory structure to a compatible AUI Sandbox.

Check out these retro versions of AUI Sandbox – 3.3.0, 3.6.0 & 4.0 – pretty wild, huh?

Using Transmit “mount as disk” and FolderWatch to develop on a remote system

Working as an external consultant means that you adapt to certain constraints. Sometimes this means you have absolutely no access to the systems you’re developing for and thus you’re reliant entirely on a your ability to bond and form a good relationship with a local admin (maybe from a different culture and continent). Other times, there is some limited access.

This time, I had some access. Just not much.

The constraints

A project I’ve recently been working on had SFTP access to the web server where the files reside, but nothing more.
Continue reading…

JIRA Release User Macro for Atlassian Confluence

Back when JIRA macros in Confluence involved the knowledge of bizarre URL string combinations, I wrote a user macro that allowed me to list all issues in a JIRA release/version if I only knew 2 bits of information: the project key and the version.

It helped me whenever I wrote a blogpost to notify people about the release of a new product version. Like so:

jira-release-user-macro

In old style wiki markup, my user macro would look like this:

{release:ProjectKey=AF032|Version=3.0.0}

Continue reading…

Objects Available to Velocity in Atlassian Confluence – A User Macro

There’s a great list of Confluence Objects Accessible From Velocity on the Atlassian Developers site. I often refer to that page. However, the list is not exactly complete.

Scott Dudley wrote a handy user macro that displays all the available objects. I’ve improved a little on Scott’s user macro by linking to the latest Confluence JavaDocs for each class.

Here’s the user macro:

Continue reading…

A legacy Atlassian Plugin SDK for Homebrew

Atlassian released version 5.0.0 of their plugin SDK earlier this month and like a fanboy I upgraded immediately. It updates Maven from 2.1.0 to 3.2.1, so that’s a big change in itself.

Today, I started work on updating an add-on for Confluence 4.3.x (yes, really). Guess what? My development environment is now completely incompatible with the target Confluence version. What to do?

Being a Homebrew fan, I’d like to use that to reinstall the old version. You can do this with old versions of some software such as Maven e.g.

brew tap homebrew/versions
brew install maven2

I’d like to do the same with the Atlassian Plugin SDK. Could I? Nope.

So I rolled my own. It was very easy.

You can use it too. Here’s how:

brew tap dvdsmpsn/tap
brew install dvdsmpsn/tap/atlassian-plugin-sdk-42

This currently installs version 4.2.19 of the SDK.

The code is available on GitHub. I’m sure there are better ways of doing this, but it fills a gap and that’s enough for me.

Update 2014-06-18:
Atlassian have added their own legacy version just like mine. You can try it out:

brew tap atlassian/tap
brew install atlassian/tap/atlassian-plugin-sdk-4

Thanks to Marcos Scriven for providing the update and letting me know.