Insane Programming Java ramblings and finds on the net

25Jan/100

Self-signed JAR signing with Maven for webstart – without the keystore

Anyone reading the above title will have serious doubts about the validity of this article. But let me explain. Mind you, this is an article for development purposes, for production you'll probably need to have a keystore with a properly signed SSL certificate (then again, most webstart applications are intranet, so why bother).
That the Maven Webstart plugin hosted by Codehaus is ill-documented is a well known fact. However, as with most Maven-related subjects, you can learn a whole lot about its workings by looking at the code, or the examples if they are provided.
A beginner will read the plugin documentation, and then start fidgeting with the Java keytool utility to get the keystore needed for jar signing. Needless to say, the keytool utility isn't the easiest one of the lot. Probably after about half an hour you'll have a decent enough keystore, going through about every function of the keytool command-line. Then he'll utilize the keystore in the plugin (preferably using a relative path).
Why the Codehaus guys haven't mentioned the easier way on the plugin's website is beyond me, but here it is:

<plugin>
    <groupId>org.codehaus.mojo.webstart</groupId>
    <artifactId>webstart-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>process-resources</phase>
            <goals>
                <goal>jnlp-download-servlet</goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <outputDirectoryName>webstart</outputDirectoryName>
        <excludeTransitive>false</excludeTransitive>
        <jnlpFiles>
            <jnlpFile>
                <templateFilename>template.vm</templateFilename>
                <outputFilename>myapp.jnlp</outputFilename>
                <jarResources>
                    <jarResource>
                        <groupId>be.insaneprogramming</groupId>
                        <artifactId>myapp-gui</artifactId>
                        <version>${project.version}</version>
                        <mainClass>be.insaneprogramming.myapp.GUIMain</mainClass>
                    </jarResource>
                </jarResources>
            </jnlpFile>
        </jnlpFiles>
        <sign>
            <keystore>/tmp/myappkeystore</keystore>
            <keypass>m2m2m2</keypass>
            <storepass>m2m2m2</storepass>
            <alias>foobar</alias>
            <validity>3650</validity>

            <dnameCn>Insane Programming</dnameCn>
            <dnameOu>Software Development</dnameOu>
            <dnameO>Insane Programming</dnameO>
            <dnameL>Maldegem</dnameL>
            <dnameSt>Oost-Vlaanderen</dnameSt>
            <dnameC>BE</dnameC>
            <verify>false</verify>
            <keystoreConfig>
                <delete>true</delete>
                <gen>true</gen>
            </keystoreConfig>
        </sign>
        <outputJarVersions>true</outputJarVersions>
        <verbose>true</verbose>
        <unsign>true</unsign>
        <verifyjar>false</verifyjar>
    </configuration>
</plugin>

This configuration will create a keystore on the fly and use that one for the signing. The advantage?

  • No keystore is needed in the project sourcetree or in a shared location
  • No more messing around with the keytool
  • Signing information is kept in the POM
  • You can reuse information in the POM for the signing (organisation name etc.), or even use Maven properties and profiles to customize the signing without having to resort to multiple keystore or a keystore with multiple aliases.
    For example you could do this in the signing configuration:

    ...
    <validity>${signing.validity}</validity>
    <dnameCn>${signing.dname.cn}</dnameCn>
    <dnameOu>${signing.dname.ou}</dnameOu>
    <dnameO>${signing.dname.o}</dnameO>
    <dnameL>${signing.dname.l}</dnameL>
    <dnameSt>${signing.dname.st}</dnameSt>
    <dnameC>${signing.dname.c}</dnameC>
    ...
    

    where the placeholder information is kept in the company super POM. A lot easier to maintain, I reckon.

  • The signature will always be valid when signing (no need to replace keystore to remove warnings)
2Jan/1013

Maven and Ant guys: you’ll never agree. On anything. Period. Deal with it!

Every 3 months or so, you'll see a new article pop up somewhere written by an Ant (mostly, sometimes Gradle or Rake) lover discussing the horrible nature of Maven and how it works.

People, please! How old are you guys? I've used both and I like Maven more. Is that a reason for me to post another rant on Ant? Seriously, most rants are one-way. It's easy to break down a tool based on some criteria, but how about proposing some solutions to problems some Maven users face that you can easily solve in [your favorite buid tool]? Whoops. Negative criticism is easy, isn't it?

Recently, I read this article. It doesn't take a genius to discover that this blogger is a Maven hater. Or to put it more bluntly: it doesn't support the way HE wants to build software. Here's an idea: try and take every feature you hate in Maven and give a Rake or Ant alternative way. Every single one. I'm waiting for the excuses you'll throw at me.

Let's see. According to this blogger, it's really hard to build a war. Last time I built a WAR with Maven, I just needed to change the packaging to WAR. Okay, you do need to know that the WEB-INF folder goes into src/main/webapp. Is that really that hard? The other rant was about the WAR size. Here he actually has a (albeit minor) point. Maven projects (especially frameworks) really need to learn the value of optional dependencies. But then again, I'd like to see Ant projects solve this issue too without their usual solution: provide a README stating which jars should be included when you want to use certain functionalities.

I've heard the statement "Why use an entire toolbox (Maven) when you only need a hammer (Ant)". Okay, you CAN put a screw in a wall with a hammer. The result ain't pretty, but it works. Does that mean a hammer is the only tool to use. No. Know when to use a tool. Any tool for that matter. Would you throw the screwdriver out of your toolbox because it can't handle a nail?

Any of the rants can be translated into either incorrect use of Maven or just plain stupidity (or even lazyness): I can point out a lot of Ant, Gradle or Rake misuse that is equally painful. Dependency resolving takes to much time? Use Artifactory or Nexus internally (it'll even solve some other problems concerning snapshots). Got problems with plugins? Stop omitting the version number in your POM's (or use a company-wide POM). Too many unused transitive dependencies that should be optional? Contact the author. Got a problem with XML POM's? Maven 3 has polyglot functionality.
All I'm saying is: stop ranting. Either come up with non-abstract solutions, or shut up. Ranting is easy. Coming up with solutions using your own solutions is less so.

Tagged as: , 13 Comments