Equivalent to "make install" in the Java world
TL; DR : Is there a standard way in the Java world for build tools to install newly created executables (like the make install
C world)?
(I would be happy with a solution that will only work on Linux)
More details :
I have a Java project redistributable via github. Compilation and dependencies are managed with maven 2. Running mvn package
creates a tarball with my jar and dependencies needed at runtime, plus an executable script that sets the classpath and starts the main jar:
#!/bin/bash
cpBase="$(dirname "$0")"
java -cp "$cpBase/*" dw.cli.Program $@
So, if anyone wants to install this on their computer, one needs to:
- run
mvn package
- and then unpack the tarball and copy the contents to the directory on
PATH
.
On the other hand, I like the way autotools work: the user doesn't have to manually copy anything because the build step make install
handles the installation for it.
I could emulate this behavior using cp
ant tasks in mine pom.xml
, but I'm more interested in learning Java best practices than providing custom behavior.
It seems, the maven does not provide for such behavior . On the other hand, I am completely unaware of what another Java build tool can do.
Edit:
As far as I understand, mvn install
and mvn deploy
do not match my need because they will install my jar in my local or remote repository. Whereas I want to install my executables to mine PATH
(ex: set my wrapper script to /usr/local/bin
)
source to share
You can create a distribution archive (zip, tar.gz) that can be downloaded by the user and is only needed to unpack and add the bin folder to the path.
The problem is that you cannot automatically improve the path environment variable. But if you are using the generated scripts from the appassembler-maven-plugin, you can just directly call the generated scripts without incrementing your path. This works with both Linux and windows.
This can be achieved by a combination of appassembler-maven-plugin and maven-assembly-plugin .
The appassembler-maven plugin will create the corresponding / bat / cmd shell files for you, and the maven-assembly-plugin can create the corresponding archives (tar.gz, zip) for you.
You can look here as an example:
https://github.com/khmarbaise/supose/tree/master/supose-assembly
source to share
The question is marked as "gradle", so I'll answer with Gradle.
I believe you are building an application, not a library. In this case, Gradle thoughtfully supplies the plugin application
.
apply plugin: 'application'
The plugin gives you the problem run
, distZip
, distTar
and installDist
who do exactly what they sound like. Check the documentation at the
official website .
Note that the installDist task by default does not place software anywhere centrally on the system. Rather, it will be installed in a subdirectory build
where temporary files are stored. You can set a property destinationDir
on the task to fix this.
source to share
"make install" works by copying your built-in artifacts to the target location. This behavior is fairly easy to emulate in ANT, because, like doing it, you can specify your own build logic:
<target name="install" description="Copy binaries into install location">
<mkdir dir="/opt/myapp/bin"/>
<copy file="${dist.dir}/myproject.jar" todir="/opt/myapp/bin"/>
<copy file="${dist.dir}/myproject.sh" todir="/opt/myapp/bin"/>
<chown owner="${install.owner}">
<fileset dir="/opt/myapp" include="**/*"/>
</chown>
</target>
Of course, you need to run this target as root:
ant build
sudo ant install
Maven, on the other hand, is a highly reliable build tool that doesn't support such a workflow. What for? This is indeed a deployment action. You can of course customize your Maven setup with the ant ANT plugin, but I would suggest just running a shell script after that. The lot is easier to understand:
mvn install
sudo install_myapp.sh
The script can select the built-in jar from the local Maven repository "$ HOME / .m2 / repository" or better yet download it from the Maven repository!
source to share