{"id":13621549,"url":"https://github.com/spring-projects-experimental/spring-boot-thin-launcher","last_synced_at":"2025-04-14T06:04:53.938Z","repository":{"id":40523904,"uuid":"71230327","full_name":"spring-projects-experimental/spring-boot-thin-launcher","owner":"spring-projects-experimental","description":"Tools for building \"thin\" executable jars, with a focus on, but not exclusively for, Spring Boot","archived":false,"fork":false,"pushed_at":"2025-01-15T13:57:09.000Z","size":2140,"stargazers_count":688,"open_issues_count":20,"forks_count":92,"subscribers_count":40,"default_branch":"main","last_synced_at":"2025-04-14T06:04:48.273Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/dsyer/spring-boot-thin-launcher","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spring-projects-experimental.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.adoc","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-18T09:13:45.000Z","updated_at":"2025-02-24T01:51:53.000Z","dependencies_parsed_at":"2025-02-08T07:01:48.233Z","dependency_job_id":"ee60196d-685f-4f70-b96d-a20d12e5e719","html_url":"https://github.com/spring-projects-experimental/spring-boot-thin-launcher","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spring-projects-experimental%2Fspring-boot-thin-launcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spring-projects-experimental%2Fspring-boot-thin-launcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spring-projects-experimental%2Fspring-boot-thin-launcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spring-projects-experimental%2Fspring-boot-thin-launcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spring-projects-experimental","download_url":"https://codeload.github.com/spring-projects-experimental/spring-boot-thin-launcher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830396,"owners_count":21168272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:01:07.875Z","updated_at":"2025-04-14T06:04:53.892Z","avatar_url":"https://github.com/spring-projects-experimental.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# Spring Boot Thin Launcher [![ci.spring.io](https://ci.spring.io/api/v1/teams/spring-team/pipelines/spring-boot-thin-launcher/badge)](https://ci.spring.io/teams/spring-team/pipelines/spring-boot-thin-launcher)\n\nA \"thin\" jar launcher for java apps. Version 1.0.31.RELEASE is in Maven Central, snapshots are in https://repo.spring.io/libs-snapshot. See https://github.com/spring-projects/spring-boot/issues/1813 for more discussion and ideas.\n\n## Getting Started\n\nThe thin-launcher provides its own custom layout for the Spring Boot\nplugins. If this layout is used then the jar built by Spring Boot will\nbe executable and thin.\n\nNOTE: if you are using a snapshot version of the thin launcher you\neither need to build it locally or include the snapshot repository\ndeclarations. You can use https://start.spring.io to find suitable\nrepository declarations for Maven and Gradle, or look at the samples\nin this project.\n\nWith Maven, build a Spring Boot application and add the layout. This\nmeans adding it to the Spring Boot plugin declaration:\n\n```xml\n\u003cplugin\u003e\n\t\u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n\t\u003cartifactId\u003espring-boot-maven-plugin\u003c/artifactId\u003e\n\t\u003cversion\u003e${spring-boot.version}\u003c/version\u003e\n\t\u003cdependencies\u003e\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.springframework.boot.experimental\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003espring-boot-thin-layout\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e1.0.31.RELEASE\u003c/version\u003e\n\t\t\u003c/dependency\u003e\n\t\u003c/dependencies\u003e\n\u003c/plugin\u003e\n```\n\nand in Gradle, you need to add the `thin-launcher` plugin and (preferably) a `maven-publish` plugin with an explicit publication definition. You can use the newer `id` style declaration:\n\n```groovy\nplugins {\n\tid 'org.springframework.boot' version '3.0.1'\n\tid 'io.spring.dependency-management' version '1.1.0'\n\tid 'java'\n\tid 'maven-publish'\n\tid 'org.springframework.boot.experimental.thin-launcher' version '1.0.31.RELEASE'\n}\n\ngroup = 'com.example'\nversion = '0.0.1-SNAPSHOT'\nsourceCompatibility = '17'\n\nrepositories {\n\tmavenLocal()\n\tmavenCentral()\n\tmaven { url \"https://repo.spring.io/snapshot\" }\n\tmaven { url \"https://repo.spring.io/milestone\" }\n}\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            from components.java\n        }\n    }\n}\n```\n\nor you can use the older `apply` style declaration:\n\n```groovy\nbuildscript {\n\text {\n\t\tspringBootVersion = '2.7.6'\n\t\twrapperVersion = '1.0.31.RELEASE'\n\t}\n\trepositories {\n\t\tmavenLocal()\n\t\tmavenCentral()\n\t}\n\tdependencies {\n\t\tclasspath(\"org.springframework.boot.experimental:spring-boot-thin-gradle-plugin:${wrapperVersion}\")\n\t\tclasspath(\"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}\")\n\t}\n}\napply plugin: 'maven-publish'\napply plugin: 'org.springframework.boot.experimental.thin-launcher'\n\npublishing {\n    publications {\n        maven(MavenPublication) {\n            from components.java\n        }\n    }\n}\n```\n\nThe publication named \"maven\" is responsible for creating a `pom.xml` for your application.\n\nFor Spring Boot 2.x snapshot versions (or older releases) you also need a `settings.gradle` with the repository configuration for the plugin. e.g. (as generated by https://start.spring.io):\n\n```groovy\npluginManagement{\n\trepositories{\n\t\tmaven{url'https://repo.spring.io/libs-snapshot'}\n\t\tgradlePluginPortal()\n\t}\n\tresolutionStrategy{\n\t\teachPlugin{\n\t\t\tif (requested.id.id=='org.springframework.boot.experimental.thin-launcher'){\n\t\t\t\tuseModule(\"org.springframework.boot.experimental:spring-boot-thin-gradle-plugin:${requested.version}\")\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nIf you don't need snapshots you can leave it all out and rely on the defaults. If you are testing a change you made to the plugin you might want to put `mavenLocal()` in the `repositories` as well.\n\nIn Gradle you also need to generate a `pom.xml` or a `thin.properties` (unless you want to maintain it by hand). A `pom.xml` will be generated automatically by the \"thinPom\" task in the Thin Gradle plugin. It does this by calling out to the maven plugin and the dependency management plugin; the maven plugin is always present, and the dependency management plugin is present if you are using the Spring Boot plugin. To generate a `pom.xml` remember to apply the maven and Thin Gradle plugins.\n\nNOTE: Gradle now has a `maven-publish` plugin that works with the newer \"standard\" configurations (e.g. `runtimeOnly` replaces `runtime`). It also works with the thin launcher plugin.\n\nThe generated pom goes in the normal maven place by default under `META-INF/maven`. You can configure the output directory by setting the \"output\" property of the \"thinPom\" task.\n\nYou can customize the generated `pom.xml`, or switch it off, by creating your own task in `build.gradle` and forcing the jar task to depend on it instead of \"thinPom\", or by simply not using the Thin Gradle plugin. Example (which just duplicates the default):\n\n```groovy\ntask createPom {\n\tdoLast {\n\t\tpom {\n\t\t\twithXml(dependencyManagement.pomConfigurer)\n\t\t}.writeTo(\"build/resources/main/META-INF/maven/${project.group}/${project.name}/pom.xml\")\n\t}\n}\n\njar.dependsOn = [createPom]\n```\n\nInstead of or as well as a `pom.xml` you could generate a `thin.properties` using `gradle thinProperties` (the task is always registered by the Thin Gradle plugin but is not executed by default). By default it shows up in `META-INF` in the built resources, so you need to run it before the jar is built, either manually, or via a task dependency, e.g.\n\n```groovy\njar.dependsOn = [thinProperties]\n```\n\nThe generated properties file is \"computed\" (it contains all the transitive dependencies), so if you have that, the dependencies from the `pom.xml` will be ignored.\n\nIf you look at the jar file produced by the build you will see that it\nis \"thin\" (a few KB), but executable with `java -jar ...`.\n\n## How does it Work?\n\nInspect the app jar that you built (or one of the samples in this\nproject) and notice that it is only a few KB. It is just a regular jar\nfile with the app classes in it and one or two extra features. The things\nit needs to operate are:\n\n1. The `ThinJarWrapper` class has been added.\n2. Either a `pom.xml` and/or a `META-INF/thin.properties` which lists the dependencies of the app.\n\nWhen the app runs the main method per the manifest is the\n`ThinJarWrapper`. Its job is to locate another jar file (the\n\"launcher\"). The wrapper downloads the launcher (if it needs to), or\nelse uses the cached version in your local Maven repository.\n\nThe launcher then takes over and reads the `pom.xml` (if present) and\nthe `thin.properties`, downloading the dependencies (and all\ntransitives) as necessary, and setting up a new class loader with them\nall on the classpath. It then runs the application's own main method\nwith that class loader. The `pom.xml` can be in the root of the jar or\nin the standard `META-INF/maven` location.\n\nThe app jar in the demo is built using the Spring Boot plugin and a\ncustom `Layout` (so it only builds with Spring Boot 2.x and above).\n\n## Caching JARs\n\nAll jar files are cached in the local Maven repository, so if you are\nbuilding and running the same app repeatedly, it should be faster\nafter the first time, or if the local repo is already warm.\n\nThe local repository can be re-located by setting a System property\n\"thin.root\". For example to use the current directory:\n\n```\n$ java -Dthin.root=. -jar app/target/*.jar\n```\n\nThis will download all the dependencies to `${thin.root}/repository`,\nand look for Maven settings in `${thin.root}/settings.xml`.\n\nYou can also do a \"dry run\", just to warm up the cache and not run the\napp, by setting a System property or command line argument\n\"thin.dryrun\" (to any value except \"false\"). In fact, since you don't\nneed the application code for this (except the\n`META-INF/thin.properties`), you could run only the launcher, or the\nwrapper which is contained in the launcher for convenience. This is a\nuseful trick for laying down a file system layer in a container image,\nfor example.\n\n\u003e NOTE: options for the `ThinJarLauncher` that are listed as\n\u003e `-Dthin.*` can also be provided as command line arguments\n\u003e (`--thin.*` per Spring Boot conventions), or as environment\n\u003e variables (`THIN_*` capitalized and underscored). The command line\n\u003e options are removed before passing down to the Boot app. The\n\u003e `ThinJarWrapper` also accepts system properties, environment\n\u003e variables or command line flags for its (smaller) set of optional\n\u003e arguments.\n\n## Build Tools\n\n### Maven\n\nIn addition to the Spring Boot layout there is an optional Maven\nplugin which can be used to do the dry run (download and cache the\ndependencies) for the current project, or for any project that has an\nexecutable thin jar in the same format. The \"app\" sample in this repo\ndeclares this plugin and inserts it into the \"package\" lifecycle:\n\n```xml\n\u003cplugin\u003e\n\t\u003cgroupId\u003eorg.springframework.boot.experimental\u003c/groupId\u003e\n\t\u003cartifactId\u003espring-boot-thin-maven-plugin\u003c/artifactId\u003e\n\t\u003cversion\u003e${wrapper.version}\u003c/version\u003e\n\t\u003cexecutions\u003e\n\t\t\u003cexecution\u003e\n\t\t\t\u003cid\u003eresolve\u003c/id\u003e\n\t\t\t\u003cgoals\u003e\n\t\t\t\t\u003cgoal\u003eresolve\u003c/goal\u003e\n\t\t\t\u003c/goals\u003e\n\t\t\t\u003cinherited\u003efalse\u003c/inherited\u003e\n\t\t\u003c/execution\u003e\n\t\u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\nAfter running the build, there is a deployable warm-cache and a copy\nof the executable jar at `target/thin/root` (by default):\n\n```\n$ cd samples/app\n$ mvn package\n$ cd target/thin/root\n$ java -Dthin.root=. -jar app-0.0.1-SNAPSHOT.jar\n```\n\nThe \"simple\" sample has the same feature, but it also downloads and\nwarms up the cache for the \"app\" sample, so you could use the same\nbuild to run both apps if you felt like it.\n\nThe Maven plugin also has a `properties` mojo, so you can create or update\n`thin.properties` from the dependencies of the project directly. By default it creates a\n`thin.properties` in `src/main/resources/META-INF`, but you can change the output\ndirectory with the plugin configuration. Example:\n\n```\n$ cd samples/app\n$ mvn spring-boot-thin:properties -Dthin.output=.\n```\n\nBy default the `thin.properties` is \"computed\" (i.e. it contains all transitive\ndependencies), but you can switch to just the declared dependencies using the \"compute\"\nconfiguration flag in the plugin (or `-Dthin.compute=false` on the command line).\n\n### Gradle\n\nThe same features are available to Gradle users by adding the thin jar plugin (as described above).\n\nThe plugin creates 2 tasks for every jar task in the project, one that\nreolves the dependencies, and one that copies the jar into the same\nlocation to make it easy to launch. A \"dry run\" can be executed in\nGradle by calling the \"thinResolve\" task defined by the plugin, e.g.\n\n```\n$ cd samples/simple\n$ gradle thinResolve\n$ cd build/thin/deploy\n$ java -Dthin.root=. -jar simple-0.0.1-SNAPSHOT.jar\n```\n\nThe default location for the cache is `build/thin/root` but this was\nchanged in the `build.gradle` for that sample:\n\n```\nthinResolvePrepare {\n\tinto new File(\"${buildDir}/thin/deploy\")\n}\n```\n\n\u003e NOTE: The \"thinResolve\" and \"thinResolvePrepare\" tasks are the\n\u003e default names for a single jar project. If your jar task is not\n\u003e called \"jar\", then the names are appended with the jar task name\n\u003e (capitalized), e.g. \"thinResolveMyJar\" for a task called\n\u003e \"myJar\"). If you have multiple jar tasks in the project, then each\n\u003e one has its own resolve tasks.\n\n## Deploying to Cloud Foundry (or Heroku)\n\nThe thin launcher (1.0.4 and above) adds an empty \"lib\" entry to the jar so that it matches the default detection algorithm for a Java application with the standard Java buildpack. As of version v4.12 of the Java buildpack the dependencies will be computed during staging (in the \"compile\" step of the buildpack), so you don't incur that cost on startup.\n\nYou can also save the staging cost, and resolve the dependencies locally before you push the app.\n\n```\n$ java -jar target/demo-0.0.1.jar --thin.dryrun --thin.root=target/thin/.m2\n$ (cd target/thin; jar -xf ../demo-0.0.1,jar)\n$ cf push myapp -p target/thin\n```\n\n(Note the use of a subdirectory `.m2` to hold the local repository cache - this works because the root is the default `HOME` directory in a Cloud Foundry app.)\n\nThe Maven plugin has a \"resolve\" task with a flag unpack (or `-Dthin.unpack` on the command line) that creates the cache in the precise form that you need to push to Cloud Foundry. The unpack flag is false by default, so remember to set it if you want to use Maven to prepare the push.\n\n## Command Line Options\n\nYou can set a variety of options on the command line or with system properties (`-D...`). The `thin.*` properties are all removed from the command line before calling the main class, so the main class doesn't have to know how it was launched.\n\n| Option              | Default                                                                          | Description                                                                                                                                                                                                                                                          |\n| ------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `thin.main`         | Start-Class in MANIFEST.MF                                                       | The main class to launch (for a Spring Boot app, usually the one with `@SpringBootApplication`)                                                                                                                                                                      |\n| `thin.dryrun`       | false                                                                            | Only resolve and download the dependencies. Don't run any main class. N.B. any value other than \"false\" (even empty) is true.                                                                                                                                        |\n| `thin.offline`      | false                                                                            | Switch to \"offline\" mode. All dependencies must be available locally (e.g. via a previous dry run) or there will be an exception.                                                                                                                                    |\n| `thin.force`        | false                                                                            | Force dependency resolution to happen, even if dependencies have been computed, and marked as \"computed\" in `thin.properties`.                                                                                                                                       |\n| `thin.classpath`    | false                                                                            | Only print the classpath. Don't run the main class. Two formats are supported: \"path\" and \"properties\". For backwards compatibility \"true\" or empty are equivalent to \"path\".                                                                                        |\n| `thin.root`         | `${user.home}/.m2`                                                               | The location of the local jar cache, laid out as a maven repository. The launcher creates a new directory here called \"repository\" if it doesn't exist.                                                                                                              |\n| `thin.libs`         | `\u003cempty\u003e`                                                                        | Additional classpath entries to append at runtime in the same form as you would use in `java -classpath ...`. If this property is defined then unresolved dependencies will be ignored when the classpath is computed, possibly leading to runtime class not found exceptions. |\n| `thin.archive`      | the same as the target archive                                                   | The archive to launch. Can be used to launch a JAR file that was build with a different version of the thin launcher, for instance, or a fat jar built by Spring Boot without the thin launcher.                                                                     |\n| `thin.parent`       | `\u003cempty\u003e`                                                                        | A parent archive to use for dependency management and common classpath entries. If you run two apps with the same parent, they will have a classpath that is the same, reading from left to right, until they actually differ.                                       |\n| `thin.location`     | `file:.,classpath:/`                                                             | The path to directory containing thin properties files (as per `thin.name`), as a comma-separated list of resource locations (directories). These locations plus the same paths relative /META-INF will be searched.                                                 |\n| `thin.name`         | \"thin\"                                                                           | The name of the properties file to search for dependency specifications and overrides.                                                                                                                                                                               |\n| `thin.profile`      | \u003cempty\u003e                                                                          | Comma-separated list of profiles to use to locate thin properties. E.g. if `thin.profile=foo` the launcher searches for files called `thin.properties` and `thin-foo.properties`.                                                                                    |\n| `thin.library`      | `org.springframework.boot.experimental:spring-boot-thin-launcher:1.0.31.RELEASE` | A locator for the launcher library. Can be Maven coordinates (with optional `maven://` prefix), or a file (with optional `file://` prefix).                                                                                                                          |\n| `thin.repo`         | `https://repo.spring.io/snapshot` (also contains GA releases)               | Base URL for the `thin.library` if it is in Maven form (the default).                                                                                                                                                                                                |\n| `thin.launcher`     | `org.springframework.boot.thin.ThinJarLauncher`                                  | The main class in the `thin.library`. If not specified it is discovered from the manifest `Main-Class` attribute.                                                                                                                                                    |\n| `thin.parent.first` | true                                                                             | Flag to say that the class loader is \"parent first\" (i.e. the system class loader will be used as the default). This is the \"standard\" JDK class loader strategy. Setting it to false is similar to what is normally used in web containers and application servers. |\n| `thin.parent.boot`  | true                                                                             | Flag to say that the parent class loader should be the boot class loader not the \"system\" class loader. The boot loader normally includes the JDK classes, but not the target archive, nor any agent jars added on the command line.                                 |\n| `thin.debug`        | false                                                                            | Flag to switch on some slightly verbose logging during the dependency resolution. Can also be switched on with `debug` (like in Spring Boot).                                                                                                                        |\n| `thin.trace`        | false                                                                            | Super verbose logging of all activity during the dependency resolution and launch process. Can also be switched on with `trace`.                                                                                                                                     |\n\nAny other `thin.properties.*` properties are used by the launcher to override or supplement the ones from `thin.properties`, so you can add additional individual dependencies on the command line using `thin.properties.dependencies.*` (for instance).\n\n## Downstream Tools\n\nThe default behaviour of the `ThinJarWrapper` is to locate and launch the `ThinJarLauncher`, but it can also run any main class you like by using the `thin.library` and `thin.launcher` properties. One of the main reasons to provide this feature is to be able to support \"tools\" that process the application jar (or whatever), for example to generate metadata, create file system layers, etc. To create a new tool, make an executable jar (it can even be thin) with a `Main-Class` in its manifest, and point to it with `thin.library`. The launched main class will find the same command line as the launched jar, but with `--thin.library` removed if it was there. It will also find a system property `thin.source` containing the location of the launched jar, or the original `thin.archive` if that was provided on the command line (this is the archive that contains the data to process normally). If the tool jar is thin, i.e. if the main class is `ThinJarWrapper`, then the `thin.archive` command line argument and system property will also be removed (to prevent an infinite loop, where the wrapper just runs itself over and over).\n\nAn example of a tool jar is the `spring-boot-thin-tools-converter` (see below). You could use that as a prototype if you wanted to create your own.\n\n## HOWTO Guides\n\n### How to Externalize the Properties File\n\nExample command line showing to pick up an external properties file:\n\n```\n$ cat config/thin.properties\ndependencies.spring-boot-starter-web: org.springframework.boot:spring-boot-starter-web\n$ java -jar app.jar --thin.location=file:./config\n```\n\n### How to Create a Docker File System Layer\n\nPrecompute the dependencies:\n\n```\n$ java -jar app.jar --thin.root=m2 --thin.dryrun\n$ java -jar app.jar --thin.classpath=properties \u003e thin.properties\n```\n\nThen build a docker image using a `Dockerfile` based on this:\n\n```\nFROM openjdk:8-jdk-alpine\nVOLUME /tmp\n\nADD m2 m2\nADD app.jar app.jar\nADD thin.properties thin.properties\n\nENTRYPOINT [ \"sh\", \"-c\", \"java -Djava.security.egd=file:/dev/./urandom -jar app.jar --thin.root=/m2\" ]\n\nEXPOSE 8080\n```\n\nThe step to add a `thin.properties` is optional, as is its calculation (you could maintain a hand-written properties file inside the JAR as well).\n\n## How to Change Dependencies\n\nYou can change the runtime dependencies, by changing the\n`thin.properties` in the jar. You can also read a local\n`thin.properties` from the current working directory, or set a System\nproperty `thin.name` to change the local file name (defaults to\n`thin`). There is also a `thin.profile` (comma separated list) which\nis appended to `thin.name`, so additional libraries can be added using\n`thin-{profile}.properties`. Profile-specific properties are loaded\nlast so they take precedence. Example to pick up an extra set of\ndependencies in `thin-rabbit.properties`:\n\n```\n$ java -jar myapp.jar --thin.profile=rabbit\n```\n\nProfile-specific `thin.properties` can be saved in the jar file\n(conventionally in `META-INF`), or in the current working directory by\ndefault.\n\nNOTE: You can add or override `thin.properties` entries on the command\nline or with System properties using key names in `thin.properties.*`\n(the prefix `thin.properties.` is stripped).\n\n## How to Upgrade Spring Boot or Spring Cloud\n\nIf your main pom (or properties) file uses boms to manage dependency\nversions, you can change the version of the bom using\n`thin.properties`. E.g.\n\n```\nboms.spring-boot-dependencies=org.springframework.boot:spring-boot-dependencies:2.2.4.RELEASE\n...\n```\n\nIf your main pom uses properties to manage dependencies (e.g. via the\nSpring Boot starter parent), you can change the value of the property\nusing `thin.properties`. E.g.\n\n```\nspring-boot.version=2.2.4.RELEASE\nspring-cloud.version=Hoxton.SR1\n```\n\nwhere the pom has\n\n```\n\u003cdependencyManagement\u003e\n  \u003cdependencies\u003e\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n      \u003cartifactId\u003espring-boot-dependencies\u003c/artifactId\u003e\n      \u003cversion\u003e${spring-boot.version}\u003c/version\u003e\n      \u003ctype\u003epom\u003c/type\u003e\n      \u003cscope\u003eimport\u003c/scope\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.springframework.cloud\u003c/groupId\u003e\n      \u003cartifactId\u003espring-cloud-dependencies\u003c/artifactId\u003e\n      \u003cversion\u003e${spring-cloud.version}\u003c/version\u003e\n      \u003ctype\u003epom\u003c/type\u003e\n      \u003cscope\u003eimport\u003c/scope\u003e\n    \u003c/dependency\u003e\n  \u003c/dependencies\u003e\n\u003c/dependencyManagement\u003e\n```\n\n## How to Exclude a Transitive Dependency\n\nYou can exclude and remove dependencies\nby prepending a key in the properties file with `exclusions.`. E.g.\n\n```\ndependencies.spring-boot-starter-web=org.springframework.boot:spring-boot-starter-web\ndependencies.spring-boot-starter-jetty=org.springframework.boot:spring-boot-starter-jetty\nexclusions.spring-cloud-starter-tomcat=org.springframework.boot:spring-cloud-starter-tomcat\n```\n\n## How to Convert a Thin Jar to a Fat Jar\n\nThere is a converter tool that you can use as a library in place of the launcher. It works by copying all of the libraries from a `thin.root` into the new jar. Example:\n\n```\n$ java -jar myapp.jar --thin.dryrun --thin.root=target/thin/root\n$ java -jar myapp.jar --thin.library=org.springframework.boot.experimental:spring-boot-thin-tools-converter:1.0.31.RELEASE\n$ java -jar myapp-exec.jar\n```\n\n## Building\n\nTo build this project locally, use the maven wrapper in the top level\n\n```\n$ ./mvnw clean install\n```\n\nThen run the \"app\" jar:\n\n```\n$ java -jar ./app/target/*.jar\n```\n\n(It starts an empty Spring Boot app with Tomcat.)\n\nYou can also build the samples independently.\n\n## Classpath Computation\n\nThe launcher has some optional arguments that result in classpath\ncomputations, instead of running the Boot app. E.g.\n\n```\n$ java -jar myapp.jar --thin.classpath=path\n```\n\nprints out (on stdout) a class path in the form that can be used\ndirectly in `java -cp`. So this is a way to run the app from its main\nmethod (which is faster than using the launcher):\n\n```\n$ CLASSPATH=`java -jar myapp.jar --thin.classpath=path`\n$ java -cp \"$CLASSPATH:myapp.jar\" demo.MyApplication\n```\n\nYou can also compute the classpath using explicit name and profile parameters:\n\n```\n$ java -jar myapp.jar --thin.classpath=path --thin.name=app --thin.profile=dev\n```\n\nwill look for `app.properties` and `app-dev.properties` to list the dependencies.\n\nYou can also specify a \"parent\" archive which is used to calculate a\nprefix for the classpath. Two apps that share a parent then have the\nsame prefix, and can share classes using `-Xshare:on`. For example:\n\n```\n$ CP1=`java -jar myapp.jar --thin.classpath=path`\n$ CP2=`java -jar otherapp.jar --thin.classpath=path --thin.parent=myapp.jar`\n\n$ java -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -Xshare:off \\\n  -XX:DumpLoadedClassList=app.classlist \\\n  -noverify -cp $CP1:myapp.jar demo.MyApplication\n$ java -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -Xshare:dump \\\n  -XX:SharedArchiveFile=app.jsa -XX:SharedClassListFile=app.classlist \\\n  -noverify -cp $CP1\n\n$ java -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -Xshare:on \\\n  -XX:SharedArchiveFile=app.jsa -noverify -cp $CP1:myapp.jar demo.MyApplication\n$ java -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -Xshare:on \\\n  -XX:SharedArchiveFile=app.jsa -noverify -cp $CP1:otherapp.jar demo.OtherApplication\n```\n\nthe two apps at the end are sharing class data from `app.jsa` and will\nalso start up faster (e.g. 6s startup goes down to 4s for\na vanilla Eureka Server).\n\nThe thin launcher can be used to pre-compute its own dependency graph in the form of a\nproperties file, which also speeds up the launch a bit, even if you still have to resolve\nall the jars (remotely or from the cache). To compute the dependency graph and output the\nresult in the form of a properties file, just use the `thin.classpath=properties` flag on\nstartup, e.g.\n\n```\n$ java -jar myapp.jar --thin.classpath=properties \u003e thin.properties\n$ java -jar myapp.jar\n```\n\nIn this example the second startup will be slightly faster, depending\non the size of the classpath, but up to a few hundred milliseconds on\neven a fast server, and more in a constrained environment.\n\nIt also works fine with profiles, so, for example, if `myapp.jar`\ncontains a `META-INF/thin-rapid.properties` you could do this:\n\n```\n$ java -jar myapp.jar --thin.profile=rapid --thin.classpath=properties \u003e thin-super.properties\n$ java -jar myapp.jar --thin.profile=super\n```\n\nNote that the generated `thin.properties` in these examples contains the property value\n`computed=true`. This tells the dependency graph calculator that the dependencies provided\ndo not need to have their transitive dependencies or versions computed. It is possible to\ncombine more than one properties file if they have different values of the `computed`\nflag, but if they both also contain dependencies then only the computed ones will be\nused. Note that this means you can compute a profile using `--thin.classpath=properties`\nand use it as a cache, speeding up startup without affecting any other settings that might\nbe in other `thin.properties`.\n\n## How to Change the Maven Local Repository\n\nYou can change the location of the local Maven repository, used to\nresolve and cache artifacts, using the standard Maven `settings.xml`\nfile (with a top level element called `\u003clocalRepository/\u003e`). You can\nalso use a system property `maven.repo.local` (or `maven.home` which\ndefaults to `${user.home}/.m2`) when you launch the thin jar, but not\na command line flag. The Maven and Gradle plugins respond to the\n`settings.xml` and also (with Maven) to `-Dmaven.repo.local` as a\ncommand line flag. When the launcher runs it also looks in `${thin.root}/..`\nfor a `settings.xml` file and uses that in preference to any other location\nif it exists. (For historical reasons it also looks in `${thin.root}/.m2`\nbut that directory is unlikely to exist.)\n\n## How to Configure a Proxy\n\nThe dependency resolution uses Maven libraries, and should respect the\nproxy settings in your `settings.xml`. The initial download of the\nlauncher by the `ThinJarWrapper` uses regular JDK libraries so you\nneed to specify the normal `-D`\n[args for networking as well](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html),\nunless you have the launcher already cached locally.\n\n## Using a Mirror for Maven Central\n\nThe thin launcher itself parses your local Maven `settings.xml` and\nuses the mirror settings there. To download the launcher itself, and\nbootstrap the process, you need to explicitly provide a `thin.repo` to\nthe wrapper (the same as the mirror). You can do this on the command\nline when running the jar, using all the usual mechanisms. To run the\nbuild plugins `resolve` goals you can make the thin launcher jar\na dependency of the plugin, to ensure it is cached locally before the\nplugin runs. E.g.\n\n```\n\u003cpluginManagement\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.springframework.boot.experimental\u003c/groupId\u003e\n            \u003cartifactId\u003espring-boot-thin-maven-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e${wrapper.version}\u003c/version\u003e\n            \u003cdependencies\u003e\n                \u003cdependency\u003e\n                    \u003cgroupId\u003eorg.springframework.boot.experimental\u003c/groupId\u003e\n                    \u003cartifactId\u003espring-boot-thin-launcher\u003c/artifactId\u003e\n                    \u003cclassifier\u003eexec\u003c/classifier\u003e\n                    \u003cversion\u003e${wrapper.version}\u003c/version\u003e\n                \u003c/dependency\u003e\n            \u003c/dependencies\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/pluginManagement\u003e\n```\n\nOr else you can set a project, system property or environment variable. E.g.\n\n```\n$ ./mvnw spring-boot-thin:resolve -Dthin.repo=http://localhost:8081/repository/maven-central\n```\n\nor\n\n```\n$ ./gradlew thinResolve -P thin.repo=http://localhost:8081/repository/maven-central\n```\n\nSystem properties (`thin.repo`) and environment variables (`THIN_REPO`) work too.\n\n## Using a Custom Repository for Dependencies\n\nThe thin launcher will use repository declarations from the `pom.xml`\nin the archive, and also from the `~/.m2/settings.xml` (by default,\nbut can be relocated using `maven.home` or `thin.root`). If you have a\nprivate repository that requires credentials to access it, the best\nchoice is\n[`settings.xml`](https://maven.apache.org/settings.html). This also\napplies to the Gradle plugin because it executes the jar file, and the\nunderlying mechanism is implemented using Maven.\n\n\u003e NOTE: The `thin.repo` setting only applies to the location of the\n\u003e launcher jar itself. If your custom repo is not a mirror it is\n\u003e unlikely to be that location.\n\n## License\n\nThis project is Open Source software released under the\n[Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspring-projects-experimental%2Fspring-boot-thin-launcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspring-projects-experimental%2Fspring-boot-thin-launcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspring-projects-experimental%2Fspring-boot-thin-launcher/lists"}