cmake: Added BUILD_FAT_JAR option (#2871)

* Added support and documentation for the CMake BUILD_FAT_JAR option

Co-authored-by: kyle <kyle@awesomeguy.co.za>
This commit is contained in:
Two4
2021-10-29 11:53:26 +02:00
committed by GitHub
parent 431a6de075
commit 35e1046e1f
7 changed files with 176 additions and 5 deletions

View File

@@ -203,6 +203,9 @@ option(USE_XPRESS "Use the XPRESS solver" OFF)
message(STATUS "XPRESS support: ${USE_XPRESS}")
if(BUILD_JAVA)
option(BUILD_FAT_JAR "Create single .jar with all dependencies (including native binaries)" OFF)
message(STATUS "Java build single fat .jar: ${BUILD_FAT_JAR}")
option(SKIP_GPG "Disable GPG sign" ON)
message(STATUS "Java disable gpg:sign: ${SKIP_GPG}")

View File

@@ -159,6 +159,7 @@ cmake -S. -Bbuild -LH
| | | |
| `SKIP_GPG` | OFF | Disable GPG sign<br>Only available if `BUILD_JAVA=ON` |
| `UNIVERSAL_JAVA_PACKAGE` | OFF | Build a multi platform package (i.e. `ortools-java` will depends on all native packages)<br>Only available if `BUILD_JAVA=ON` |
| `BUILD_FAT_JAR` | OFF | Build a `ortools-java` .jar that includes all of its own Maven dependencies, including the native package<br>Only available if `BUILD_JAVA=ON` |
| | | |
| `FETCH_PYTHON_DEPS` | BUILD_DEPS | Fetch python modules needed to build ortools package<br>Only available if `BUILD_PYTHON=ON` |
| | | |

View File

@@ -140,7 +140,7 @@ add_custom_target(java_native_package
$<$<NOT:$<PLATFORM_ID:Windows>>:$<TARGET_SONAME_FILE:${PROJECT_NAME}>>
${JAVA_RESOURCES_PATH}/${JAVA_NATIVE_PROJECT}/
COMMAND ${MAVEN_EXECUTABLE} compile -B
COMMAND ${MAVEN_EXECUTABLE} package -B
COMMAND ${MAVEN_EXECUTABLE} package -B $<$<BOOL:${BUILD_FAT_JAR}>:-Dfatjar=true>
COMMAND ${MAVEN_EXECUTABLE} install -B $<$<BOOL:${SKIP_GPG}>:-Dgpg.skip=true>
BYPRODUCTS
${JAVA_NATIVE_PROJECT_PATH}/target
@@ -190,7 +190,7 @@ add_custom_target(java_package ALL
${JAVA_PROJECT_PATH}/pom.xml
${JAVA_SRCS}
COMMAND ${MAVEN_EXECUTABLE} compile -B
COMMAND ${MAVEN_EXECUTABLE} package -B
COMMAND ${MAVEN_EXECUTABLE} package -B $<$<BOOL:${BUILD_FAT_JAR}>:-Dfatjar=true>
COMMAND ${MAVEN_EXECUTABLE} install -B $<$<BOOL:${SKIP_GPG}>:-Dgpg.skip=true>
BYPRODUCTS
${JAVA_PROJECT_PATH}/target

View File

@@ -89,6 +89,8 @@ to study their layout.
#### Building local Package
##### Standard Maven Package
So now, let's create the local `com.google.ortools:ortools-java.jar` maven
package which will depend on our previous native package.
@@ -118,10 +120,69 @@ mvn package
mvn install
```
If everything good the package (located in
`<buildir>/java/ortools-java/target/`) should have this layout:
If Maven executes these commands successfully, the package (located in
`<buildir>/temp_java/ortools-java/target/`) should have this layout:
```
{...}/target/ortools-java-8.0.jar:
{...}/target/ortools-java-{build version}.jar:
\- com/
\- google/
\- ortools/
\- Loader$PathConsumer.class
\- Loader$1.class
\- Loader.class
\- constraintsolver/
\- RoutingModel.class
\- RoutingIndexManager.class
\- ...
\- ...
...
```
##### Dependency-inclusive Maven Package (fat .jar)
We can also create a Maven package that includes all of its own dependencies, also known as a 'fat .jar'. This is useful
for situations in which it is more convenient, or even necessary, to use a single .jar as a dependency for a Java
OR-Tools project.
One example is when OR-Tools is compiled with third-party solver support (such as CPLEX or XPress), and one needs to
build and execute in an environment that does not have access to one's local Maven repository (for example, a
remotely-built Docker container).
Building a fat .jar with all dependencies included (including the native package) allows one to have a single
dependency, namely `com.google.ortools:ortools-java.jar`, which can be marked as `<scope>provided</scope>` in one's
project `pom.xml`:
```xml
<dependency>
<groupId>com.google.ortools</groupId>
<artifactId>ortools-java</artifactId>
<version>{insert build version here}</version>
<scope>provided</scope>
</dependency>
```
One would then make this fat .jar available in the execution environment's Java classpath, for example:
```bash
java -cp "/path/to/dependency.jar" -jar "/path/to/your/executable/.jar"
```
There are several ways to make the fat .jar dependency available to your Java program - please consult
[JDK documentation](https://devdocs.io/openjdk/) (this links to OpenJDK 15 documentation), as well as documentation for
any packaging and/or execution frameworks/tools you may be using.
To package a fat .jar with Maven, run
```bash
mvn package -Dfatjar=true
```
To then (optionally) install it to your local Maven repository, run
```bash
mvn install
```
Note that this will replace any previously downloaded or built 'non-fat-.jar' ortools-java packages in your local
Maven repository
[comment]: <> (FIXME show depedencies within .jar structure)
If Maven executes these commands successfully, the package (located in
`<buildir>/temp_java/ortools-java/target/`) should have this layout:
```
{...}/target/ortools-java-{build version}.jar:
\- com/
\- google/
\- ortools/
@@ -169,6 +230,7 @@ Few links on the subject...
* [Maven Javadoc Plugin](https://maven.apache.org/plugins/maven-javadoc-plugin/)
* [Maven Source Plugin](https://maven.apache.org/plugins/maven-source-plugin/)
* [Maven GPG Plugin](https://maven.apache.org/plugins/maven-gpg-plugin/)
* [Maven Assembly Plugin](https://maven.apache.org/plugins/maven-assembly-plugin/)
* [Java Native Access Project](https://github.com/java-native-access/jna)
## Misc

View File

@@ -154,4 +154,39 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-fat-jar</id>
<activation>
<property>
<name>fatjar</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -140,4 +140,39 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-fat-jar</id>
<activation>
<property>
<name>fatjar</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -129,4 +129,39 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-fat-jar</id>
<activation>
<property>
<name>fatjar</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>