Fxlauncher is a auto updating launcher for javafx programs. Download a small jar (around 18Kb), start it and it will download the actual application and run it. Every time you start the small jar it will check if there is a newer version and download it automatically. So fxlauncher is a fun project and it will make keeping a desktop application uptodate easy. Setting up fxlauncher from Maven was not so easy. A plugin was needed.
requirements
The plugin needs to do the following:
- create the 
app.xmlthat is used to describe the application, its dependencies and several settings. - update 
fxlauncher.jarwith app.xml - copy all the dependencies to a directory from where it can later be uploaded to a webserver
 - upload to a webserver.
 
All these tasks can be done without writing a plugin for it and was how it was done untill now, this means several calls using the maven-exec-plugin. The setup was huge.
I will not go into details about all of them, but I do want to highlight some interesting things I found while writing this.
Maven plugin documentation is bad
Subject says it all. I did not expect the documentation to be this bad. In the end I analyzed several well known plugins (the dependency plugin, the shade plugin and the jgitflow plugin) to see how a maven-plugin project is supposed to be setup. There is an archetype for it but I could not get that one to work. See pom.xml for how I set it.
java.nio.file.FileSystem is cool
To manipulate the fxlauncher.jar I decided to use the FileSystem that was introduced in Java7. This makes it very easy to add or delete files to, in this case, a jar file.
void addtoLauncher(String fileToAdd) throws MojoExecutionException {
        getLog().info(String.format("placing %s in fxlauncher", fileToAdd));
        Path path = Paths.get(String.format("%s/fxlauncher.jar", buildDir));
        Map<String, String> props = new HashMap<>();
        props.put("create", "false");
        URI uri = URI.create("jar:" + path.toUri().toASCIIString());
        try (FileSystem jarFile = FileSystems.newFileSystem(uri, props)) {
            Path source = Paths.get(fileToAdd);
            Path target = jarFile.getPath(String.valueOf(source.getFileName()));
            Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            throw new MojoExecutionException("error in adding file to jar", e);
        }
    }
The heavy lifting is done in the try block. There are several types of files you can open this way.
mojo-executor is cool too
Normally when you want to copy dependencies to a certain place you will setup the maven-dependency-plugin to do the heavy lifting for you. You would configure it in your pom.xml and tie it to a phase. I wanted however to be able to call the maven-dependency-plugin from another plugin. Luckily this is possible with the mojo-executor:
void copyDependencies() throws MojoExecutionException, IOException {
     getLog().info("copying to " + buildDir);
     executeMojo(
            plugin(groupId("org.apache.maven.plugins"),
                    artifactId("maven-dependency-plugin"),
                    version("2.0")
            ),
            goal("copy-dependencies"),
            configuration(
                    element(name("outputDirectory"), buildDir)
            ),
            executionEnvironment(
                project,
                session,
                buildPluginManager
            ));
}
It doesn’t get much easier then this. I like the fluent like api.