1

What is(are) the simpler way(s), using just "native" Apache Maven plugins, to inject a script at the beginning of a jar file to make the jar an executable file?

Actually, any way to "edit" the built jar file as a regular file concatenating it with another file may work. Like the shell cat example down below:

$ cat ${projectRoot}/src/main/stubs/runstub.sh target/${builtJarPath} > target/${builtJarPathWithoutExtention}-autorun.jar
$ chmod +x target/${builtJarPathWithoutExtention}-autorun.jar

In case you want to know the reason to inject a shell script at the beginning of a jar file, check the internet about "converting jar file to Linux executable", example:

Luciano
  • 2,695
  • 6
  • 38
  • 53
  • A jar will not being made executable by using a shell script into it. An executable needs first a correct entry in mainClass within the MANIFEST.MF file which enables it to start a jar like `java -jar jarfile.jar` ... – khmarbaise Mar 16 '21 at 14:24
  • @khmarbaise: The manifest file doesn't matter, the script will launch the JVM with the project desired args having or not any manifest file. The manifest file isn't necessary if your script doesn't rely on it. So, it will be executable if you inject a proper script into it. We should rather care about the drawback of depending on any script "runner", like as: `sh`, `bash`, `zsh`, or even `python`... in specific OSes. – Luciano Mar 16 '21 at 17:53
  • I know that you not forced to use a MANIFEST.MF etc. If think about os independency a shell script does not make sense. I know that you start up the jvm via script or without ... but how do you start the script? Or how to get the script started because if it's inside the jar you can't start it... you can create an executable via Graal VM which compiles into a native executable but I don't know what kind of app you have... Usually you create two different scripts `.cmd`(windows) and `.sh` for linux and create a zip/tar.gz archive which contains everything is needed...(JVM not included) – khmarbaise Mar 16 '21 at 19:18
  • You could create a packaged jvm via JLink (JDK9+) and do the same distribute the whole JRE including your app... but then you have to modularize .... – khmarbaise Mar 16 '21 at 19:19

1 Answers1

1

You can use exec-maven-plugin

<plugin>
  <artifactId>exec-maven-plugin</artifactId>
  <groupId>org.codehaus.mojo</groupId>
  <executions>
    <execution>
      <id>Inject stub</id>
      <phase>install</phase> <!-- Select a phase that is after package generation -->
      <goals>
        <goal>exec</goal>
      </goals>
      <configuration>
        <executable>${basedir}/scripts/inject-stub.sh</executable>
      </configuration>
    </execution>
  </executions>
</plugin>
Ghokun
  • 3,345
  • 3
  • 26
  • 30