Spring Boot Reference Guide

Authors

Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, Andy Wilkinson, Marcel Overdijk, Christian Dupuis, Sébastien Deleuze, Michael Simons, Vedran Pavić, Jay Bryant, Madhura Bhave

2.1.18.RELEASE

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.


Table of Contents

I. Spring Boot Documentation
1. About the Documentation
2. Getting Help
3. Upgrading from an Earlier Version
4. First Steps
5. Working with Spring Boot
6. Learning about Spring Boot Features
7. Moving to Production
8. Advanced Topics
II. Getting Started
9. Introducing Spring Boot
10. System Requirements
10.1. Servlet Containers
11. Installing Spring Boot
11.1. Installation Instructions for the Java Developer
11.1.1. Maven Installation
11.1.2. Gradle Installation
11.2. Installing the Spring Boot CLI
11.2.1. Manual Installation
11.2.2. Installation with SDKMAN!
11.2.3. OSX Homebrew Installation
11.2.4. MacPorts Installation
11.2.5. Command-line Completion
11.2.6. Windows Scoop Installation
11.2.7. Quick-start Spring CLI Example
11.3. Upgrading from an Earlier Version of Spring Boot
12. Developing Your First Spring Boot Application
12.1. Creating the POM
12.2. Adding Classpath Dependencies
12.3. Writing the Code
12.3.1. The @RestController and @RequestMapping Annotations
12.3.2. The @EnableAutoConfiguration Annotation
12.3.3. The “main” Method
12.4. Running the Example
12.5. Creating an Executable Jar
13. What to Read Next
III. Using Spring Boot
14. Build Systems
14.1. Dependency Management
14.2. Maven
14.2.1. Inheriting the Starter Parent
14.2.2. Using Spring Boot without the Parent POM
14.2.3. Using the Spring Boot Maven Plugin
14.3. Gradle
14.4. Ant
14.5. Starters
15. Structuring Your Code
15.1. Using the “default” Package
15.2. Locating the Main Application Class
16. Configuration Classes
16.1. Importing Additional Configuration Classes
16.2. Importing XML Configuration
17. Auto-configuration
17.1. Gradually Replacing Auto-configuration
17.2. Disabling Specific Auto-configuration Classes
18. Spring Beans and Dependency Injection
19. Using the @SpringBootApplication Annotation
20. Running Your Application
20.1. Running from an IDE
20.2. Running as a Packaged Application
20.3. Using the Maven Plugin
20.4. Using the Gradle Plugin
20.5. Hot Swapping
21. Developer Tools
21.1. Property Defaults
21.2. Automatic Restart
21.2.1. Logging changes in condition evaluation
21.2.2. Excluding Resources
21.2.3. Watching Additional Paths
21.2.4. Disabling Restart
21.2.5. Using a Trigger File
21.2.6. Customizing the Restart Classloader
21.2.7. Known Limitations
21.3. LiveReload
21.4. Global Settings
21.5. Remote Applications
21.5.1. Running the Remote Client Application
21.5.2. Remote Update
21.5.3. Configuring File System Watcher
21.5.4. Security Configuration for Devtools Remote
22. Packaging Your Application for Production
23. What to Read Next
IV. Spring Boot features
24. SpringApplication
24.1. Startup Failure
24.2. Customizing the Banner
24.3. Customizing SpringApplication
24.4. Fluent Builder API
24.5. Application Events and Listeners
24.6. Web Environment
24.7. Accessing Application Arguments
24.8. Using the ApplicationRunner or CommandLineRunner
24.9. Application Exit
24.10. Admin Features
25. Externalized Configuration
25.1. Configuring Random Values
25.2. Accessing Command Line Properties
25.3. Application Property Files
25.4. Profile-specific Properties
25.5. Placeholders in Properties
25.6. Encrypting Properties
25.7. Using YAML Instead of Properties
25.7.1. Loading YAML
25.7.2. Exposing YAML as Properties in the Spring Environment
25.7.3. Multi-profile YAML Documents
25.7.4. YAML Shortcomings
25.8. Type-safe Configuration Properties
25.8.1. Third-party Configuration
25.8.2. Relaxed Binding
Binding Maps
Binding from Environment Variables
25.8.3. Merging Complex Types
25.8.4. Properties Conversion
Converting durations
Converting Data Sizes
25.8.5. @ConfigurationProperties Validation
25.8.6. @ConfigurationProperties vs. @Value
26. Profiles
26.1. Adding Active Profiles
26.2. Programmatically Setting Profiles
26.3. Profile-specific Configuration Files
27. Logging
27.1. Log Format
27.2. Console Output
27.2.1. Color-coded Output
27.3. File Output
27.4. Log Levels
27.5. Log Groups
27.6. Custom Log Configuration
27.7. Logback Extensions
27.7.1. Profile-specific Configuration
27.7.2. Environment Properties
28. Internationalization
29. JSON
29.1. Jackson
29.2. Gson
29.3. JSON-B
30. Developing Web Applications
30.1. The “Spring Web MVC Framework”
30.1.1. Spring MVC Auto-configuration
30.1.2. HttpMessageConverters
30.1.3. Custom JSON Serializers and Deserializers
30.1.4. MessageCodesResolver
30.1.5. Static Content
30.1.6. Welcome Page
30.1.7. Custom Favicon
30.1.8. Path Matching and Content Negotiation
30.1.9. ConfigurableWebBindingInitializer
30.1.10. Template Engines
30.1.11. Error Handling
Custom Error Pages
Mapping Error Pages outside of Spring MVC
Error handling in a war deployment
30.1.12. Spring HATEOAS
30.1.13. CORS Support
30.2. The “Spring WebFlux Framework”
30.2.1. Spring WebFlux Auto-configuration
30.2.2. HTTP Codecs with HttpMessageReaders and HttpMessageWriters
30.2.3. Static Content
30.2.4. Template Engines
30.2.5. Error Handling
Custom Error Pages
30.2.6. Web Filters
30.3. JAX-RS and Jersey
30.4. Embedded Servlet Container Support
30.4.1. Servlets, Filters, and listeners
Registering Servlets, Filters, and Listeners as Spring Beans
30.4.2. Servlet Context Initialization
Scanning for Servlets, Filters, and listeners
30.4.3. The ServletWebServerApplicationContext
30.4.4. Customizing Embedded Servlet Containers
Programmatic Customization
Customizing ConfigurableServletWebServerFactory Directly
30.4.5. JSP Limitations
30.5. Embedded Reactive Server Support
30.6. Reactive Server Resources Configuration
31. Security
31.1. MVC Security
31.2. WebFlux Security
31.3. OAuth2
31.3.1. Client
OAuth2 client registration for common providers
31.3.2. Resource Server
31.3.3. Authorization Server
31.4. Actuator Security
31.4.1. Cross Site Request Forgery Protection
32. Working with SQL Databases
32.1. Configure a DataSource
32.1.1. Embedded Database Support
32.1.2. Connection to a Production Database
32.1.3. Connection to a JNDI DataSource
32.2. Using JdbcTemplate
32.3. JPA and Spring Data JPA
32.3.1. Entity Classes
32.3.2. Spring Data JPA Repositories
32.3.3. Creating and Dropping JPA Databases
32.3.4. Open EntityManager in View
32.4. Spring Data JDBC
32.5. Using H2’s Web Console
32.5.1. Changing the H2 Console’s Path
32.6. Using jOOQ
32.6.1. Code Generation
32.6.2. Using DSLContext
32.6.3. jOOQ SQL Dialect
32.6.4. Customizing jOOQ
33. Working with NoSQL Technologies
33.1. Redis
33.1.1. Connecting to Redis
33.2. MongoDB
33.2.1. Connecting to a MongoDB Database
33.2.2. MongoTemplate
33.2.3. Spring Data MongoDB Repositories
33.2.4. Embedded Mongo
33.3. Neo4j
33.3.1. Connecting to a Neo4j Database
33.3.2. Using the Embedded Mode
33.3.3. Neo4jSession
33.3.4. Spring Data Neo4j Repositories
33.4. Solr
33.4.1. Connecting to Solr
33.4.2. Spring Data Solr Repositories
33.5. Elasticsearch
33.5.1. Connecting to Elasticsearch by REST clients
33.5.2. Connecting to Elasticsearch by Using Jest
33.5.3. Connecting to Elasticsearch by Using Spring Data
33.5.4. Spring Data Elasticsearch Repositories
33.6. Cassandra
33.6.1. Connecting to Cassandra
33.6.2. Spring Data Cassandra Repositories
33.7. Couchbase
33.7.1. Connecting to Couchbase
33.7.2. Spring Data Couchbase Repositories
33.8. LDAP
33.8.1. Connecting to an LDAP Server
33.8.2. Spring Data LDAP Repositories
33.8.3. Embedded In-memory LDAP Server
33.9. InfluxDB
33.9.1. Connecting to InfluxDB
34. Caching
34.1. Supported Cache Providers
34.1.1. Generic
34.1.2. JCache (JSR-107)
34.1.3. EhCache 2.x
34.1.4. Hazelcast
34.1.5. Infinispan
34.1.6. Couchbase
34.1.7. Redis
34.1.8. Caffeine
34.1.9. Simple
34.1.10. None
35. Messaging
35.1. JMS
35.1.1. ActiveMQ Support
35.1.2. Artemis Support
35.1.3. Using a JNDI ConnectionFactory
35.1.4. Sending a Message
35.1.5. Receiving a Message
35.2. AMQP
35.2.1. RabbitMQ support
35.2.2. Sending a Message
35.2.3. Receiving a Message
35.3. Apache Kafka Support
35.3.1. Sending a Message
35.3.2. Receiving a Message
35.3.3. Kafka Streams
35.3.4. Additional Kafka Properties
36. Calling REST Services with RestTemplate
36.1. RestTemplate Customization
37. Calling REST Services with WebClient
37.1. WebClient Runtime
37.2. WebClient Customization
38. Validation
39. Sending Email
40. Distributed Transactions with JTA
40.1. Using an Atomikos Transaction Manager
40.2. Using a Bitronix Transaction Manager
40.3. Using a Java EE Managed Transaction Manager
40.4. Mixing XA and Non-XA JMS Connections
40.5. Supporting an Alternative Embedded Transaction Manager
41. Hazelcast
42. Quartz Scheduler
43. Task Execution and Scheduling
44. Spring Integration
45. Spring Session
46. Monitoring and Management over JMX
47. Testing
47.1. Test Scope Dependencies
47.2. Testing Spring Applications
47.3. Testing Spring Boot Applications
47.3.1. Detecting Web Application Type
47.3.2. Detecting Test Configuration
47.3.3. Excluding Test Configuration
47.3.4. Testing with a mock environment
47.3.5. Testing with a running server
47.3.6. Using JMX
47.3.7. Mocking and Spying Beans
47.3.8. Auto-configured Tests
47.3.9. Auto-configured JSON Tests
47.3.10. Auto-configured Spring MVC Tests
47.3.11. Auto-configured Spring WebFlux Tests
47.3.12. Auto-configured Data JPA Tests
47.3.13. Auto-configured JDBC Tests
47.3.14. Auto-configured Data JDBC Tests
47.3.15. Auto-configured jOOQ Tests
47.3.16. Auto-configured Data MongoDB Tests
47.3.17. Auto-configured Data Neo4j Tests
47.3.18. Auto-configured Data Redis Tests
47.3.19. Auto-configured Data LDAP Tests
47.3.20. Auto-configured REST Clients
47.3.21. Auto-configured Spring REST Docs Tests
Auto-configured Spring REST Docs Tests with Mock MVC
Auto-configured Spring REST Docs Tests with WebTestClient
Auto-configured Spring REST Docs Tests with REST Assured
47.3.22. Additional Auto-configuration and Slicing
47.3.23. User Configuration and Slicing
47.3.24. Using Spock to Test Spring Boot Applications
47.4. Test Utilities
47.4.1. ConfigFileApplicationContextInitializer
47.4.2. TestPropertyValues
47.4.3. OutputCapture
47.4.4. TestRestTemplate
48. WebSockets
49. Web Services
49.1. Calling Web Services with WebServiceTemplate
50. Creating Your Own Auto-configuration
50.1. Understanding Auto-configured Beans
50.2. Locating Auto-configuration Candidates
50.3. Condition Annotations
50.3.1. Class Conditions
50.3.2. Bean Conditions
50.3.3. Property Conditions
50.3.4. Resource Conditions
50.3.5. Web Application Conditions
50.3.6. SpEL Expression Conditions
50.4. Testing your Auto-configuration
50.4.1. Simulating a Web Context
50.4.2. Overriding the Classpath
50.5. Creating Your Own Starter
50.5.1. Naming
50.5.2. Configuration keys
50.5.3. autoconfigure Module
50.5.4. Starter Module
51. Kotlin support
51.1. Requirements
51.2. Null-safety
51.3. Kotlin API
51.3.1. runApplication
51.3.2. Extensions
51.4. Dependency management
51.5. @ConfigurationProperties
51.6. Testing
51.7. Resources
51.7.1. Further reading
51.7.2. Examples
52. What to Read Next
V. Spring Boot Actuator: Production-ready features
53. Enabling Production-ready Features
54. Endpoints
54.1. Enabling Endpoints
54.2. Exposing Endpoints
54.3. Securing HTTP Endpoints
54.4. Configuring Endpoints
54.5. Hypermedia for Actuator Web Endpoints
54.6. CORS Support
54.7. Implementing Custom Endpoints
54.7.1. Receiving Input
Input type conversion
54.7.2. Custom Web Endpoints
Web Endpoint Request Predicates
Path
HTTP method
Consumes
Produces
Web Endpoint Response Status
Web Endpoint Range Requests
Web Endpoint Security
54.7.3. Servlet endpoints
54.7.4. Controller endpoints
54.8. Health Information
54.8.1. Auto-configured HealthIndicators
54.8.2. Writing Custom HealthIndicators
54.8.3. Reactive Health Indicators
54.8.4. Auto-configured ReactiveHealthIndicators
54.9. Application Information
54.9.1. Auto-configured InfoContributors
54.9.2. Custom Application Information
54.9.3. Git Commit Information
54.9.4. Build Information
54.9.5. Writing Custom InfoContributors
55. Monitoring and Management over HTTP
55.1. Customizing the Management Endpoint Paths
55.2. Customizing the Management Server Port
55.3. Configuring Management-specific SSL
55.4. Customizing the Management Server Address
55.5. Disabling HTTP Endpoints
56. Monitoring and Management over JMX
56.1. Customizing MBean Names
56.2. Disabling JMX Endpoints
56.3. Using Jolokia for JMX over HTTP
56.3.1. Customizing Jolokia
56.3.2. Disabling Jolokia
57. Loggers
57.1. Configure a Logger
58. Metrics
58.1. Getting started
58.2. Supported monitoring systems
58.2.1. AppOptics
58.2.2. Atlas
58.2.3. Datadog
58.2.4. Dynatrace
58.2.5. Elastic
58.2.6. Ganglia
58.2.7. Graphite
58.2.8. Humio
58.2.9. Influx
58.2.10. JMX
58.2.11. KairosDB
58.2.12. New Relic
58.2.13. Prometheus
58.2.14. SignalFx
58.2.15. Simple
58.2.16. StatsD
58.2.17. Wavefront
58.3. Supported Metrics
58.3.1. Spring MVC Metrics
58.3.2. Spring WebFlux Metrics
58.3.3. Jersey Server Metrics
58.3.4. HTTP Client Metrics
58.3.5. Cache Metrics
58.3.6. DataSource Metrics
58.3.7. Hibernate Metrics
58.3.8. RabbitMQ Metrics
58.4. Registering custom metrics
58.5. Customizing individual metrics
58.5.1. Common tags
58.5.2. Per-meter properties
58.6. Metrics endpoint
59. Auditing
60. HTTP Tracing
60.1. Custom HTTP tracing
61. Process Monitoring
61.1. Extending Configuration
61.2. Programmatically
62. Cloud Foundry Support
62.1. Disabling Extended Cloud Foundry Actuator Support
62.2. Cloud Foundry Self-signed Certificates
62.3. Custom context path
63. What to Read Next
VI. Deploying Spring Boot Applications
64. Deploying to the Cloud
64.1. Cloud Foundry
64.1.1. Binding to Services
64.2. Heroku
64.3. OpenShift
64.4. Amazon Web Services (AWS)
64.4.1. AWS Elastic Beanstalk
Using the Tomcat Platform
Using the Java SE Platform
64.4.2. Summary
64.5. Boxfuse and Amazon Web Services
64.6. Google Cloud
65. Installing Spring Boot Applications
65.1. Supported Operating Systems
65.2. Unix/Linux Services
65.2.1. Installation as an init.d Service (System V)
Securing an init.d Service
65.2.2. Installation as a systemd Service
65.2.3. Customizing the Startup Script
Customizing the Start Script when It Is Written
Customizing a Script When It Runs
65.3. Microsoft Windows Services
66. What to Read Next
VII. Spring Boot CLI
67. Installing the CLI
68. Using the CLI
68.1. Running Applications with the CLI
68.1.1. Deduced “grab” Dependencies
68.1.2. Deduced “grab” Coordinates
68.1.3. Default Import Statements
68.1.4. Automatic Main Method
68.1.5. Custom Dependency Management
68.2. Applications with Multiple Source Files
68.3. Packaging Your Application
68.4. Initialize a New Project
68.5. Using the Embedded Shell
68.6. Adding Extensions to the CLI
69. Developing Applications with the Groovy Beans DSL
70. Configuring the CLI with settings.xml
71. What to Read Next
VIII. Build tool plugins
72. Spring Boot Maven Plugin
72.1. Including the Plugin
72.2. Packaging Executable Jar and War Files
73. Spring Boot Gradle Plugin
74. Spring Boot AntLib Module
74.1. Spring Boot Ant Tasks
74.1.1. spring-boot:exejar
74.1.2. Examples
74.2. spring-boot:findmainclass
74.2.1. Examples
75. Supporting Other Build Systems
75.1. Repackaging Archives
75.2. Nested Libraries
75.3. Finding a Main Class
75.4. Example Repackage Implementation
76. What to Read Next
IX. ‘How-to’ guides
77. Spring Boot Application
77.1. Create Your Own FailureAnalyzer
77.2. Troubleshoot Auto-configuration
77.3. Customize the Environment or ApplicationContext Before It Starts
77.4. Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)
77.5. Create a Non-web Application
78. Properties and Configuration
78.1. Automatically Expand Properties at Build Time
78.1.1. Automatic Property Expansion Using Maven
78.1.2. Automatic Property Expansion Using Gradle
78.2. Externalize the Configuration of SpringApplication
78.3. Change the Location of External Properties of an Application
78.4. Use ‘Short’ Command Line Arguments
78.5. Use YAML for External Properties
78.6. Set the Active Spring Profiles
78.7. Change Configuration Depending on the Environment
78.8. Discover Built-in Options for External Properties
79. Embedded Web Servers
79.1. Use Another Web Server
79.2. Disabling the Web Server
79.3. Change the HTTP Port
79.4. Use a Random Unassigned HTTP Port
79.5. Discover the HTTP Port at Runtime
79.6. Enable HTTP Response Compression
79.7. Configure SSL
79.8. Configure HTTP/2
79.8.1. HTTP/2 with Undertow
79.8.2. HTTP/2 with Jetty
79.8.3. HTTP/2 with Tomcat
79.8.4. HTTP/2 with Reactor Netty
79.9. Configure the Web Server
79.10. Add a Servlet, Filter, or Listener to an Application
79.10.1. Add a Servlet, Filter, or Listener by Using a Spring Bean
Disable Registration of a Servlet or Filter
79.10.2. Add Servlets, Filters, and Listeners by Using Classpath Scanning
79.11. Configure Access Logging
79.12. Running Behind a Front-end Proxy Server
79.12.1. Customize Tomcat’s Proxy Configuration
79.13. Enable Multiple Connectors with Tomcat
79.14. Use Tomcat’s LegacyCookieProcessor
79.15. Enable Multiple Listeners with Undertow
79.16. Create WebSocket Endpoints Using @ServerEndpoint
80. Spring MVC
80.1. Write a JSON REST Service
80.2. Write an XML REST Service
80.3. Customize the Jackson ObjectMapper
80.4. Customize the @ResponseBody Rendering
80.5. Handling Multipart File Uploads
80.6. Switch Off the Spring MVC DispatcherServlet
80.7. Switch off the Default MVC Configuration
80.8. Customize ViewResolvers
81. Testing With Spring Security
82. Jersey
82.1. Secure Jersey endpoints with Spring Security
82.2. Use Jersey Alongside Another Web Framework
83. HTTP Clients
83.1. Configure RestTemplate to Use a Proxy
83.2. Configure the TcpClient used by a Reactor Netty-based WebClient
84. Logging
84.1. Configure Logback for Logging
84.1.1. Configure Logback for File-only Output
84.2. Configure Log4j for Logging
84.2.1. Use YAML or JSON to Configure Log4j 2
85. Data Access
85.1. Configure a Custom DataSource
85.2. Configure Two DataSources
85.3. Use Spring Data Repositories
85.4. Separate @Entity Definitions from Spring Configuration
85.5. Configure JPA Properties
85.6. Configure Hibernate Naming Strategy
85.7. Configure Hibernate Second-Level Caching
85.8. Use Dependency Injection in Hibernate Components
85.9. Use a Custom EntityManagerFactory
85.10. Use Two EntityManagers
85.11. Use a Traditional persistence.xml File
85.12. Use Spring Data JPA and Mongo Repositories
85.13. Customize Spring Data’s Web Support
85.14. Expose Spring Data Repositories as REST Endpoint
85.15. Configure a Component that is Used by JPA
85.16. Configure jOOQ with Two DataSources
86. Database Initialization
86.1. Initialize a Database Using JPA
86.2. Initialize a Database Using Hibernate
86.3. Initialize a Database
86.4. Initialize a Spring Batch Database
86.5. Use a Higher-level Database Migration Tool
86.5.1. Execute Flyway Database Migrations on Startup
86.5.2. Execute Liquibase Database Migrations on Startup
87. Messaging
87.1. Disable Transacted JMS Session
88. Batch Applications
88.1. Execute Spring Batch Jobs on Startup
89. Actuator
89.1. Change the HTTP Port or Address of the Actuator Endpoints
89.2. Customize the ‘whitelabel’ Error Page
89.3. Sanitize Sensitive Values
89.4. Map Health Indicators to Micrometer Metrics
90. Security
90.1. Switch off the Spring Boot Security Configuration
90.2. Change the UserDetailsService and Add User Accounts
90.3. Enable HTTPS When Running behind a Proxy Server
91. Hot Swapping
91.1. Reload Static Content
91.2. Reload Templates without Restarting the Container
91.2.1. Thymeleaf Templates
91.2.2. FreeMarker Templates
91.2.3. Groovy Templates
91.3. Fast Application Restarts
91.4. Reload Java Classes without Restarting the Container
92. Build
92.1. Generate Build Information
92.2. Generate Git Information
92.3. Customize Dependency Versions
92.4. Create an Executable JAR with Maven
92.5. Use a Spring Boot Application as a Dependency
92.6. Extract Specific Libraries When an Executable Jar Runs
92.7. Create a Non-executable JAR with Exclusions
92.8. Remote Debug a Spring Boot Application Started with Maven
92.9. Build an Executable Archive from Ant without Using spring-boot-antlib
93. Traditional Deployment
93.1. Create a Deployable War File
93.2. Convert an Existing Application to Spring Boot
93.3. Deploying a WAR to WebLogic
93.4. Use Jedis Instead of Lettuce
X. Appendices
A. Common application properties
B. Configuration Metadata
B.1. Metadata Format
B.1.1. Group Attributes
B.1.2. Property Attributes
B.1.3. Hint Attributes
B.1.4. Repeated Metadata Items
B.2. Providing Manual Hints
B.2.1. Value Hint
B.2.2. Value Providers
Any
Class Reference
Handle As
Logger Name
Spring Bean Reference
Spring Profile Name
B.3. Generating Your Own Metadata by Using the Annotation Processor
B.3.1. Nested Properties
B.3.2. Adding Additional Metadata
C. Auto-configuration classes
C.1. From the “spring-boot-autoconfigure” module
C.2. From the “spring-boot-actuator-autoconfigure” module
D. Test auto-configuration annotations
E. The Executable Jar Format
E.1. Nested JARs
E.1.1. The Executable Jar File Structure
E.1.2. The Executable War File Structure
E.2. Spring Boot’s “JarFile” Class
E.2.1. Compatibility with the Standard Java “JarFile”
E.3. Launching Executable Jars
E.3.1. Launcher Manifest
E.3.2. Exploded Archives
E.4. PropertiesLauncher Features
E.5. Executable Jar Restrictions
E.6. Alternative Single Jar Solutions
F. Dependency versions