Migrate spring-boot-docs to Antora
See gh-33766
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
[[appendix.configuration-metadata.annotation-processor]]
|
||||
= Generating Your Own Metadata by Using the Annotation Processor
|
||||
|
||||
You can easily generate your own configuration metadata file from items annotated with `@ConfigurationProperties` by using the `spring-boot-configuration-processor` jar.
|
||||
The jar includes a Java annotation processor which is invoked as your project is compiled.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.annotation-processor.configuring]]
|
||||
== Configuring the Annotation Processor
|
||||
|
||||
To use the processor, include a dependency on `spring-boot-configuration-processor`.
|
||||
|
||||
With Maven the dependency should be declared as optional, as shown in the following example:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
With Gradle, the dependency should be declared in the `annotationProcessor` configuration, as shown in the following example:
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
dependencies {
|
||||
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
|
||||
}
|
||||
----
|
||||
|
||||
If you are using an `additional-spring-configuration-metadata.json` file, the `compileJava` task should be configured to depend on the `processResources` task, as shown in the following example:
|
||||
|
||||
[source,gradle]
|
||||
----
|
||||
tasks.named('compileJava') {
|
||||
inputs.files(tasks.named('processResources'))
|
||||
}
|
||||
----
|
||||
|
||||
This dependency ensures that the additional metadata is available when the annotation processor runs during compilation.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If you are using AspectJ in your project, you need to make sure that the annotation processor runs only once.
|
||||
There are several ways to do this.
|
||||
With Maven, you can configure the `maven-apt-plugin` explicitly and add the dependency to the annotation processor only there.
|
||||
You could also let the AspectJ plugin run all the processing and disable annotation processing in the `maven-compiler-plugin` configuration, as follows:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<proc>none</proc>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If you are using Lombok in your project, you need to make sure that its annotation processor runs before `spring-boot-configuration-processor`.
|
||||
To do so with Maven, you can list the annotation processors in the right order using the `annotationProcessors` attribute of the Maven compiler plugin.
|
||||
If you are not using this attribute, and annotation processors are picked up by the dependencies available on the classpath, make sure that the `lombok` dependency is defined before the `spring-boot-configuration-processor` dependency.
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.annotation-processor.automatic-metadata-generation]]
|
||||
== Automatic Metadata Generation
|
||||
|
||||
The processor picks up both classes and methods that are annotated with `@ConfigurationProperties`.
|
||||
|
||||
If the class has a single parameterized constructor, one property is created per constructor parameter, unless the constructor is annotated with `@Autowired`.
|
||||
If the class has a constructor explicitly annotated with `@ConstructorBinding`, one property is created per constructor parameter for that constructor.
|
||||
Otherwise, properties are discovered through the presence of standard getters and setters with special handling for collection and map types (that is detected even if only a getter is present).
|
||||
The annotation processor also supports the use of the `@Data`, `@Value`, `@Getter`, and `@Setter` lombok annotations.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
include-code::MyServerProperties[]
|
||||
|
||||
This exposes three properties where `my.server.name` has no default and `my.server.ip` and `my.server.port` defaults to `"127.0.0.1"` and `9797` respectively.
|
||||
The Javadoc on fields is used to populate the `description` attribute. For instance, the description of `my.server.ip` is "IP address to listen to.".
|
||||
|
||||
NOTE: You should only use plain text with `@ConfigurationProperties` field Javadoc, since they are not processed before being added to the JSON.
|
||||
|
||||
The annotation processor applies a number of heuristics to extract the default value from the source model.
|
||||
Default values have to be provided statically. In particular, do not refer to a constant defined in another class.
|
||||
Also, the annotation processor cannot auto-detect default values for ``Enum``s and ``Collections``s.
|
||||
|
||||
For cases where the default value could not be detected, xref:configuration-metadata/annotation-processor.adoc#appendix.configuration-metadata.annotation-processor.adding-additional-metadata[manual metadata] should be provided.
|
||||
Consider the following example:
|
||||
|
||||
include-code::MyMessagingProperties[]
|
||||
|
||||
In order to document default values for properties in the class above, you could add the following content to xref:configuration-metadata/annotation-processor.adoc#appendix.configuration-metadata.annotation-processor.adding-additional-metadata[the manual metadata of the module]:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"properties": [
|
||||
{
|
||||
"name": "my.messaging.addresses",
|
||||
"defaultValue": ["a", "b"]
|
||||
},
|
||||
{
|
||||
"name": "my.messaging.container-type",
|
||||
"defaultValue": "simple"
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
NOTE: Only the `name` of the property is required to document additional metadata for existing properties.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.annotation-processor.automatic-metadata-generation.nested-properties]]
|
||||
=== Nested Properties
|
||||
|
||||
The annotation processor automatically considers inner classes as nested properties.
|
||||
Rather than documenting the `ip` and `port` at the root of the namespace, we could create a sub-namespace for it.
|
||||
Consider the updated example:
|
||||
|
||||
include-code::MyServerProperties[]
|
||||
|
||||
The preceding example produces metadata information for `my.server.name`, `my.server.host.ip`, and `my.server.host.port` properties.
|
||||
You can use the `@NestedConfigurationProperty` annotation on a field to indicate that a regular (non-inner) class should be treated as if it were nested.
|
||||
|
||||
TIP: This has no effect on collections and maps, as those types are automatically identified, and a single metadata property is generated for each of them.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.annotation-processor.adding-additional-metadata]]
|
||||
== Adding Additional Metadata
|
||||
|
||||
Spring Boot's configuration file handling is quite flexible, and it is often the case that properties may exist that are not bound to a `@ConfigurationProperties` bean.
|
||||
You may also need to tune some attributes of an existing key.
|
||||
To support such cases and let you provide custom "hints", the annotation processor automatically merges items from `META-INF/additional-spring-configuration-metadata.json` into the main metadata file.
|
||||
|
||||
If you refer to a property that has been detected automatically, the description, default value, and deprecation information are overridden, if specified.
|
||||
If the manual property declaration is not identified in the current module, it is added as a new property.
|
||||
|
||||
The format of the `additional-spring-configuration-metadata.json` file is exactly the same as the regular `spring-configuration-metadata.json`.
|
||||
The additional properties file is optional.
|
||||
If you do not have any additional properties, do not add the file.
|
||||
@@ -0,0 +1,300 @@
|
||||
[[appendix.configuration-metadata.format]]
|
||||
= Metadata Format
|
||||
|
||||
Configuration metadata files are located inside jars under `META-INF/spring-configuration-metadata.json`.
|
||||
They use a JSON format with items categorized under either "`groups`" or "`properties`" and additional values hints categorized under "hints", as shown in the following example:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"groups": [
|
||||
{
|
||||
"name": "server",
|
||||
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
|
||||
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
|
||||
},
|
||||
{
|
||||
"name": "spring.jpa.hibernate",
|
||||
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
|
||||
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
|
||||
"sourceMethod": "getHibernate()"
|
||||
}
|
||||
...
|
||||
],"properties": [
|
||||
{
|
||||
"name": "server.port",
|
||||
"type": "java.lang.Integer",
|
||||
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
|
||||
},
|
||||
{
|
||||
"name": "server.address",
|
||||
"type": "java.net.InetAddress",
|
||||
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
|
||||
},
|
||||
{
|
||||
"name": "spring.jpa.hibernate.ddl-auto",
|
||||
"type": "java.lang.String",
|
||||
"description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
|
||||
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
|
||||
}
|
||||
...
|
||||
],"hints": [
|
||||
{
|
||||
"name": "spring.jpa.hibernate.ddl-auto",
|
||||
"values": [
|
||||
{
|
||||
"value": "none",
|
||||
"description": "Disable DDL handling."
|
||||
},
|
||||
{
|
||||
"value": "validate",
|
||||
"description": "Validate the schema, make no changes to the database."
|
||||
},
|
||||
{
|
||||
"value": "update",
|
||||
"description": "Update the schema if necessary."
|
||||
},
|
||||
{
|
||||
"value": "create",
|
||||
"description": "Create the schema and destroy previous data."
|
||||
},
|
||||
{
|
||||
"value": "create-drop",
|
||||
"description": "Create and then destroy the schema at the end of the session."
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
Each "`property`" is a configuration item that the user specifies with a given value.
|
||||
For example, `server.port` and `server.address` might be specified in your `application.properties`/`application.yaml`, as follows:
|
||||
|
||||
[configprops,yaml]
|
||||
----
|
||||
server:
|
||||
port: 9090
|
||||
address: 127.0.0.1
|
||||
----
|
||||
|
||||
The "`groups`" are higher level items that do not themselves specify a value but instead provide a contextual grouping for properties.
|
||||
For example, the `server.port` and `server.address` properties are part of the `server` group.
|
||||
|
||||
NOTE: It is not required that every "`property`" has a "`group`".
|
||||
Some properties might exist in their own right.
|
||||
|
||||
Finally, "`hints`" are additional information used to assist the user in configuring a given property.
|
||||
For example, when a developer is configuring the configprop:spring.jpa.hibernate.ddl-auto[] property, a tool can use the hints to offer some auto-completion help for the `none`, `validate`, `update`, `create`, and `create-drop` values.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.format.group]]
|
||||
== Group Attributes
|
||||
|
||||
The JSON object contained in the `groups` array can contain the attributes shown in the following table:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
| Name | Type | Purpose
|
||||
|
||||
| `name`
|
||||
| String
|
||||
| The full name of the group.
|
||||
This attribute is mandatory.
|
||||
|
||||
| `type`
|
||||
| String
|
||||
| The class name of the data type of the group.
|
||||
For example, if the group were based on a class annotated with `@ConfigurationProperties`, the attribute would contain the fully qualified name of that class.
|
||||
If it were based on a `@Bean` method, it would be the return type of that method.
|
||||
If the type is not known, the attribute may be omitted.
|
||||
|
||||
| `description`
|
||||
| String
|
||||
| A short description of the group that can be displayed to users.
|
||||
If no description is available, it may be omitted.
|
||||
It is recommended that descriptions be short paragraphs, with the first line providing a concise summary.
|
||||
The last line in the description should end with a period (`.`).
|
||||
|
||||
| `sourceType`
|
||||
| String
|
||||
| The class name of the source that contributed this group.
|
||||
For example, if the group were based on a `@Bean` method annotated with `@ConfigurationProperties`, this attribute would contain the fully qualified name of the `@Configuration` class that contains the method.
|
||||
If the source type is not known, the attribute may be omitted.
|
||||
|
||||
| `sourceMethod`
|
||||
| String
|
||||
| The full name of the method (include parenthesis and argument types) that contributed this group (for example, the name of a `@ConfigurationProperties` annotated `@Bean` method).
|
||||
If the source method is not known, it may be omitted.
|
||||
|===
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.format.property]]
|
||||
== Property Attributes
|
||||
|
||||
The JSON object contained in the `properties` array can contain the attributes described in the following table:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
| Name | Type | Purpose
|
||||
|
||||
| `name`
|
||||
| String
|
||||
| The full name of the property.
|
||||
Names are in lower-case period-separated form (for example, `server.address`).
|
||||
This attribute is mandatory.
|
||||
|
||||
| `type`
|
||||
| String
|
||||
| The full signature of the data type of the property (for example, `java.lang.String`) but also a full generic type (such as `java.util.Map<java.lang.String,com.example.MyEnum>`).
|
||||
You can use this attribute to guide the user as to the types of values that they can enter.
|
||||
For consistency, the type of a primitive is specified by using its wrapper counterpart (for example, `boolean` becomes `java.lang.Boolean`).
|
||||
Note that this class may be a complex type that gets converted from a `String` as values are bound.
|
||||
If the type is not known, it may be omitted.
|
||||
|
||||
| `description`
|
||||
| String
|
||||
| A short description of the property that can be displayed to users.
|
||||
If no description is available, it may be omitted.
|
||||
It is recommended that descriptions be short paragraphs, with the first line providing a concise summary.
|
||||
The last line in the description should end with a period (`.`).
|
||||
|
||||
| `sourceType`
|
||||
| String
|
||||
| The class name of the source that contributed this property.
|
||||
For example, if the property were from a class annotated with `@ConfigurationProperties`, this attribute would contain the fully qualified name of that class.
|
||||
If the source type is unknown, it may be omitted.
|
||||
|
||||
| `defaultValue`
|
||||
| Object
|
||||
| The default value, which is used if the property is not specified.
|
||||
If the type of the property is an array, it can be an array of value(s).
|
||||
If the default value is unknown, it may be omitted.
|
||||
|
||||
| `deprecation`
|
||||
| Deprecation
|
||||
| Specify whether the property is deprecated.
|
||||
If the field is not deprecated or if that information is not known, it may be omitted.
|
||||
The next table offers more detail about the `deprecation` attribute.
|
||||
|===
|
||||
|
||||
The JSON object contained in the `deprecation` attribute of each `properties` element can contain the following attributes:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
| Name | Type | Purpose
|
||||
|
||||
| `level`
|
||||
| String
|
||||
| The level of deprecation, which can be either `warning` (the default) or `error`.
|
||||
When a property has a `warning` deprecation level, it should still be bound in the environment.
|
||||
However, when it has an `error` deprecation level, the property is no longer managed and is not bound.
|
||||
|
||||
| `reason`
|
||||
| String
|
||||
| A short description of the reason why the property was deprecated.
|
||||
If no reason is available, it may be omitted.
|
||||
It is recommended that descriptions be short paragraphs, with the first line providing a concise summary.
|
||||
The last line in the description should end with a period (`.`).
|
||||
|
||||
| `replacement`
|
||||
| String
|
||||
| The full name of the property that _replaces_ this deprecated property.
|
||||
If there is no replacement for this property, it may be omitted.
|
||||
|
||||
| `since`
|
||||
| String
|
||||
| The version in which the property became deprecated.
|
||||
Can be omitted.
|
||||
|===
|
||||
|
||||
NOTE: Prior to Spring Boot 1.3, a single `deprecated` boolean attribute can be used instead of the `deprecation` element.
|
||||
This is still supported in a deprecated fashion and should no longer be used.
|
||||
If no reason and replacement are available, an empty `deprecation` object should be set.
|
||||
|
||||
Deprecation can also be specified declaratively in code by adding the `@DeprecatedConfigurationProperty` annotation to the getter exposing the deprecated property.
|
||||
For instance, assume that the `my.app.target` property was confusing and was renamed to `my.app.name`.
|
||||
The following example shows how to handle that situation:
|
||||
|
||||
include-code::MyProperties[]
|
||||
|
||||
NOTE: There is no way to set a `level`.
|
||||
`warning` is always assumed, since code is still handling the property.
|
||||
|
||||
The preceding code makes sure that the deprecated property still works (delegating to the `name` property behind the scenes).
|
||||
Once the `getTarget` and `setTarget` methods can be removed from your public API, the automatic deprecation hint in the metadata goes away as well.
|
||||
If you want to keep a hint, adding manual metadata with an `error` deprecation level ensures that users are still informed about that property.
|
||||
Doing so is particularly useful when a `replacement` is provided.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.format.hints]]
|
||||
== Hint Attributes
|
||||
|
||||
The JSON object contained in the `hints` array can contain the attributes shown in the following table:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
| Name | Type | Purpose
|
||||
|
||||
| `name`
|
||||
| String
|
||||
| The full name of the property to which this hint refers.
|
||||
Names are in lower-case period-separated form (such as `spring.mvc.servlet.path`).
|
||||
If the property refers to a map (such as `system.contexts`), the hint either applies to the _keys_ of the map (`system.contexts.keys`) or the _values_ (`system.contexts.values`) of the map.
|
||||
This attribute is mandatory.
|
||||
|
||||
| `values`
|
||||
| ValueHint[]
|
||||
| A list of valid values as defined by the `ValueHint` object (described in the next table).
|
||||
Each entry defines the value and may have a description.
|
||||
|
||||
| `providers`
|
||||
| ValueProvider[]
|
||||
| A list of providers as defined by the `ValueProvider` object (described later in this document).
|
||||
Each entry defines the name of the provider and its parameters, if any.
|
||||
|===
|
||||
|
||||
The JSON object contained in the `values` attribute of each `hint` element can contain the attributes described in the following table:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
| Name | Type | Purpose
|
||||
|
||||
| `value`
|
||||
| Object
|
||||
| A valid value for the element to which the hint refers.
|
||||
If the type of the property is an array, it can also be an array of value(s).
|
||||
This attribute is mandatory.
|
||||
|
||||
| `description`
|
||||
| String
|
||||
| A short description of the value that can be displayed to users.
|
||||
If no description is available, it may be omitted.
|
||||
It is recommended that descriptions be short paragraphs, with the first line providing a concise summary.
|
||||
The last line in the description should end with a period (`.`).
|
||||
|===
|
||||
|
||||
The JSON object contained in the `providers` attribute of each `hint` element can contain the attributes described in the following table:
|
||||
|
||||
[cols="1,1,4"]
|
||||
|===
|
||||
|Name | Type |Purpose
|
||||
|
||||
| `name`
|
||||
| String
|
||||
| The name of the provider to use to offer additional content assistance for the element to which the hint refers.
|
||||
|
||||
| `parameters`
|
||||
| JSON object
|
||||
| Any additional parameter that the provider supports (check the documentation of the provider for more details).
|
||||
|===
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.format.repeated-items]]
|
||||
== Repeated Metadata Items
|
||||
|
||||
Objects with the same "`property`" and "`group`" name can appear multiple times within a metadata file.
|
||||
For example, you could bind two separate classes to the same prefix, with each having potentially overlapping property names.
|
||||
While the same names appearing in the metadata multiple times should not be common, consumers of metadata should take care to ensure that they support it.
|
||||
@@ -0,0 +1,9 @@
|
||||
[appendix]
|
||||
[[appendix.configuration-metadata]]
|
||||
= Configuration Metadata
|
||||
|
||||
Spring Boot jars include metadata files that provide details of all supported configuration properties.
|
||||
The files are designed to let IDE developers offer contextual help and "`code completion`" as users are working with `application.properties` or `application.yaml` files.
|
||||
|
||||
The majority of the metadata file is generated automatically at compile time by processing all items annotated with `@ConfigurationProperties`.
|
||||
However, it is possible to xref:configuration-metadata/annotation-processor.adoc#appendix.configuration-metadata.annotation-processor.adding-additional-metadata[write part of the metadata manually] for corner cases or more advanced use cases.
|
||||
@@ -0,0 +1,375 @@
|
||||
[[appendix.configuration-metadata.manual-hints]]
|
||||
= Providing Manual Hints
|
||||
|
||||
To improve the user experience and further assist the user in configuring a given property, you can provide additional metadata that:
|
||||
|
||||
* Describes the list of potential values for a property.
|
||||
* Associates a provider, to attach a well defined semantic to a property, so that a tool can discover the list of potential values based on the project's context.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-hint]]
|
||||
== Value Hint
|
||||
|
||||
The `name` attribute of each hint refers to the `name` of a property.
|
||||
In the xref:configuration-metadata/format.adoc[initial example shown earlier], we provide five values for the `spring.jpa.hibernate.ddl-auto` property: `none`, `validate`, `update`, `create`, and `create-drop`.
|
||||
Each value may have a description as well.
|
||||
|
||||
If your property is of type `Map`, you can provide hints for both the keys and the values (but not for the map itself).
|
||||
The special `.keys` and `.values` suffixes must refer to the keys and the values, respectively.
|
||||
|
||||
Assume a `my.contexts` maps magic `String` values to an integer, as shown in the following example:
|
||||
|
||||
include-code::MyProperties[]
|
||||
|
||||
The magic values are (in this example) are `sample1` and `sample2`.
|
||||
In order to offer additional content assistance for the keys, you could add the following JSON to xref:configuration-metadata/annotation-processor.adoc#appendix.configuration-metadata.annotation-processor.adding-additional-metadata[the manual metadata of the module]:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "my.contexts.keys",
|
||||
"values": [
|
||||
{
|
||||
"value": "sample1"
|
||||
},
|
||||
{
|
||||
"value": "sample2"
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
TIP: We recommend that you use an `Enum` for those two values instead.
|
||||
If your IDE supports it, this is by far the most effective approach to auto-completion.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers]]
|
||||
== Value Providers
|
||||
|
||||
Providers are a powerful way to attach semantics to a property.
|
||||
In this section, we define the official providers that you can use for your own hints.
|
||||
However, your favorite IDE may implement some of these or none of them.
|
||||
Also, it could eventually provide its own.
|
||||
|
||||
NOTE: As this is a new feature, IDE vendors must catch up with how it works.
|
||||
Adoption times naturally vary.
|
||||
|
||||
The following table summarizes the list of supported providers:
|
||||
|
||||
[cols="2,4"]
|
||||
|===
|
||||
| Name | Description
|
||||
|
||||
| `any`
|
||||
| Permits any additional value to be provided.
|
||||
|
||||
| `class-reference`
|
||||
| Auto-completes the classes available in the project.
|
||||
Usually constrained by a base class that is specified by the `target` parameter.
|
||||
|
||||
| `handle-as`
|
||||
| Handles the property as if it were defined by the type defined by the mandatory `target` parameter.
|
||||
|
||||
| `logger-name`
|
||||
| Auto-completes valid logger names and xref:reference:features/logging.adoc#features.logging.log-groups[logger groups].
|
||||
Typically, package and class names available in the current project can be auto-completed as well as defined groups.
|
||||
|
||||
| `spring-bean-reference`
|
||||
| Auto-completes the available bean names in the current project.
|
||||
Usually constrained by a base class that is specified by the `target` parameter.
|
||||
|
||||
| `spring-profile-name`
|
||||
| Auto-completes the available Spring profile names in the project.
|
||||
|===
|
||||
|
||||
TIP: Only one provider can be active for a given property, but you can specify several providers if they can all manage the property _in some way_.
|
||||
Make sure to place the most powerful provider first, as the IDE must use the first one in the JSON section that it can handle.
|
||||
If no provider for a given property is supported, no special content assistance is provided, either.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.any]]
|
||||
=== Any
|
||||
|
||||
The special **any** provider value permits any additional values to be provided.
|
||||
Regular value validation based on the property type should be applied if this is supported.
|
||||
|
||||
This provider is typically used if you have a list of values and any extra values should still be considered as valid.
|
||||
|
||||
The following example offers `on` and `off` as auto-completion values for `system.state`:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "system.state",
|
||||
"values": [
|
||||
{
|
||||
"value": "on"
|
||||
},
|
||||
{
|
||||
"value": "off"
|
||||
}
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"name": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
Note that, in the preceding example, any other value is also allowed.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.class-reference]]
|
||||
=== Class Reference
|
||||
|
||||
The **class-reference** provider auto-completes classes available in the project.
|
||||
This provider supports the following parameters:
|
||||
|
||||
[cols="1,1,2,4"]
|
||||
|===
|
||||
| Parameter | Type | Default value | Description
|
||||
|
||||
| `target`
|
||||
| `String` (`Class`)
|
||||
| _none_
|
||||
| The fully qualified name of the class that should be assignable to the chosen value.
|
||||
Typically used to filter out-non candidate classes.
|
||||
Note that this information can be provided by the type itself by exposing a class with the appropriate upper bound.
|
||||
|
||||
| `concrete`
|
||||
| `boolean`
|
||||
| true
|
||||
| Specify whether only concrete classes are to be considered as valid candidates.
|
||||
|===
|
||||
|
||||
|
||||
The following metadata snippet corresponds to the standard `server.servlet.jsp.class-name` property that defines the `JspServlet` class name to use:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "server.servlet.jsp.class-name",
|
||||
"providers": [
|
||||
{
|
||||
"name": "class-reference",
|
||||
"parameters": {
|
||||
"target": "jakarta.servlet.http.HttpServlet"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.handle-as]]
|
||||
=== Handle As
|
||||
|
||||
The **handle-as** provider lets you substitute the type of the property to a more high-level type.
|
||||
This typically happens when the property has a `java.lang.String` type, because you do not want your configuration classes to rely on classes that may not be on the classpath.
|
||||
This provider supports the following parameters:
|
||||
|
||||
[cols="1,1,2,4"]
|
||||
|===
|
||||
| Parameter | Type | Default value | Description
|
||||
|
||||
| **`target`**
|
||||
| `String` (`Class`)
|
||||
| _none_
|
||||
| The fully qualified name of the type to consider for the property.
|
||||
This parameter is mandatory.
|
||||
|===
|
||||
|
||||
The following types can be used:
|
||||
|
||||
* Any `java.lang.Enum`: Lists the possible values for the property.
|
||||
(We recommend defining the property with the `Enum` type, as no further hint should be required for the IDE to auto-complete the values)
|
||||
* `java.nio.charset.Charset`: Supports auto-completion of charset/encoding values (such as `UTF-8`)
|
||||
* `java.util.Locale`: auto-completion of locales (such as `en_US`)
|
||||
* `org.springframework.util.MimeType`: Supports auto-completion of content type values (such as `text/plain`)
|
||||
* `org.springframework.core.io.Resource`: Supports auto-completion of Spring’s Resource abstraction to refer to a file on the filesystem or on the classpath (such as `classpath:/sample.properties`)
|
||||
|
||||
TIP: If multiple values can be provided, use a `Collection` or _Array_ type to teach the IDE about it.
|
||||
|
||||
The following metadata snippet corresponds to the standard `spring.liquibase.change-log` property that defines the path to the changelog to use.
|
||||
It is actually used internally as a `org.springframework.core.io.Resource` but cannot be exposed as such, because we need to keep the original String value to pass it to the Liquibase API.
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "spring.liquibase.change-log",
|
||||
"providers": [
|
||||
{
|
||||
"name": "handle-as",
|
||||
"parameters": {
|
||||
"target": "org.springframework.core.io.Resource"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.logger-name]]
|
||||
=== Logger Name
|
||||
|
||||
The **logger-name** provider auto-completes valid logger names and xref:reference:features/logging.adoc#features.logging.log-groups[logger groups].
|
||||
Typically, package and class names available in the current project can be auto-completed.
|
||||
If groups are enabled (default) and if a custom logger group is identified in the configuration, auto-completion for it should be provided.
|
||||
Specific frameworks may have extra magic logger names that can be supported as well.
|
||||
|
||||
This provider supports the following parameters:
|
||||
|
||||
[cols="1,1,2,4"]
|
||||
|===
|
||||
| Parameter | Type | Default value | Description
|
||||
|
||||
| `group`
|
||||
| `boolean`
|
||||
| `true`
|
||||
| Specify whether known groups should be considered.
|
||||
|===
|
||||
|
||||
Since a logger name can be any arbitrary name, this provider should allow any value but could highlight valid package and class names that are not available in the project's classpath.
|
||||
|
||||
The following metadata snippet corresponds to the standard `logging.level` property.
|
||||
Keys are _logger names_, and values correspond to the standard log levels or any custom level.
|
||||
As Spring Boot defines a few logger groups out-of-the-box, dedicated value hints have been added for those.
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "logging.level.keys",
|
||||
"values": [
|
||||
{
|
||||
"value": "root",
|
||||
"description": "Root logger used to assign the default logging level."
|
||||
},
|
||||
{
|
||||
"value": "sql",
|
||||
"description": "SQL logging group including Hibernate SQL logger."
|
||||
},
|
||||
{
|
||||
"value": "web",
|
||||
"description": "Web logging group including codecs."
|
||||
}
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"name": "logger-name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "logging.level.values",
|
||||
"values": [
|
||||
{
|
||||
"value": "trace"
|
||||
},
|
||||
{
|
||||
"value": "debug"
|
||||
},
|
||||
{
|
||||
"value": "info"
|
||||
},
|
||||
{
|
||||
"value": "warn"
|
||||
},
|
||||
{
|
||||
"value": "error"
|
||||
},
|
||||
{
|
||||
"value": "fatal"
|
||||
},
|
||||
{
|
||||
"value": "off"
|
||||
}
|
||||
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"name": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.spring-bean-reference]]
|
||||
=== Spring Bean Reference
|
||||
|
||||
The **spring-bean-reference** provider auto-completes the beans that are defined in the configuration of the current project.
|
||||
This provider supports the following parameters:
|
||||
|
||||
[cols="1,1,2,4"]
|
||||
|===
|
||||
| Parameter | Type | Default value | Description
|
||||
|
||||
| `target`
|
||||
| `String` (`Class`)
|
||||
| _none_
|
||||
| The fully qualified name of the bean class that should be assignable to the candidate.
|
||||
Typically used to filter out non-candidate beans.
|
||||
|===
|
||||
|
||||
The following metadata snippet corresponds to the standard `spring.jmx.server` property that defines the name of the `MBeanServer` bean to use:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "spring.jmx.server",
|
||||
"providers": [
|
||||
{
|
||||
"name": "spring-bean-reference",
|
||||
"parameters": {
|
||||
"target": "javax.management.MBeanServer"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
|
||||
NOTE: The binder is not aware of the metadata.
|
||||
If you provide that hint, you still need to transform the bean name into an actual Bean reference using by the `ApplicationContext`.
|
||||
|
||||
|
||||
|
||||
[[appendix.configuration-metadata.manual-hints.value-providers.spring-profile-name]]
|
||||
=== Spring Profile Name
|
||||
|
||||
The **spring-profile-name** provider auto-completes the Spring profiles that are defined in the configuration of the current project.
|
||||
|
||||
The following metadata snippet corresponds to the standard `spring.profiles.active` property that defines the name of the Spring profile(s) to enable:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{"hints": [
|
||||
{
|
||||
"name": "spring.profiles.active",
|
||||
"providers": [
|
||||
{
|
||||
"name": "spring-profile-name"
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
----
|
||||
@@ -0,0 +1,10 @@
|
||||
[[appendix.executable-jar.alternatives]]
|
||||
= Alternative Single Jar Solutions
|
||||
|
||||
If the preceding restrictions mean that you cannot use Spring Boot Loader, consider the following alternatives:
|
||||
|
||||
* https://maven.apache.org/plugins/maven-shade-plugin/[Maven Shade Plugin]
|
||||
* http://www.jdotsoft.com/JarClassLoader.php[JarClassLoader]
|
||||
* https://sourceforge.net/projects/one-jar/[OneJar]
|
||||
* https://imperceptiblethoughts.com/shadow/[Gradle Shadow Plugin]
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[appendix]
|
||||
[[appendix.executable-jar]]
|
||||
= The Executable Jar Format
|
||||
|
||||
The `spring-boot-loader` modules lets Spring Boot support executable jar and war files.
|
||||
If you use the Maven plugin or the Gradle plugin, executable jars are automatically generated, and you generally do not need to know the details of how they work.
|
||||
|
||||
If you need to create executable jars from a different build system or if you are just curious about the underlying technology, this appendix provides some background.
|
||||
@@ -0,0 +1,36 @@
|
||||
[[appendix.executable-jar.jarfile-class]]
|
||||
= Spring Boot's "`NestedJarFile`" Class
|
||||
|
||||
The core class used to support loading nested jars is `org.springframework.boot.loader.jar.NestedJarFile`.
|
||||
It lets you load jar content from nested child jar data.
|
||||
When first loaded, the location of each `JarEntry` is mapped to a physical file offset of the outer jar, as shown in the following example:
|
||||
|
||||
[source]
|
||||
----
|
||||
myapp.jar
|
||||
+-------------------+-------------------------+
|
||||
| /BOOT-INF/classes | /BOOT-INF/lib/mylib.jar |
|
||||
|+-----------------+||+-----------+----------+|
|
||||
|| A.class ||| B.class | C.class ||
|
||||
|+-----------------+||+-----------+----------+|
|
||||
+-------------------+-------------------------+
|
||||
^ ^ ^
|
||||
0063 3452 3980
|
||||
----
|
||||
|
||||
The preceding example shows how `A.class` can be found in `/BOOT-INF/classes` in `myapp.jar` at position `0063`.
|
||||
`B.class` from the nested jar can actually be found in `myapp.jar` at position `3452`, and `C.class` is at position `3980`.
|
||||
|
||||
Armed with this information, we can load specific nested entries by seeking to the appropriate part of the outer jar.
|
||||
We do not need to unpack the archive, and we do not need to read all entry data into memory.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.jarfile-class.compatibility]]
|
||||
== Compatibility With the Standard Java "`JarFile`"
|
||||
|
||||
Spring Boot Loader strives to remain compatible with existing code and libraries.
|
||||
`org.springframework.boot.loader.jar.NestedJarFile` extends from `java.util.jar.JarFile` and should work as a drop-in replacement.
|
||||
|
||||
Nested JAR URLs of the form `jar:nested:/path/myjar.jar/!BOOT-INF/lib/mylib.jar!/B.class` are supported and open a connection compatible with `java.net.JarURLConnection`.
|
||||
These can be used with Java's `URLClassLoader`.
|
||||
@@ -0,0 +1,41 @@
|
||||
[[appendix.executable-jar.launching]]
|
||||
= Launching Executable Jars
|
||||
|
||||
The `org.springframework.boot.loader.launch.Launcher` class is a special bootstrap class that is used as an executable jar's main entry point.
|
||||
It is the actual `Main-Class` in your jar file, and it is used to setup an appropriate `ClassLoader` and ultimately call your `main()` method.
|
||||
|
||||
There are three launcher subclasses (`JarLauncher`, `WarLauncher`, and `PropertiesLauncher`).
|
||||
Their purpose is to load resources (`.class` files and so on) from nested jar files or war files in directories (as opposed to those explicitly on the classpath).
|
||||
In the case of `JarLauncher` and `WarLauncher`, the nested paths are fixed.
|
||||
`JarLauncher` looks in `BOOT-INF/lib/`, and `WarLauncher` looks in `WEB-INF/lib/` and `WEB-INF/lib-provided/`.
|
||||
You can add extra jars in those locations if you want more.
|
||||
|
||||
The `PropertiesLauncher` looks in `BOOT-INF/lib/` in your application archive by default.
|
||||
You can add additional locations by setting an environment variable called `LOADER_PATH` or `loader.path` in `loader.properties` (which is a comma-separated list of directories, archives, or directories within archives).
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.launching.manifest]]
|
||||
== Launcher Manifest
|
||||
|
||||
You need to specify an appropriate `Launcher` as the `Main-Class` attribute of `META-INF/MANIFEST.MF`.
|
||||
The actual class that you want to launch (that is, the class that contains a `main` method) should be specified in the `Start-Class` attribute.
|
||||
|
||||
The following example shows a typical `MANIFEST.MF` for an executable jar file:
|
||||
|
||||
[source,manifest]
|
||||
----
|
||||
Main-Class: org.springframework.boot.loader.launch.JarLauncher
|
||||
Start-Class: com.mycompany.project.MyApplication
|
||||
----
|
||||
|
||||
For a war file, it would be as follows:
|
||||
|
||||
[source,manifest]
|
||||
----
|
||||
Main-Class: org.springframework.boot.loader.launch.WarLauncher
|
||||
Start-Class: com.mycompany.project.MyApplication
|
||||
----
|
||||
|
||||
NOTE: You need not specify `Class-Path` entries in your manifest file.
|
||||
The classpath is deduced from the nested jars.
|
||||
@@ -0,0 +1,149 @@
|
||||
[[appendix.executable-jar.nested-jars]]
|
||||
= Nested JARs
|
||||
|
||||
Java does not provide any standard way to load nested jar files (that is, jar files that are themselves contained within a jar).
|
||||
This can be problematic if you need to distribute a self-contained application that can be run from the command line without unpacking.
|
||||
|
||||
To solve this problem, many developers use "`shaded`" jars.
|
||||
A shaded jar packages all classes, from all jars, into a single "`uber jar`".
|
||||
The problem with shaded jars is that it becomes hard to see which libraries are actually in your application.
|
||||
It can also be problematic if the same filename is used (but with different content) in multiple jars.
|
||||
Spring Boot takes a different approach and lets you actually nest jars directly.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.nested-jars.jar-structure]]
|
||||
== The Executable Jar File Structure
|
||||
|
||||
Spring Boot Loader-compatible jar files should be structured in the following way:
|
||||
|
||||
[source]
|
||||
----
|
||||
example.jar
|
||||
|
|
||||
+-META-INF
|
||||
| +-MANIFEST.MF
|
||||
+-org
|
||||
| +-springframework
|
||||
| +-boot
|
||||
| +-loader
|
||||
| +-<spring boot loader classes>
|
||||
+-BOOT-INF
|
||||
+-classes
|
||||
| +-mycompany
|
||||
| +-project
|
||||
| +-YourClasses.class
|
||||
+-lib
|
||||
+-dependency1.jar
|
||||
+-dependency2.jar
|
||||
----
|
||||
|
||||
Application classes should be placed in a nested `BOOT-INF/classes` directory.
|
||||
Dependencies should be placed in a nested `BOOT-INF/lib` directory.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.nested-jars.war-structure]]
|
||||
== The Executable War File Structure
|
||||
|
||||
Spring Boot Loader-compatible war files should be structured in the following way:
|
||||
|
||||
[source]
|
||||
----
|
||||
example.war
|
||||
|
|
||||
+-META-INF
|
||||
| +-MANIFEST.MF
|
||||
+-org
|
||||
| +-springframework
|
||||
| +-boot
|
||||
| +-loader
|
||||
| +-<spring boot loader classes>
|
||||
+-WEB-INF
|
||||
+-classes
|
||||
| +-com
|
||||
| +-mycompany
|
||||
| +-project
|
||||
| +-YourClasses.class
|
||||
+-lib
|
||||
| +-dependency1.jar
|
||||
| +-dependency2.jar
|
||||
+-lib-provided
|
||||
+-servlet-api.jar
|
||||
+-dependency3.jar
|
||||
----
|
||||
|
||||
Dependencies should be placed in a nested `WEB-INF/lib` directory.
|
||||
Any dependencies that are required when running embedded but are not required when deploying to a traditional web container should be placed in `WEB-INF/lib-provided`.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.nested-jars.index-files]]
|
||||
== Index Files
|
||||
|
||||
Spring Boot Loader-compatible jar and war archives can include additional index files under the `BOOT-INF/` directory.
|
||||
A `classpath.idx` file can be provided for both jars and wars, and it provides the ordering that jars should be added to the classpath.
|
||||
The `layers.idx` file can be used only for jars, and it allows a jar to be split into logical layers for Docker/OCI image creation.
|
||||
|
||||
Index files follow a YAML compatible syntax so that they can be easily parsed by third-party tools.
|
||||
These files, however, are _not_ parsed internally as YAML and they must be written in exactly the formats described below in order to be used.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.nested-jars.classpath-index]]
|
||||
== Classpath Index
|
||||
|
||||
The classpath index file can be provided in `BOOT-INF/classpath.idx`.
|
||||
Typically, it is generated automatically by Spring Boot's Maven and Gradle build plugins.
|
||||
It provides a list of jar names (including the directory) in the order that they should be added to the classpath.
|
||||
When generated by the build plugins, this classpath ordering matches that used by the build system for running and testing the application.
|
||||
Each line must start with dash space (`"-·"`) and names must be in double quotes.
|
||||
|
||||
For example, given the following jar:
|
||||
|
||||
[source]
|
||||
----
|
||||
example.jar
|
||||
|
|
||||
+-META-INF
|
||||
| +-...
|
||||
+-BOOT-INF
|
||||
+-classes
|
||||
| +...
|
||||
+-lib
|
||||
+-dependency1.jar
|
||||
+-dependency2.jar
|
||||
----
|
||||
|
||||
The index file would look like this:
|
||||
|
||||
[source]
|
||||
----
|
||||
- "BOOT-INF/lib/dependency2.jar"
|
||||
- "BOOT-INF/lib/dependency1.jar"
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar.nested-jars.layer-index]]
|
||||
== Layer Index
|
||||
|
||||
The layers index file can be provided in `BOOT-INF/layers.idx`.
|
||||
It provides a list of layers and the parts of the jar that should be contained within them.
|
||||
Layers are written in the order that they should be added to the Docker/OCI image.
|
||||
Layers names are written as quoted strings prefixed with dash space (`"-·"`) and with a colon (`":"`) suffix.
|
||||
Layer content is either a file or directory name written as a quoted string prefixed by space space dash space (`"··-·"`).
|
||||
A directory name ends with `/`, a file name does not.
|
||||
When a directory name is used it means that all files inside that directory are in the same layer.
|
||||
|
||||
A typical example of a layers index would be:
|
||||
|
||||
[source]
|
||||
----
|
||||
- "dependencies":
|
||||
- "BOOT-INF/lib/dependency1.jar"
|
||||
- "BOOT-INF/lib/dependency2.jar"
|
||||
- "application":
|
||||
- "BOOT-INF/classes/"
|
||||
- "META-INF/"
|
||||
----
|
||||
@@ -0,0 +1,82 @@
|
||||
[[appendix.executable-jar.property-launcher]]
|
||||
= PropertiesLauncher Features
|
||||
|
||||
`PropertiesLauncher` has a few special features that can be enabled with external properties (System properties, environment variables, manifest entries, or `loader.properties`).
|
||||
The following table describes these properties:
|
||||
|
||||
|===
|
||||
| Key | Purpose
|
||||
|
||||
| `loader.path`
|
||||
| Comma-separated Classpath, such as `lib,$\{HOME}/app/lib`.
|
||||
Earlier entries take precedence, like a regular `-classpath` on the `javac` command line.
|
||||
|
||||
| `loader.home`
|
||||
| Used to resolve relative paths in `loader.path`.
|
||||
For example, given `loader.path=lib`, then `${loader.home}/lib` is a classpath location (along with all jar files in that directory).
|
||||
This property is also used to locate a `loader.properties` file, as in the following example `file:///opt/app` It defaults to `${user.dir}`.
|
||||
|
||||
| `loader.args`
|
||||
| Default arguments for the main method (space separated).
|
||||
|
||||
| `loader.main`
|
||||
| Name of main class to launch (for example, `com.app.Application`).
|
||||
|
||||
| `loader.config.name`
|
||||
| Name of properties file (for example, `launcher`).
|
||||
It defaults to `loader`.
|
||||
|
||||
| `loader.config.location`
|
||||
| Path to properties file (for example, `classpath:loader.properties`).
|
||||
It defaults to `loader.properties`.
|
||||
|
||||
| `loader.system`
|
||||
| Boolean flag to indicate that all properties should be added to System properties.
|
||||
It defaults to `false`.
|
||||
|===
|
||||
|
||||
When specified as environment variables or manifest entries, the following names should be used:
|
||||
|
||||
|===
|
||||
| Key | Manifest entry | Environment variable
|
||||
|
||||
| `loader.path`
|
||||
| `Loader-Path`
|
||||
| `LOADER_PATH`
|
||||
|
||||
| `loader.home`
|
||||
| `Loader-Home`
|
||||
| `LOADER_HOME`
|
||||
|
||||
| `loader.args`
|
||||
| `Loader-Args`
|
||||
| `LOADER_ARGS`
|
||||
|
||||
| `loader.main`
|
||||
| `Start-Class`
|
||||
| `LOADER_MAIN`
|
||||
|
||||
| `loader.config.location`
|
||||
| `Loader-Config-Location`
|
||||
| `LOADER_CONFIG_LOCATION`
|
||||
|
||||
| `loader.system`
|
||||
| `Loader-System`
|
||||
| `LOADER_SYSTEM`
|
||||
|===
|
||||
|
||||
TIP: Build plugins automatically move the `Main-Class` attribute to `Start-Class` when the uber jar is built.
|
||||
If you use that, specify the name of the class to launch by using the `Main-Class` attribute and leaving out `Start-Class`.
|
||||
|
||||
The following rules apply to working with `PropertiesLauncher`:
|
||||
|
||||
* `loader.properties` is searched for in `loader.home`, then in the root of the classpath, and then in `classpath:/BOOT-INF/classes`.
|
||||
The first location where a file with that name exists is used.
|
||||
* `loader.home` is the directory location of an additional properties file (overriding the default) only when `loader.config.location` is not specified.
|
||||
* `loader.path` can contain directories (which are scanned recursively for jar and zip files), archive paths, a directory within an archive that is scanned for jar files (for example, `dependencies.jar!/lib`), or wildcard patterns (for the default JVM behavior).
|
||||
Archive paths can be relative to `loader.home` or anywhere in the file system with a `jar:file:` prefix.
|
||||
* `loader.path` (if empty) defaults to `BOOT-INF/lib` (meaning a local directory or a nested one if running from an archive).
|
||||
Because of this, `PropertiesLauncher` behaves the same as `JarLauncher` when no additional configuration is provided.
|
||||
* `loader.path` can not be used to configure the location of `loader.properties` (the classpath used to search for the latter is the JVM classpath when `PropertiesLauncher` is launched).
|
||||
* Placeholder replacement is done from System and environment variables plus the properties file itself on all values before use.
|
||||
* The search order for properties (where it makes sense to look in more than one place) is environment variables, system properties, `loader.properties`, the exploded archive manifest, and the archive manifest.
|
||||
@@ -0,0 +1,21 @@
|
||||
[[appendix.executable-jar.restrictions]]
|
||||
= Executable Jar Restrictions
|
||||
|
||||
You need to consider the following restrictions when working with a Spring Boot Loader packaged application:
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar-zip-entry-compression]]
|
||||
* Zip entry compression:
|
||||
The `ZipEntry` for a nested jar must be saved by using the `ZipEntry.STORED` method.
|
||||
This is required so that we can seek directly to individual content within the nested jar.
|
||||
The content of the nested jar file itself can still be compressed, as can any other entry in the outer jar.
|
||||
|
||||
|
||||
|
||||
[[appendix.executable-jar-system-classloader]]
|
||||
* System classLoader:
|
||||
Launched applications should use `Thread.getContextClassLoader()` when loading classes (most libraries and frameworks do so by default).
|
||||
Trying to load nested jar classes with `ClassLoader.getSystemClassLoader()` fails.
|
||||
`java.util.Logging` always uses the system classloader.
|
||||
For this reason, you should consider a different logging implementation.
|
||||
@@ -0,0 +1,14 @@
|
||||
* Specifications
|
||||
|
||||
** xref:specification:configuration-metadata/index.adoc[]
|
||||
*** xref:specification:configuration-metadata/format.adoc[]
|
||||
*** xref:specification:configuration-metadata/manual-hints.adoc[]
|
||||
*** xref:specification:configuration-metadata/annotation-processor.adoc[]
|
||||
|
||||
** xref:specification:executable-jar/index.adoc[]
|
||||
*** xref:specification:executable-jar/nested-jars.adoc[]
|
||||
*** xref:specification:executable-jar/jarfile-class.adoc[]
|
||||
*** xref:specification:executable-jar/launching.adoc[]
|
||||
*** xref:specification:executable-jar/property-launcher.adoc[]
|
||||
*** xref:specification:executable-jar/restrictions.adoc[]
|
||||
*** xref:specification:executable-jar/alternatives.adoc[]
|
||||
Reference in New Issue
Block a user