Careful With Your Binary Resources!

Our production application stack has a fair amount of external service connections that require the use of certs for SSL security. We used to use a static reference (e.g. /config/certs or c:\config\certs for you Windows people) to locate the certificates, but this was always suboptimal as it made the application less portable. I finally got around to moving from the static reference and landing on Java jar introspection to find the file (using something similar to ClassName.getResource("/cert.pks");).

This conversion worked very well and everything seemed fine until the change got to our continuous integration (or CI) box. That machine, a Centos distribution, kept failing with the error Invalid keystore format when we tried to initialize the keystore in code. I spent hours trying to figure out the difference between my local machine (running OS X, which worked fine) and the CI box. I finally diff’d the cert file in src/main/resources and the resulting file in target/classes. I discovered that the two files were radically different.

Maven has a very cool feature that not only copies values from src/main/resources into target/classes and, ultimately, the resulting Jar file but also can substitute tokens in text files as part of the build (referred to as “filtering”). To enable this, all you have to do is add

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
</resources>

to your pom.xml file and you’re off to the races. However, Maven will process every file in the src/main/resources directory as part of performing this substitution. This normally wouldn’t be an issue, but certificate files contain some raw text and Maven dutifully filters them just as it would any resource. This caused a serious issue with the character encoding as Maven was writing out a file with a completely different encoding scheme than the file was created with. Basically, Maven filtering was corrupting our certs.

To fix this, I created a subdirectory off of src/main/resources (I called it binary) and added a manual exclusion in the pom.xml file. The resulting XML looks as follows:

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>**/binary/*</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/binary</directory>
            </resource>
</resources>

This worked perfectly. Hopefully, it helps some of you as well!

Advertisements

About johnnywey

Welcome to A Regular Expression. This blog is designed to reflect my thoughts on life, music, software design, Apple, faith, philosophy, and whatever else I can think of.

Posted on November 4, 2009, in Java, Programming. Bookmark the permalink. 5 Comments.

  1. Thanks for this post. It solved my issue!

  2. Dude I love you (No homo).
    You save my life

  3. This is amazing. Thank you! This issue was killing us.

  4. Saved my day

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: