chrisdchristo / capsule-maven-plugin

Capsule Maven Plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Automatic binding to package phase

StanAccy opened this issue · comments

It seems that in order to use the plugin, you have to issue:

mvn *package* capsule:build    

and not just

mvn capsule:build

otherwise all the dependent JARs for the app are not found and thus fat-jar creation fails. Binding to the package phase makes a ton of sense, so why not just bind to the package phase automatically in the plugin, and remove the docs about mvn capsule:build, since that doesn't work for most folks out of the gate? Also, automatic binding would obviate the need to add the manual binding step (thus further lowering barrier to entry and making capsule even easier to use)

Hi, thanks for reporting. Apologies if it wasn't a completely smooth process to get you setup! I've adjusted to the readme in light of your concerns.

I'm not sure you can automatically bind a phase to a plugin? You can set a default phase (and thus not requiring the <phase> tag in the execution) but thats about it.

So what you can do is:

<plugin>
    <groupId>com.github.chrischristo</groupId>
    <artifactId>capsule-maven-plugin</artifactId>
    <version>${capsule.maven.plugin.version}</version>
    <configuration>
        <appClass>hello.HelloWorld</appClass>
    </configuration>
</plugin>

but make sure you include the package command as you know: mvn package capsule:build

or define with an execution (the default phase is package so you don't need to specify):

<plugin>
    <groupId>com.github.chrischristo</groupId>
    <artifactId>capsule-maven-plugin</artifactId>
    <version>${capsule.maven.plugin.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>build</goal>
            </goals>
            <configuration>
                <appClass>hello.HelloWorld</appClass>
            </configuration>
        </execution>
    </executions>
</plugin>

Also, for certain scenarios the second option where you hook the plugin in the package phase is not desirable. For example you might be using the exec plugin where you run the app directly. This requires you to build the package phase, something like mvn package exec:java. However to execute this command you do not need the capsule built jars, thus this would add pointless build time when you just want to run your app (Think about large apps too). This is actually how I develop, I use the exec plugin to run my app quickly, but when I want to release, I build the artifact into a capsule to deploy to a server.

Thanks Chris (for the answer and for writing the plugin - it works great). Our initial forays were successful - it was only when we went to build the capsule manually that we noticed this problem. There must be a way to auto-bind to the package phase (perhaps my terminology is off here with phase/execution binding) since all the "standard" plugins do so - JAR, WAR etc. Impact on build time for us is pretty irrelevant - while our total package size is upwards of 60Mb, the time it takes to assemble is barely noticeable.

As for your use case of running the app - I hadn't thought of that (since java -jar ourjar-fat.jar is already super simple). You might want to bump that idea up the docs a little since it makes things super easy. If its there already, I totally missed it, but its a great use case for testing and dev.

Thanks again

I think what you desire is a custom packaging type for maven. Something like <packaging>capsule</packaging> instead of <packaging>jar</packaging>. This is quite a difficult thing to implement as you would need to add custom configurations to a maven install as shown here. Also, the original jar still needs to be built (so it can be included in the capsule) so this new packaging type would have to accommodate the preceding step. A custom packaging type is not something I've implemented before so forgive me if any of the above is incorrect.

Honestly, I think its fine as is. Include the plugin with the execution step for your needs (so the capsule is built automatically at the package phase):

<plugin>
    <groupId>com.github.chrischristo</groupId>
    <artifactId>capsule-maven-plugin</artifactId>
    <version>${capsule.maven.plugin.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>build</goal>
            </goals>
            <configuration>
                <appClass>hello.HelloWorld</appClass>
            </configuration>
        </execution>
    </executions>
</plugin>

And yeah, for the use case I described before, all you need is the one step of mvn package exec:java which is even simpler than running the two step mvn package capsule:build && java -jar target/ourjar-fat.jar ;).

I'll bump that up in the readme to hopefully encourage others. Thanks :).