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.15.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. First Steps
4. Working with Spring Boot
5. Learning about Spring Boot Features
6. Moving to Production
7. Advanced Topics
II. Getting Started
8. Introducing Spring Boot
9. System Requirements
9.1. Servlet Containers
10. Installing Spring Boot
10.1. Installation Instructions for the Java Developer
10.1.1. Maven Installation
10.1.2. Gradle Installation
10.2. Installing the Spring Boot CLI
10.2.1. Manual Installation
10.2.2. Installation with SDKMAN!
10.2.3. OSX Homebrew Installation
10.2.4. MacPorts Installation
10.2.5. Command-line Completion
10.2.6. Windows Scoop Installation
10.2.7. Quick-start Spring CLI Example
10.3. Upgrading from an Earlier Version of Spring Boot
11. Developing Your First Spring Boot Application
11.1. Creating the POM
11.2. Adding Classpath Dependencies
11.3. Writing the Code
11.3.1. The @RestController and @RequestMapping Annotations
11.3.2. The @EnableAutoConfiguration Annotation
11.3.3. The “main” Method
11.4. Running the Example
11.5. Creating an Executable Jar
12. What to Read Next
III. Using Spring Boot
13. Build Systems
13.1. Dependency Management
13.2. Maven
13.2.1. Inheriting the Starter Parent
13.2.2. Using Spring Boot without the Parent POM
13.2.3. Using the Spring Boot Maven Plugin
13.3. Gradle
13.4. Ant
13.5. Starters
14. Structuring Your Code
14.1. Using the “default” Package
14.2. Locating the Main Application Class
15. Configuration Classes
15.1. Importing Additional Configuration Classes
15.2. Importing XML Configuration
16. Auto-configuration
16.1. Gradually Replacing Auto-configuration
16.2. Disabling Specific Auto-configuration Classes
17. Spring Beans and Dependency Injection
18. Using the @SpringBootApplication Annotation
19. Running Your Application
19.1. Running from an IDE
19.2. Running as a Packaged Application
19.3. Using the Maven Plugin
19.4. Using the Gradle Plugin
19.5. Hot Swapping
20. Developer Tools
20.1. Property Defaults
20.2. Automatic Restart
20.2.1. Logging changes in condition evaluation
20.2.2. Excluding Resources
20.2.3. Watching Additional Paths
20.2.4. Disabling Restart
20.2.5. Using a Trigger File
20.2.6. Customizing the Restart Classloader
20.2.7. Known Limitations
20.3. LiveReload
20.4. Global Settings
20.5. Remote Applications
20.5.1. Running the Remote Client Application
20.5.2. Remote Update
20.5.3. Configuring File System Watcher
20.5.4. Security Configuration for Devtools Remote
21. Packaging Your Application for Production
22. What to Read Next
IV. Spring Boot features
23. SpringApplication
23.1. Startup Failure
23.2. Customizing the Banner
23.3. Customizing SpringApplication
23.4. Fluent Builder API
23.5. Application Events and Listeners
23.6. Web Environment
23.7. Accessing Application Arguments
23.8. Using the ApplicationRunner or CommandLineRunner
23.9. Application Exit
23.10. Admin Features
24. Externalized Configuration
24.1. Configuring Random Values
24.2. Accessing Command Line Properties
24.3. Application Property Files
24.4. Profile-specific Properties
24.5. Placeholders in Properties
24.6. Encrypting Properties
24.7. Using YAML Instead of Properties
24.7.1. Loading YAML
24.7.2. Exposing YAML as Properties in the Spring Environment
24.7.3. Multi-profile YAML Documents
24.7.4. YAML Shortcomings
24.8. Type-safe Configuration Properties
24.8.1. Third-party Configuration
24.8.2. Relaxed Binding
Binding Maps
Binding from Environment Variables
24.8.3. Merging Complex Types
24.8.4. Properties Conversion
Converting durations
Converting Data Sizes
24.8.5. @ConfigurationProperties Validation
24.8.6. @ConfigurationProperties vs. @Value
25. Profiles
25.1. Adding Active Profiles
25.2. Programmatically Setting Profiles
25.3. Profile-specific Configuration Files
26. Logging
26.1. Log Format
26.2. Console Output
26.2.1. Color-coded Output
26.3. File Output
26.4. Log Levels
26.5. Log Groups
26.6. Custom Log Configuration
26.7. Logback Extensions
26.7.1. Profile-specific Configuration
26.7.2. Environment Properties
27. Internationalization
28. JSON
28.1. Jackson
28.2. Gson
28.3. JSON-B
29. Developing Web Applications
29.1. The “Spring Web MVC Framework”
29.1.1. Spring MVC Auto-configuration
29.1.2. HttpMessageConverters
29.1.3. Custom JSON Serializers and Deserializers
29.1.4. MessageCodesResolver
29.1.5. Static Content
29.1.6. Welcome Page
29.1.7. Custom Favicon
29.1.8. Path Matching and Content Negotiation
29.1.9. ConfigurableWebBindingInitializer
29.1.10. Template Engines
29.1.11. Error Handling
Custom Error Pages
Mapping Error Pages outside of Spring MVC
Error handling in a war deployment
29.1.12. Spring HATEOAS
29.1.13. CORS Support
29.2. The “Spring WebFlux Framework”
29.2.1. Spring WebFlux Auto-configuration
29.2.2. HTTP Codecs with HttpMessageReaders and HttpMessageWriters
29.2.3. Static Content
29.2.4. Template Engines
29.2.5. Error Handling
Custom Error Pages
29.2.6. Web Filters
29.3. JAX-RS and Jersey
29.4. Embedded Servlet Container Support
29.4.1. Servlets, Filters, and listeners
Registering Servlets, Filters, and Listeners as Spring Beans
29.4.2. Servlet Context Initialization
Scanning for Servlets, Filters, and listeners
29.4.3. The ServletWebServerApplicationContext
29.4.4. Customizing Embedded Servlet Containers
Programmatic Customization
Customizing ConfigurableServletWebServerFactory Directly
29.4.5. JSP Limitations
29.5. Embedded Reactive Server Support
29.6. Reactive Server Resources Configuration
30. Security
30.1. MVC Security
30.2. WebFlux Security
30.3. OAuth2
30.3.1. Client
OAuth2 client registration for common providers
30.3.2. Resource Server
30.3.3. Authorization Server
30.4. Actuator Security
30.4.1. Cross Site Request Forgery Protection
31. Working with SQL Databases
31.1. Configure a DataSource
31.1.1. Embedded Database Support
31.1.2. Connection to a Production Database
31.1.3. Connection to a JNDI DataSource
31.2. Using JdbcTemplate
31.3. JPA and Spring Data JPA
31.3.1. Entity Classes
31.3.2. Spring Data JPA Repositories
31.3.3. Creating and Dropping JPA Databases
31.3.4. Open EntityManager in View
31.4. Spring Data JDBC
31.5. Using H2’s Web Console
31.5.1. Changing the H2 Console’s Path
31.6. Using jOOQ
31.6.1. Code Generation
31.6.2. Using DSLContext
31.6.3. jOOQ SQL Dialect
31.6.4. Customizing jOOQ
32. Working with NoSQL Technologies
32.1. Redis
32.1.1. Connecting to Redis
32.2. MongoDB
32.2.1. Connecting to a MongoDB Database
32.2.2. MongoTemplate
32.2.3. Spring Data MongoDB Repositories
32.2.4. Embedded Mongo
32.3. Neo4j
32.3.1. Connecting to a Neo4j Database
32.3.2. Using the Embedded Mode
32.3.3. Neo4jSession
32.3.4. Spring Data Neo4j Repositories
32.4. Solr
32.4.1. Connecting to Solr
32.4.2. Spring Data Solr Repositories
32.5. Elasticsearch
32.5.1. Connecting to Elasticsearch by REST clients
32.5.2. Connecting to Elasticsearch by Using Jest
32.5.3. Connecting to Elasticsearch by Using Spring Data
32.5.4. Spring Data Elasticsearch Repositories
32.6. Cassandra
32.6.1. Connecting to Cassandra
32.6.2. Spring Data Cassandra Repositories
32.7. Couchbase
32.7.1. Connecting to Couchbase
32.7.2. Spring Data Couchbase Repositories
32.8. LDAP
32.8.1. Connecting to an LDAP Server
32.8.2. Spring Data LDAP Repositories
32.8.3. Embedded In-memory LDAP Server
32.9. InfluxDB
32.9.1. Connecting to InfluxDB
33. Caching
33.1. Supported Cache Providers
33.1.1. Generic
33.1.2. JCache (JSR-107)
33.1.3. EhCache 2.x
33.1.4. Hazelcast
33.1.5. Infinispan
33.1.6. Couchbase
33.1.7. Redis
33.1.8. Caffeine
33.1.9. Simple
33.1.10. None
34. Messaging
34.1. JMS
34.1.1. ActiveMQ Support
34.1.2. Artemis Support
34.1.3. Using a JNDI ConnectionFactory
34.1.4. Sending a Message
34.1.5. Receiving a Message
34.2. AMQP
34.2.1. RabbitMQ support
34.2.2. Sending a Message
34.2.3. Receiving a Message
34.3. Apache Kafka Support
34.3.1. Sending a Message
34.3.2. Receiving a Message
34.3.3. Kafka Streams
34.3.4. Additional Kafka Properties
35. Calling REST Services with RestTemplate
35.1. RestTemplate Customization
36. Calling REST Services with WebClient
36.1. WebClient Runtime
36.2. WebClient Customization
37. Validation
38. Sending Email
39. Distributed Transactions with JTA
39.1. Using an Atomikos Transaction Manager
39.2. Using a Bitronix Transaction Manager
39.3. Using a Java EE Managed Transaction Manager
39.4. Mixing XA and Non-XA JMS Connections
39.5. Supporting an Alternative Embedded Transaction Manager
40. Hazelcast
41. Quartz Scheduler
42. Task Execution and Scheduling
43. Spring Integration
44. Spring Session
45. Monitoring and Management over JMX
46. Testing
46.1. Test Scope Dependencies
46.2. Testing Spring Applications
46.3. Testing Spring Boot Applications
46.3.1. Detecting Web Application Type
46.3.2. Detecting Test Configuration
46.3.3. Excluding Test Configuration
46.3.4. Testing with a mock environment
46.3.5. Testing with a running server
46.3.6. Using JMX
46.3.7. Mocking and Spying Beans
46.3.8. Auto-configured Tests
46.3.9. Auto-configured JSON Tests
46.3.10. Auto-configured Spring MVC Tests
46.3.11. Auto-configured Spring WebFlux Tests
46.3.12. Auto-configured Data JPA Tests
46.3.13. Auto-configured JDBC Tests
46.3.14. Auto-configured Data JDBC Tests
46.3.15. Auto-configured jOOQ Tests
46.3.16. Auto-configured Data MongoDB Tests
46.3.17. Auto-configured Data Neo4j Tests
46.3.18. Auto-configured Data Redis Tests
46.3.19. Auto-configured Data LDAP Tests
46.3.20. Auto-configured REST Clients
46.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
46.3.22. Additional Auto-configuration and Slicing
46.3.23. User Configuration and Slicing
46.3.24. Using Spock to Test Spring Boot Applications
46.4. Test Utilities
46.4.1. ConfigFileApplicationContextInitializer
46.4.2. TestPropertyValues
46.4.3. OutputCapture
46.4.4. TestRestTemplate
47. WebSockets
48. Web Services
48.1. Calling Web Services with WebServiceTemplate
49. Creating Your Own Auto-configuration
49.1. Understanding Auto-configured Beans
49.2. Locating Auto-configuration Candidates
49.3. Condition Annotations
49.3.1. Class Conditions
49.3.2. Bean Conditions
49.3.3. Property Conditions
49.3.4. Resource Conditions
49.3.5. Web Application Conditions
49.3.6. SpEL Expression Conditions
49.4. Testing your Auto-configuration
49.4.1. Simulating a Web Context
49.4.2. Overriding the Classpath
49.5. Creating Your Own Starter
49.5.1. Naming
49.5.2. Configuration keys
49.5.3. autoconfigure Module
49.5.4. Starter Module
50. Kotlin support
50.1. Requirements
50.2. Null-safety
50.3. Kotlin API
50.3.1. runApplication
50.3.2. Extensions
50.4. Dependency management
50.5. @ConfigurationProperties
50.6. Testing
50.7. Resources
50.7.1. Further reading
50.7.2. Examples
51. What to Read Next
V. Spring Boot Actuator: Production-ready features
52. Enabling Production-ready Features
53. Endpoints
53.1. Enabling Endpoints
53.2. Exposing Endpoints
53.3. Securing HTTP Endpoints
53.4. Configuring Endpoints
53.5. Hypermedia for Actuator Web Endpoints
53.6. CORS Support
53.7. Implementing Custom Endpoints
53.7.1. Receiving Input
Input type conversion
53.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
53.7.3. Servlet endpoints
53.7.4. Controller endpoints
53.8. Health Information
53.8.1. Auto-configured HealthIndicators
53.8.2. Writing Custom HealthIndicators
53.8.3. Reactive Health Indicators
53.8.4. Auto-configured ReactiveHealthIndicators
53.9. Application Information
53.9.1. Auto-configured InfoContributors
53.9.2. Custom Application Information
53.9.3. Git Commit Information
53.9.4. Build Information
53.9.5. Writing Custom InfoContributors
54. Monitoring and Management over HTTP
54.1. Customizing the Management Endpoint Paths
54.2. Customizing the Management Server Port
54.3. Configuring Management-specific SSL
54.4. Customizing the Management Server Address
54.5. Disabling HTTP Endpoints
55. Monitoring and Management over JMX
55.1. Customizing MBean Names
55.2. Disabling JMX Endpoints
55.3. Using Jolokia for JMX over HTTP
55.3.1. Customizing Jolokia
55.3.2. Disabling Jolokia
56. Loggers
56.1. Configure a Logger
57. Metrics
57.1. Getting started
57.2. Supported monitoring systems
57.2.1. AppOptics
57.2.2. Atlas
57.2.3. Datadog
57.2.4. Dynatrace
57.2.5. Elastic
57.2.6. Ganglia
57.2.7. Graphite
57.2.8. Humio
57.2.9. Influx
57.2.10. JMX
57.2.11. KairosDB
57.2.12. New Relic
57.2.13. Prometheus
57.2.14. SignalFx
57.2.15. Simple
57.2.16. StatsD
57.2.17. Wavefront
57.3. Supported Metrics
57.3.1. Spring MVC Metrics
57.3.2. Spring WebFlux Metrics
57.3.3. Jersey Server Metrics
57.3.4. HTTP Client Metrics
57.3.5. Cache Metrics
57.3.6. DataSource Metrics
57.3.7. Hibernate Metrics
57.3.8. RabbitMQ Metrics
57.4. Registering custom metrics
57.5. Customizing individual metrics
57.5.1. Common tags
57.5.2. Per-meter properties
57.6. Metrics endpoint
58. Auditing
59. HTTP Tracing
59.1. Custom HTTP tracing
60. Process Monitoring
60.1. Extending Configuration
60.2. Programmatically
61. Cloud Foundry Support
61.1. Disabling Extended Cloud Foundry Actuator Support
61.2. Cloud Foundry Self-signed Certificates
61.3. Custom context path
62. What to Read Next
VI. Deploying Spring Boot Applications
63. Deploying to the Cloud
63.1. Cloud Foundry
63.1.1. Binding to Services
63.2. Heroku
63.3. OpenShift
63.4. Amazon Web Services (AWS)
63.4.1. AWS Elastic Beanstalk
Using the Tomcat Platform
Using the Java SE Platform
63.4.2. Summary
63.5. Boxfuse and Amazon Web Services
63.6. Google Cloud
64. Installing Spring Boot Applications
64.1. Supported Operating Systems
64.2. Unix/Linux Services
64.2.1. Installation as an init.d Service (System V)
Securing an init.d Service
64.2.2. Installation as a systemd Service
64.2.3. Customizing the Startup Script
Customizing the Start Script when It Is Written
Customizing a Script When It Runs
64.3. Microsoft Windows Services
65. What to Read Next
VII. Spring Boot CLI
66. Installing the CLI
67. Using the CLI
67.1. Running Applications with the CLI
67.1.1. Deduced “grab” Dependencies
67.1.2. Deduced “grab” Coordinates
67.1.3. Default Import Statements
67.1.4. Automatic Main Method
67.1.5. Custom Dependency Management
67.2. Applications with Multiple Source Files
67.3. Packaging Your Application
67.4. Initialize a New Project
67.5. Using the Embedded Shell
67.6. Adding Extensions to the CLI
68. Developing Applications with the Groovy Beans DSL
69. Configuring the CLI with settings.xml
70. What to Read Next
VIII. Build tool plugins
71. Spring Boot Maven Plugin
71.1. Including the Plugin
71.2. Packaging Executable Jar and War Files
72. Spring Boot Gradle Plugin
73. Spring Boot AntLib Module
73.1. Spring Boot Ant Tasks
73.1.1. spring-boot:exejar
73.1.2. Examples
73.2. spring-boot:findmainclass
73.2.1. Examples
74. Supporting Other Build Systems
74.1. Repackaging Archives
74.2. Nested Libraries
74.3. Finding a Main Class
74.4. Example Repackage Implementation
75. What to Read Next
IX. ‘How-to’ guides
76. Spring Boot Application
76.1. Create Your Own FailureAnalyzer
76.2. Troubleshoot Auto-configuration
76.3. Customize the Environment or ApplicationContext Before It Starts
76.4. Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)
76.5. Create a Non-web Application
77. Properties and Configuration
77.1. Automatically Expand Properties at Build Time
77.1.1. Automatic Property Expansion Using Maven
77.1.2. Automatic Property Expansion Using Gradle
77.2. Externalize the Configuration of SpringApplication
77.3. Change the Location of External Properties of an Application
77.4. Use ‘Short’ Command Line Arguments
77.5. Use YAML for External Properties
77.6. Set the Active Spring Profiles
77.7. Change Configuration Depending on the Environment
77.8. Discover Built-in Options for External Properties
78. Embedded Web Servers
78.1. Use Another Web Server
78.2. Disabling the Web Server
78.3. Change the HTTP Port
78.4. Use a Random Unassigned HTTP Port
78.5. Discover the HTTP Port at Runtime
78.6. Enable HTTP Response Compression
78.7. Configure SSL
78.8. Configure HTTP/2
78.8.1. HTTP/2 with Undertow
78.8.2. HTTP/2 with Jetty
78.8.3. HTTP/2 with Tomcat
78.8.4. HTTP/2 with Reactor Netty
78.9. Configure the Web Server
78.10. Add a Servlet, Filter, or Listener to an Application
78.10.1. Add a Servlet, Filter, or Listener by Using a Spring Bean
Disable Registration of a Servlet or Filter
78.10.2. Add Servlets, Filters, and Listeners by Using Classpath Scanning
78.11. Configure Access Logging
78.12. Running Behind a Front-end Proxy Server
78.12.1. Customize Tomcat’s Proxy Configuration
78.13. Enable Multiple Connectors with Tomcat
78.14. Use Tomcat’s LegacyCookieProcessor
78.15. Enable Multiple Listeners with Undertow
78.16. Create WebSocket Endpoints Using @ServerEndpoint
79. Spring MVC
79.1. Write a JSON REST Service
79.2. Write an XML REST Service
79.3. Customize the Jackson ObjectMapper
79.4. Customize the @ResponseBody Rendering
79.5. Handling Multipart File Uploads
79.6. Switch Off the Spring MVC DispatcherServlet
79.7. Switch off the Default MVC Configuration
79.8. Customize ViewResolvers
80. Testing With Spring Security
81. Jersey
81.1. Secure Jersey endpoints with Spring Security
81.2. Use Jersey Alongside Another Web Framework
82. HTTP Clients
82.1. Configure RestTemplate to Use a Proxy
82.2. Configure the TcpClient used by a Reactor Netty-based WebClient
83. Logging
83.1. Configure Logback for Logging
83.1.1. Configure Logback for File-only Output
83.2. Configure Log4j for Logging
83.2.1. Use YAML or JSON to Configure Log4j 2
84. Data Access
84.1. Configure a Custom DataSource
84.2. Configure Two DataSources
84.3. Use Spring Data Repositories
84.4. Separate @Entity Definitions from Spring Configuration
84.5. Configure JPA Properties
84.6. Configure Hibernate Naming Strategy
84.7. Configure Hibernate Second-Level Caching
84.8. Use Dependency Injection in Hibernate Components
84.9. Use a Custom EntityManagerFactory
84.10. Use Two EntityManagers
84.11. Use a Traditional persistence.xml File
84.12. Use Spring Data JPA and Mongo Repositories
84.13. Customize Spring Data’s Web Support
84.14. Expose Spring Data Repositories as REST Endpoint
84.15. Configure a Component that is Used by JPA
84.16. Configure jOOQ with Two DataSources
85. Database Initialization
85.1. Initialize a Database Using JPA
85.2. Initialize a Database Using Hibernate
85.3. Initialize a Database
85.4. Initialize a Spring Batch Database
85.5. Use a Higher-level Database Migration Tool
85.5.1. Execute Flyway Database Migrations on Startup
85.5.2. Execute Liquibase Database Migrations on Startup
86. Messaging
86.1. Disable Transacted JMS Session
87. Batch Applications
87.1. Execute Spring Batch Jobs on Startup
88. Actuator
88.1. Change the HTTP Port or Address of the Actuator Endpoints
88.2. Customize the ‘whitelabel’ Error Page
88.3. Sanitize Sensitive Values
88.4. Map Health Indicators to Micrometer Metrics
89. Security
89.1. Switch off the Spring Boot Security Configuration
89.2. Change the UserDetailsService and Add User Accounts
89.3. Enable HTTPS When Running behind a Proxy Server
90. Hot Swapping
90.1. Reload Static Content
90.2. Reload Templates without Restarting the Container
90.2.1. Thymeleaf Templates
90.2.2. FreeMarker Templates
90.2.3. Groovy Templates
90.3. Fast Application Restarts
90.4. Reload Java Classes without Restarting the Container
91. Build
91.1. Generate Build Information
91.2. Generate Git Information
91.3. Customize Dependency Versions
91.4. Create an Executable JAR with Maven
91.5. Use a Spring Boot Application as a Dependency
91.6. Extract Specific Libraries When an Executable Jar Runs
91.7. Create a Non-executable JAR with Exclusions
91.8. Remote Debug a Spring Boot Application Started with Maven
91.9. Build an Executable Archive from Ant without Using spring-boot-antlib
92. Traditional Deployment
92.1. Create a Deployable War File
92.2. Convert an Existing Application to Spring Boot
92.3. Deploying a WAR to WebLogic
92.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