|
| 1 | +# Canteen |
| 2 | + |
| 3 | +The `canteen-maven-plugin` is used to make executable jar files self-executing. That is, executable from the command |
| 4 | +line as if they were native programs instead of requiring a `java -jar` command. |
| 5 | + |
| 6 | +```bash |
| 7 | +# For example |
| 8 | +java -jar copyjar-1.0.0.jar fromFile toFile |
| 9 | + |
| 10 | +# Becomes |
| 11 | +./copyjar-1.0.0-linux-x86_64.exe fromFile toFile |
| 12 | +``` |
| 13 | + |
| 14 | +Canteen creates platform native self-executing jars for 64-bit Linux, MacOS, and Windows. |
| 15 | + |
| 16 | +## Usage |
| 17 | + |
| 18 | +Bundle your jar as an executable jar, and add the `canteen-maven-plugin` to your pom.xml. |
| 19 | + |
| 20 | +```xml |
| 21 | +<build> |
| 22 | + <plugins> |
| 23 | + <!-- Make the jar executable (for java -jar) --> |
| 24 | + <plugin> |
| 25 | + <groupId>org.apache.maven.plugins</groupId> |
| 26 | + <artifactId>maven-jar-plugin</artifactId> |
| 27 | + <version>2.4</version> |
| 28 | + <configuration> |
| 29 | + <archive> |
| 30 | + <manifest> |
| 31 | + <addClasspath>true</addClasspath> |
| 32 | + <mainClass>mypackage.Main</mainClass> |
| 33 | + </manifest> |
| 34 | + </archive> |
| 35 | + </configuration> |
| 36 | + </plugin> |
| 37 | + |
| 38 | + <!-- Make the jar self-executing with Canteen --> |
| 39 | + <plugin> |
| 40 | + <groupId>com.salesforce.servicelibs</groupId> |
| 41 | + <artifactId>canteen-maven-plugin</artifactId> |
| 42 | + <version>${canteen.version}</version> |
| 43 | + <executions> |
| 44 | + <execution> |
| 45 | + <goals> |
| 46 | + <goal>bootstrap</goal> |
| 47 | + </goals> |
| 48 | + </execution> |
| 49 | + </executions> |
| 50 | + </plugin> |
| 51 | + </plugins> |
| 52 | +</build> |
| 53 | +``` |
| 54 | + |
| 55 | +Canteen will add three additional artifacts to your Maven module with types and classifiers compatible with the |
| 56 | +[os-maven-plugin](https://github.com/trustin/os-maven-plugin). |
| 57 | + |
| 58 | +* `artifactId:groupId:version:exe:linux-x86_64` |
| 59 | +* `artifactId:groupId:version:exe:osx-x86_64` |
| 60 | +* `artifactId:groupId:version:exe:windows-x86_64` |
| 61 | + |
| 62 | +## How does Canteen work? |
| 63 | + |
| 64 | +Canteen leverages a quirk of Java's jar format to make jars behave like native executables. |
| 65 | + |
| 66 | +Under the hood, jar files are just zip archives. A zip archive is made up of one or more independently compressed files, |
| 67 | +followed by an index table. The zip index table is rooted at the end of the archive with offset pointers relative to the |
| 68 | +final byte address of the file. The backwards-looking nature of the zip archive index means you can prepend a zip |
| 69 | +archive with arbitrary data or executable code without violating the integrity of the archive. |
| 70 | + |
| 71 | +Unlike zip archives which are read backwards, executable programs are loaded and executed from byte zero. A common |
| 72 | +technique for adding "data" to executables is to append bytes to the end of the executable, where it won't affect |
| 73 | +execution. |
| 74 | + |
| 75 | +Concatenating an executable and a zip archive results in a file that is both a valid executable (read from the front), |
| 76 | +and a valid zip archive (read from the back). This technique was historically used to create self-extracting zip files. |
| 77 | +The `canteen-maven-plugin` uses the same technique to prepend a simple platform specific bootstrap program |
| 78 | +cross-compiled with Go to the front of a jar. |
| 79 | + |
| 80 | +When you execute a Canteen packaged jar, the bootstrap program captures all the command line arguments and the name |
| 81 | +of the current file. It then spawns a child process as `java -jar $args`, proxying `stdin`, `stdout`, and `stderr` |
| 82 | +between the shell and the child process. |
0 commit comments