100% found this document useful (2 votes)
28 views55 pages

Pro Spring Boot 2: An Authoritative Guide To Building Microservices, Web and Enterprise Applications, and Best Practices 2nd Edition Felipe Gutierrez

The document promotes a collection of ebooks available for download at textbookfull.com, including titles focused on Spring Boot and related technologies. It highlights various books authored by Felipe Gutierrez and others, covering topics such as microservices, web applications, and best practices in Spring development. Users can download ebooks in multiple formats and access supplementary materials through GitHub links provided in the text.

Uploaded by

quartzqaysar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
28 views55 pages

Pro Spring Boot 2: An Authoritative Guide To Building Microservices, Web and Enterprise Applications, and Best Practices 2nd Edition Felipe Gutierrez

The document promotes a collection of ebooks available for download at textbookfull.com, including titles focused on Spring Boot and related technologies. It highlights various books authored by Felipe Gutierrez and others, covering topics such as microservices, web applications, and best practices in Spring development. Users can download ebooks in multiple formats and access supplementary materials through GitHub links provided in the text.

Uploaded by

quartzqaysar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

Explore the full ebook collection and download it now at textbookfull.

com

Pro Spring Boot 2: An Authoritative Guide to


Building Microservices, Web and Enterprise
Applications, and Best Practices 2nd Edition
Felipe Gutierrez
https://textbookfull.com/product/pro-spring-boot-2-an-
authoritative-guide-to-building-microservices-web-and-
enterprise-applications-and-best-practices-2nd-edition-
felipe-gutierrez/

OR CLICK HERE

DOWLOAD EBOOK

Browse and Get More Ebook Downloads Instantly at https://textbookfull.com


Click here to visit textbookfull.com and download textbook now
Your digital treasures (PDF, ePub, MOBI) await
Download instantly and pick your perfect format...

Read anywhere, anytime, on any device!

Pro Spring Boot 2 An Authoritative Guide to Building


Microservices Web and Enterprise Applications and Best
Practices Second Edition Felipe Gutierrez
https://textbookfull.com/product/pro-spring-boot-2-an-authoritative-
guide-to-building-microservices-web-and-enterprise-applications-and-
best-practices-second-edition-felipe-gutierrez/
textbookfull.com

Spring Boot Messaging: Messaging APIs for Enterprise and


Integration Solutions Felipe Gutierrez

https://textbookfull.com/product/spring-boot-messaging-messaging-apis-
for-enterprise-and-integration-solutions-felipe-gutierrez/

textbookfull.com

Biota Grow 2C gather 2C cook Loucas

https://textbookfull.com/product/biota-grow-2c-gather-2c-cook-loucas/

textbookfull.com

Pro Spring MVC with WebFlux: Web Development in Spring


Framework 5 and Spring Boot 2 2nd Edition Marten Deinum

https://textbookfull.com/product/pro-spring-mvc-with-webflux-web-
development-in-spring-framework-5-and-spring-boot-2-2nd-edition-
marten-deinum/
textbookfull.com
Pro Spring MVC with WebFlux: Web Development in Spring
Framework 5 and Spring Boot 2 2nd Edition Marten Deinum

https://textbookfull.com/product/pro-spring-mvc-with-webflux-web-
development-in-spring-framework-5-and-spring-boot-2-2nd-edition-
marten-deinum-2/
textbookfull.com

Pro Spring Security: Securing Spring Framework 5 and Boot


2-based Java Applications 2nd Edition Carlo Scarioni

https://textbookfull.com/product/pro-spring-security-securing-spring-
framework-5-and-boot-2-based-java-applications-2nd-edition-carlo-
scarioni/
textbookfull.com

Spring Boot Persistence Best Practices: Optimize Java


Persistence Performance in Spring Boot Applications 1st
Edition Anghel Leonard
https://textbookfull.com/product/spring-boot-persistence-best-
practices-optimize-java-persistence-performance-in-spring-boot-
applications-1st-edition-anghel-leonard/
textbookfull.com

Spring Boot 2 0 Projects Build production grade reactive


applications and microservices with Spring Boot English
Edition Mohamed Shazin Sadakath
https://textbookfull.com/product/spring-boot-2-0-projects-build-
production-grade-reactive-applications-and-microservices-with-spring-
boot-english-edition-mohamed-shazin-sadakath/
textbookfull.com

Pro Spring MVC with WebFlux Web Development in Spring


Framework 5 and Spring Boot 2 Second Edition Marten Deinum
Iuliana Cosmina
https://textbookfull.com/product/pro-spring-mvc-with-webflux-web-
development-in-spring-framework-5-and-spring-boot-2-second-edition-
marten-deinum-iuliana-cosmina/
textbookfull.com
Pro
Spring Boot 2
An Authoritative Guide to Building
Microservices, Web and Enterprise
Applications, and Best Practices

Second Edition

Felipe Gutierrez
Pro Spring Boot 2
An Authoritative Guide to Building
Microservices, Web and Enterprise
Applications, and Best Practices
Second Edition

Felipe Gutierrez
Pro Spring Boot 2: An Authoritative Guide to Building Microservices, Web and
Enterprise Applications, and Best Practices
Felipe Gutierrez
Albuquerque, NM, USA

ISBN-13 (pbk): 978-1-4842-3675-8 ISBN-13 (electronic): 978-1-4842-3676-5


https://doi.org/10.1007/978-1-4842-3676-5
Library of Congress Control Number: 2016941344

Copyright © 2019 by Felipe Gutierrez


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Steve Anglin
Development Editor: Matthew Moodie
Coordinating Editor: Mark Powers
Cover designed by eStudioCalamar
Cover image designed by Freepik (www.freepik.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 233 Spring Street,
6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-
sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member
(owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a
Delaware corporation.
For information on translations, please e-mail [email protected]; for reprint, paperback, or audio rights,
please email [email protected].
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub via the book's product page, located at www.apress.com/9781484236758. For more
detailed information, please visit http://www.apress.com/source-code.
Printed on acid-free paper
To my wife, Norma Castaneda
Table of Contents
About the Author��������������������������������������������������������������������������������������������������� xiii

About the Technical Reviewer���������������������������������������������������������������������������������xv


Acknowledgments�������������������������������������������������������������������������������������������������xvii

Chapter 1: Spring Framework 5������������������������������������������������������������������������������� 1


A Little History������������������������������������������������������������������������������������������������������������������������������� 1
Design Principles and Patterns����������������������������������������������������������������������������������������������������� 2
Spring Framework 5��������������������������������������������������������������������������������������������������������������������� 3
A Simple Spring Web Application�������������������������������������������������������������������������������������������������� 4
Using Maven for Creating a Project����������������������������������������������������������������������������������������� 4
Adding Dependencies�������������������������������������������������������������������������������������������������������������� 5
Spring Web Configuration�������������������������������������������������������������������������������������������������������� 9
Classes���������������������������������������������������������������������������������������������������������������������������������� 17
Running the App�������������������������������������������������������������������������������������������������������������������� 23
Using Java Config������������������������������������������������������������������������������������������������������������������ 26
Summary������������������������������������������������������������������������������������������������������������������������������������ 30

Chapter 2: Introduction to Spring Boot������������������������������������������������������������������� 31


Spring Boot��������������������������������������������������������������������������������������������������������������������������������� 31
Spring Boot to the Rescue����������������������������������������������������������������������������������������������������� 33
Spring Boot CLI���������������������������������������������������������������������������������������������������������������������� 34
Spring Boot Application Model���������������������������������������������������������������������������������������������������� 36
My First Spring Boot Application������������������������������������������������������������������������������������������� 37
Why Spring Boot?����������������������������������������������������������������������������������������������������������������������� 42
Spring Boot Features������������������������������������������������������������������������������������������������������������� 43
Summary������������������������������������������������������������������������������������������������������������������������������������ 44

v
Table of Contents

Chapter 3: Spring Boot Internals and Features������������������������������������������������������ 45


Auto-Configuration���������������������������������������������������������������������������������������������������������������������� 45
Disable a Specific Auto-Configuration����������������������������������������������������������������������������������� 48
@EnableAutoConfiguration and @Enable<Technology> annotations����������������������������������� 50
Spring Boot Features������������������������������������������������������������������������������������������������������������������ 54
SpringApplication Class��������������������������������������������������������������������������������������������������������� 57
Custom Banner���������������������������������������������������������������������������������������������������������������������� 58
SpringApplicationBuilder������������������������������������������������������������������������������������������������������� 63
Application Arguments���������������������������������������������������������������������������������������������������������� 66
ApplicationRunner and CommandLineRunner���������������������������������������������������������������������������� 68
Application Configuration������������������������������������������������������������������������������������������������������ 71
Configuration Properties Examples��������������������������������������������������������������������������������������� 73
Custom Properties Prefix������������������������������������������������������������������������������������������������������� 81
Summary������������������������������������������������������������������������������������������������������������������������������������ 85

Chapter 4: Web Applications with Spring Boot������������������������������������������������������� 87


Spring MVC��������������������������������������������������������������������������������������������������������������������������������� 87
Spring Boot MVC Auto-Configuration������������������������������������������������������������������������������������������ 88
Spring Boot Web: ToDo App��������������������������������������������������������������������������������������������������������� 90
ToDo App�������������������������������������������������������������������������������������������������������������������������������� 91
Running: ToDo App��������������������������������������������������������������������������������������������������������������� 104
Testing: ToDo App���������������������������������������������������������������������������������������������������������������� 105
Spring Boot Web: Overriding Defaults��������������������������������������������������������������������������������������� 110
Server Overriding���������������������������������������������������������������������������������������������������������������� 110
JSON Date Format��������������������������������������������������������������������������������������������������������������� 112
Content-Type: JSON/XML����������������������������������������������������������������������������������������������������� 112
Spring MVC: Overriding Defaults����������������������������������������������������������������������������������������� 114
Using a Different Application Container������������������������������������������������������������������������������� 114
Spring Boot Web: Client������������������������������������������������������������������������������������������������������������ 115
ToDo Client App������������������������������������������������������������������������������������������������������������������� 116
Summary���������������������������������������������������������������������������������������������������������������������������������� 124

vi
Table of Contents

Chapter 5: Data Access with Spring Boot������������������������������������������������������������� 127


SQL Databases�������������������������������������������������������������������������������������������������������������������������� 127
Spring Data������������������������������������������������������������������������������������������������������������������������������� 128
Spring JDBC������������������������������������������������������������������������������������������������������������������������������ 129
JDBC with Spring Boot�������������������������������������������������������������������������������������������������������� 130
ToDo App with JDBC������������������������������������������������������������������������������������������������������������ 131
Spring Data JPA������������������������������������������������������������������������������������������������������������������������ 139
Spring Data JPA with Spring Boot��������������������������������������������������������������������������������������� 140
ToDo App with Spring Data JPA������������������������������������������������������������������������������������������� 141
Spring Data REST���������������������������������������������������������������������������������������������������������������������� 150
Spring Data REST with Spring Boot������������������������������������������������������������������������������������� 150
ToDo App with Spring Data JPA and Spring Data REST������������������������������������������������������� 151
No SQL Databases��������������������������������������������������������������������������������������������������������������������� 158
Spring Data MongoDB��������������������������������������������������������������������������������������������������������������� 158
Spring Data MongoDB with Spring Boot������������������������������������������������������������������������������ 159
ToDo App with Spring Data MongoDB��������������������������������������������������������������������������������� 161
ToDo App with Spring Data MongoDB REST������������������������������������������������������������������������ 165
Spring Data Redis��������������������������������������������������������������������������������������������������������������������� 165
Spring Data Redis with Spring Boot������������������������������������������������������������������������������������ 166
ToDo App with Spring Data Redis���������������������������������������������������������������������������������������� 166
More Data Features with Spring Boot��������������������������������������������������������������������������������������� 170
Multiple Data Sources��������������������������������������������������������������������������������������������������������� 170
Summary���������������������������������������������������������������������������������������������������������������������������������� 171

Chapter 6: WebFlux and Reactive Data with Spring Boot������������������������������������� 173


Reactive Systems���������������������������������������������������������������������������������������������������������������������� 173
The Reactive Manifesto������������������������������������������������������������������������������������������������������� 173
Project Reactor������������������������������������������������������������������������������������������������������������������������� 175
ToDo App with Reactor�������������������������������������������������������������������������������������������������������� 175

vii
Table of Contents

WebFlux������������������������������������������������������������������������������������������������������������������������������������ 184
WebClient���������������������������������������������������������������������������������������������������������������������������� 186
WebFlux and Spring Boot Auto-configuration��������������������������������������������������������������������������� 187
Using WebFlux with Spring Boot����������������������������������������������������������������������������������������� 188
Reactive Data���������������������������������������������������������������������������������������������������������������������������� 196
MongoDB Reactive Streams������������������������������������������������������������������������������������������������ 196
Summary���������������������������������������������������������������������������������������������������������������������������������� 206

Chapter 7: Testing with Spring Boot��������������������������������������������������������������������� 207


Spring Testing Framework�������������������������������������������������������������������������������������������������������� 207
Spring Boot Testing Framework������������������������������������������������������������������������������������������������ 209
Testing Web Endpoints�������������������������������������������������������������������������������������������������������� 210
Mocking Beans�������������������������������������������������������������������������������������������������������������������� 211
Spring Boot Testing Slices��������������������������������������������������������������������������������������������������� 212
Summary���������������������������������������������������������������������������������������������������������������������������������� 218

Chapter 8: Security with Spring Boot������������������������������������������������������������������� 219


Spring Security������������������������������������������������������������������������������������������������������������������������� 219
Security with Spring Boot��������������������������������������������������������������������������������������������������������� 220
ToDo App with Basic Security��������������������������������������������������������������������������������������������������� 220
Overriding Simple Security�������������������������������������������������������������������������������������������������� 227
Overriding the Default Login Page��������������������������������������������������������������������������������������� 229
Custom Login Page�������������������������������������������������������������������������������������������������������������� 232
Using Security with JDBC��������������������������������������������������������������������������������������������������������� 240
Directory App with JDBC Security��������������������������������������������������������������������������������������� 241
Using the Directory App within the ToDo App���������������������������������������������������������������������� 250
WebFlux Security���������������������������������������������������������������������������������������������������������������������� 257
ToDo App with OAuth2��������������������������������������������������������������������������������������������������������������� 257
Creating the ToDo App in GitHub������������������������������������������������������������������������������������������ 261
Summary���������������������������������������������������������������������������������������������������������������������������������� 268

viii
Table of Contents

Chapter 9: Messaging with Spring Boot��������������������������������������������������������������� 269


What Is Messaging?������������������������������������������������������������������������������������������������������������������ 269
JMS with Spring Boot��������������������������������������������������������������������������������������������������������������� 270
ToDo App with JMS�������������������������������������������������������������������������������������������������������������� 270
Using JMS Pub/Sub������������������������������������������������������������������������������������������������������������� 281
Remote ActiveMQ���������������������������������������������������������������������������������������������������������������� 282
RabbitMQ with Spring Boot������������������������������������������������������������������������������������������������������� 282
Installing RabbitMQ������������������������������������������������������������������������������������������������������������� 283
RabbitMQ/AMQP: Exchanges, Bindings, and Queues���������������������������������������������������������� 283
ToDo App with RabbitMQ����������������������������������������������������������������������������������������������������� 285
Remote RabbitMQ���������������������������������������������������������������������������������������������������������������� 297
Redis Messaging with Spring Boot������������������������������������������������������������������������������������������� 298
Installing Redis�������������������������������������������������������������������������������������������������������������������� 298
ToDo App with Redis������������������������������������������������������������������������������������������������������������ 298
Remote Redis���������������������������������������������������������������������������������������������������������������������� 306
WebSockets with Spring Boot��������������������������������������������������������������������������������������������������� 307
ToDo App with WebSockets������������������������������������������������������������������������������������������������� 307
Summary���������������������������������������������������������������������������������������������������������������������������������� 318

Chapter 10: Spring Boot Actuator������������������������������������������������������������������������� 319


Spring Boot Actuator����������������������������������������������������������������������������������������������������������������� 319
ToDo App with Actuator������������������������������������������������������������������������������������������������������������� 320
/actuator������������������������������������������������������������������������������������������������������������������������������ 325
/actuator/conditions������������������������������������������������������������������������������������������������������������ 326
/actuator/beans������������������������������������������������������������������������������������������������������������������� 327
/actuator/configprops���������������������������������������������������������������������������������������������������������� 328
/actuator/threaddump��������������������������������������������������������������������������������������������������������� 329
/actuator/env����������������������������������������������������������������������������������������������������������������������� 330
/actuator/health������������������������������������������������������������������������������������������������������������������� 331
/actuator/info����������������������������������������������������������������������������������������������������������������������� 333
/actuator/loggers����������������������������������������������������������������������������������������������������������������� 333

ix
Table of Contents

/actuator/loggers/{name}���������������������������������������������������������������������������������������������������� 334
/actuator/metrics����������������������������������������������������������������������������������������������������������������� 334
/actuator/mappings������������������������������������������������������������������������������������������������������������� 336
/actuator/shutdown������������������������������������������������������������������������������������������������������������� 337
/actuator/httptrace�������������������������������������������������������������������������������������������������������������� 339
Changing the Endpoint ID���������������������������������������������������������������������������������������������������� 340
Actuator CORS Support������������������������������������������������������������������������������������������������������� 341
Changing the Management Endpoints Path������������������������������������������������������������������������ 341
Securing Endpoints������������������������������������������������������������������������������������������������������������� 342
Configuring Endpoints��������������������������������������������������������������������������������������������������������� 342
Implementing Custom Actuator Endpoints�������������������������������������������������������������������������������� 343
ToDo App with Custom Actuator Endpoints������������������������������������������������������������������������� 343
Spring Boot Actuator Health������������������������������������������������������������������������������������������������������ 353
ToDo App with Custom HealthIndicator������������������������������������������������������������������������������� 358
Spring Boot Actuator Metrics���������������������������������������������������������������������������������������������������� 363
ToDo App with Micrometer: Prometheus and Grafana��������������������������������������������������������� 363
General Stats for Spring Boot with Grafana������������������������������������������������������������������������ 378
Summary���������������������������������������������������������������������������������������������������������������������������������� 381

Chapter 11: Spring Integration and Spring Cloud Stream with Spring Boot������ 383
Spring Integration Primer���������������������������������������������������������������������������������������������������������� 384
Programming Spring Integration����������������������������������������������������������������������������������������� 386
Using XML���������������������������������������������������������������������������������������������������������������������������� 392
Using Annotations���������������������������������������������������������������������������������������������������������������� 395
Using JavaConfig����������������������������������������������������������������������������������������������������������������� 397
ToDo with File Integration���������������������������������������������������������������������������������������������������� 398
Spring Cloud Stream����������������������������������������������������������������������������������������������������������������� 405
Spring Cloud������������������������������������������������������������������������������������������������������������������������ 405
Spring Cloud Stream����������������������������������������������������������������������������������������������������������� 407
Spring Cloud Stream App Starters��������������������������������������������������������������������������������������� 430
Summary���������������������������������������������������������������������������������������������������������������������������������� 431

x
Table of Contents

Chapter 12: Spring Boot in the Cloud������������������������������������������������������������������� 433


The Cloud and Cloud-Native Architecture��������������������������������������������������������������������������������� 433
Twelve-Factor Applications������������������������������������������������������������������������������������������������������� 434
Microservices���������������������������������������������������������������������������������������������������������������������������� 436
Preparing the ToDo App as a Microservice������������������������������������������������������������������������������� 437
Pivotal Cloud Foundry��������������������������������������������������������������������������������������������������������������� 438
PAS: Pivotal Application Service������������������������������������������������������������������������������������������ 439
PAS Features����������������������������������������������������������������������������������������������������������������������� 440
Using PWS/PAS�������������������������������������������������������������������������������������������������������������������� 441
Cloud Foundry CLI: Command-Line Interface���������������������������������������������������������������������� 444
Log in to PWS/PAS Using the CLI Tool���������������������������������������������������������������������������������� 444
Deploying the ToDo App into PAS����������������������������������������������������������������������������������������� 445
Creating Services���������������������������������������������������������������������������������������������������������������� 448
Cleaning Up������������������������������������������������������������������������������������������������������������������������� 453
Summary���������������������������������������������������������������������������������������������������������������������������������� 454

Chapter 13: Extending Spring Boot���������������������������������������������������������������������� 455


Creating a spring-boot-starter�������������������������������������������������������������������������������������������������� 455
todo-client-spring-boot-starter������������������������������������������������������������������������������������������� 457
todo-client-spring-boot-autoconfigure�������������������������������������������������������������������������������� 459
Creating an @Enable* Feature�������������������������������������������������������������������������������������������������� 467
ToDo REST API Service�������������������������������������������������������������������������������������������������������������� 471
Installing and Testing���������������������������������������������������������������������������������������������������������������� 474
Task Project������������������������������������������������������������������������������������������������������������������������� 474
Running the Task App���������������������������������������������������������������������������������������������������������� 477
Summary���������������������������������������������������������������������������������������������������������������������������������� 479

Appendix A: Spring Boot CLI��������������������������������������������������������������������������������� 481


Spring Boot CLI������������������������������������������������������������������������������������������������������������������������� 481
The run Command��������������������������������������������������������������������������������������������������������������������� 483
The test Command�������������������������������������������������������������������������������������������������������������������� 485

xi
Table of Contents

The grab Command������������������������������������������������������������������������������������������������������������������� 488


The jar Command���������������������������������������������������������������������������������������������������������������������� 489
The war Command�������������������������������������������������������������������������������������������������������������������� 491
The install Command���������������������������������������������������������������������������������������������������������������� 492
The uninstall Command������������������������������������������������������������������������������������������������������������ 493
The init Command��������������������������������������������������������������������������������������������������������������������� 494
The shell Command������������������������������������������������������������������������������������������������������������������ 498
The help Command������������������������������������������������������������������������������������������������������������������� 499
Summary���������������������������������������������������������������������������������������������������������������������������������� 500

Index��������������������������������������������������������������������������������������������������������������������� 501

xii
About the Author
Felipe Gutierrez is a solutions software architect, with
bachelor’s and master’s degrees in computer science from
Instituto Tecnologico y de Estudios Superiores de Monterrey
Campus Ciudad de Mexico. Gutierrez has over 20 years of
IT experience and has developed programs for companies
in multiple vertical industries, such as government, retail,
healthcare, education, and banking. He is currently working
as a platform and solutions architect for Pivotal, specializing
in cloud foundry PAS and PKS, Spring Framework, Spring
Cloud Native Applications, Groovy, and RabbitMQ, among other technologies. He
has also worked as a solutions architect for big companies like Nokia, Apple, Redbox,
and Qualcomm. Gutierrez is the author of Spring Boot Messaging (Apress, 2017) and
Introducing Spring Framework (Apress, 2014).

xiii
About the Technical Reviewer
Manuel Jordan Elera is an autodidactic developer and
researcher who enjoys learning new technologies for his
own experiments and creating new integrations. Manuel
won the Springy Award Community Champion and Spring
Champion 2013. In his little free time, he reads the Bible and
composes music on his guitar. Manuel is known as
dr_pompeii. He has tech reviewed numerous books,
including Pro Spring, 4th Edition (Apress, 2014), Practical
Spring LDAP (Apress, 2013), Pro JPA 2, Second Edition
(Apress, 2013), and Pro Spring Security (Apress, 2013). You
can read his detailed tutorials about Spring technologies and contact him through his
blog at www.manueljordanelera.blogspot.com, and follow him on his Twitter account,
­@dr_pompeii.

xv
Acknowledgments
I would like to express all my gratitude to the Apress team: Steve Anglin for accepting
my proposal, Mark Powers for keeping me on track and for his patience with me, and
the rest of the Apress team involved in this project. Thanks to everybody for making this
possible.
Thanks to my technical reviewer, Manuel Jordan, for all the details and effort in his
reviews, and the entire Spring Boot team for creating this amazing technology.
Thanks to my parents, Rocio Cruz and Felipe Gutierrez, for all their love and support;
to my brother, Edgar Gerardo Gutierrez, and my sister-in-law, Auristella Sanchez, and
specially to my girls, who also keep me on track—Norma, Laura “Lau”, Nayely my “Flaca”,
and Ximena my “Gallito”—I love you girls. And to my baby, Rodrigo!
—Felipe Gutierrez

xvii
CHAPTER 1

Spring Framework 5
Welcome to the first chapter of the book, where I give you an introduction to the Spring
Framework, a little bit of history, and how it has evolved since its inception. This chapter
is for developers that are new to the Spring Framework. If you are an experienced Spring
Framework developer, you can skip this chapter.
Maybe you are thinking, “I want to learn Spring Boot. Why do I need to know about
Spring Framework?” Well, let me tell you that Spring Boot is Spring. Spring Boot has a
different mechanism for running Spring applications; to understand how Spring Boot
really works and does its job, it is necessary to know more about the Spring Framework.

A Little History
The Spring Framework was created in 2003 by Rod Johnson, author of J2EE Development
without EJB (Wrox Publishing, 2004). The Spring Framework was the response to all the
complexity that the J2EE specifications had at that time. Today, it has improved, but you
need to have a whole infrastructure to run certain aspects of the J2EE ecosystem.
We can say Spring is a complementary technology to Java EE. The Spring Framework
integrates several technologies, such as Servlet API, WebSocket API, concurrency
utilities, JSON Binding API, bean validation, JPA, JMS, and JTA/JCA.
The Spring Framework supports the dependency injection and common annotation
specifications that make development easier.
This chapter shows that the Spring Framework version 5.x requires a Java EE 7 level
(Servlet 3.1+ and JPA 2.1) as the minimum. Spring still works with Tomcat 8 and 9,
WebSphere 8, and JBoss EAP 7. Also, I show you the new addition to the Spring
Framework 5— reactive support!
Nowadays, Spring is one of the most used and recognized frameworks in the Java
community, not only because it works, but because it continues to innovate with other
amazing projects, including Spring Boot, Spring Security, Spring Data, Spring Cloud,
Spring Batch, and Spring Integration, among others.
1
© Felipe Gutierrez 2019
F. Gutierrez, Pro Spring Boot 2, https://doi.org/10.1007/978-1-4842-3676-5_1
Chapter 1 Spring Framework 5

Design Principles and Patterns


To know Spring Boot, you need to learn about a framework; it’s important to know not
only what it does but also which principles it follows. The following are some of the
principles of the Spring Framework.

• Provide choice at every level. Spring lets you defer design decisions as
late as possible. For example, you can switch persistence providers
through configuration without changing your code. The same is true
for many other infrastructure concerns and integration with third-­
party APIs. And you will see, this even happens when you deploy
your application to the cloud.

• Accommodate diverse perspectives. Spring embraces flexibility and is


not opinionated about how things should be done. It supports a wide
range of application needs with different perspectives.

• Maintain strong backward compatibility. Spring’s evolution has been


carefully managed to force few breaking changes between versions.
Spring supports a carefully chosen range of JDK versions and third-­
party libraries to facilitate maintenance of applications and libraries
that depend on Spring.

• Care about API design. The Spring team puts a lot of thought and
time into making APIs that are intuitive and that hold up across many
versions and many years.

• Set high standards for code quality. The Spring Framework puts a
strong emphasis on meaningful, current, and accurate Javadocs. It is
one of very few projects that can claim clean code structure with no
circular dependencies between packages.

So, what do you need to run a Spring application? Spring works with Plain Old
Java Objects (POJOs), making it easy to extend. Spring is not invasive and makes your
application enterprise ready; but you need to help Spring by adding a configuration to
wire up all dependencies and inject what’s needed to create Spring beans to execute your
application (see Figure 1-1).

2
Chapter 1 Spring Framework 5

Figure 1-1. Spring context

Figure 1-1 shows the Spring context that creates all the Spring beans—thanks to the
configuration that references your classes, which makes your application run. You find
out more in the next sections, in which you create a complete REST API app.

Spring Framework 5
Spring makes it easy to create Java enterprise applications because it provides everything
that a developer needs to embrace the Java language in an enterprise environment. It
offers excellent support of Groovy and Kotlin as alternative languages on the JVM (Java
virtual machine).
Spring Framework 5 requires JDK 8+ and provides out-of-the-box-support for
Java Development Kit (JDK) 9, 10, and 11. The Spring team has the same long-term
maintenance support for 11 and version 17, which correlates with the JDK team. This
new version came out in 2017 with a new way to do functional programming with
Reactive Streams.
Spring Web MVC was built to serve the Servlet API and Servlet containers. This was
OK until there was more demand for services, which detected a particular problem:
there was some blocking on each request; and with high demand, it was necessary to
do something else. The result: the reactive stack, a web framework. The Spring WebFlux
module was introduced in version 5, with a fully non-blocking stack that supports
Reactive Streams back pressure and runs on servers such as Netty, Undertow, and
Servlet 3.1+ containers. This was part of the answer for a non-blocking stack that handles
concurrency with a small number of threads that can scale with less hardware.

3
Chapter 1 Spring Framework 5

The WebFlux module depends on another Spring project: Project Reactor. Reactor
is the reactive library of choice for Spring WebFlux. It provides the Mono and Flux API
types to work on data sequences of 0..1 and 0..N through a rich set of operators aligned
with the ReactiveX vocabulary of operators. Reactor is a Reactive Streams library, and
therefore, all of its operators support non-blocking back pressure. Reactor has a strong
focus on server-side Java. It is developed in close collaboration with Spring.
I don’t want to get into much of the Spring features because I can show them with
a simple web application. What do you think? All of these cool WebFlux features are
reviewed in its own chapter.

A Simple Spring Web Application


Let’s start by creating a Spring web application— a ToDo app that offers a REST API
that can do a CRUD (create, read, update, and delete). To create a new Spring app, you
need to have Maven installed. In the following chapters, you can choose either Maven or
Gradle.

Using Maven for Creating a Project


Let’s start by using the following command from Maven to create the ToDo Spring
project.

$ mvn archetype:generate -DgroupId=com.apress.todo


-DartifactId=todo -Dversion=0.0.1-SNAPSHOT -DinteractiveMode=false
-DarchetypeArtifactId=maven-archetype-webapp

This command is generating the basic template and structure for web applications.
Normally, it generates the webapp and resources folders but not the java folder, which
you need to create manually.

4
Chapter 1 Spring Framework 5

todo
├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp

You can import the code in your favorite IDE; this will make it easier to identify any
problems.

A
 dding Dependencies
Open pom.xml and replace all the content with Listing 1-1.

Listing 1-1. todo/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=


"http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.apress.todo</groupId>
    <artifactId>todo</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>todo Webapp</name>

    <properties>

        <!-- Generic properties -->


        <java.version>1.8</java.version>

5
Chapter 1 Spring Framework 5

        <!-- Web -->


        <jsp.version>2.2</jsp.version>
        <jstl.version>1.2</jstl.version>
        <servlet.version>3.1.0</servlet.version>
        <bootstrap.version>3.3.7</bootstrap.version>
        <jackson.version>2.9.2</jackson.version>
        <webjars.version>0.32</webjars.version>

        <!-- Spring -->


        <spring-framework.version>5.0.3.RELEASE</spring-­framework.version>

        <!-- JPA -->


        <spring-data-jpa>1.11.4.RELEASE</spring-data-jpa>
        <hibernate-jpa.version>1.0.0.Final</hibernate-jpa.version>
        <hibernate.version>4.3.11.Final</hibernate.version>

        <!-- Drivers -->


        <h2.version>1.4.197</h2.version>

        <!-- Logs -->


        <slf4j.version>1.7.25</slf4j.version>
        <logback.version>1.2.3</logback.version>
    </properties>

    <dependencies>
        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Spring Data JPA -->


        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa}</version>
        </dependency>

6
Chapter 1 Spring Framework 5

        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>${hibernate-jpa.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- Logs -->


        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>

        <!-- Drivers -->


        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
            <scope>runtime</scope>
        </dependency>

7
Chapter 1 Spring Framework 5

        <!-- Java EE Web dependencies -->


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>${jsp.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Web UI -->


        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>${webjars.version}</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>${bootstrap.version}</version>
        </dependency>

        <!-- Web - JSON/XML Response -->


        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
8
Chapter 1 Spring Framework 5

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>${jackson.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>todo</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Listing 1-1 shows the pom.xml file and all the dependencies that you need to create a
simple Spring web app.

Spring Web Configuration


Next, let’s start with the Spring configuration. Spring needs the developer to decide
where the classes are and how they interact with each other, as well some extra
configuration for web applications.
Let’s start by modifying the web.xml file, shown in Listing 1-2.

9
Chapter 1 Spring Framework 5

Listing 1-2. todo/src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>


<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <display-name>ToDo Web Application</display-name>
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

It is necessary to set up the DispatcherServlet, which is the main entry point for
any Spring web app. This class wires up everything based on the context configuration.
As you can see, it is a very trivial configuration.
Next, let’s configure the Spring context by creating a dispatcherServlet-­servlet.
xml file. There is a naming convention; if the servlet is named todo in the web.xml file,
then the Spring context file should be named ­todo-servlet.xml. In this case, the servlet
was named dispatcherServlet, so it looks for a dispatcherServlet-servlet.xml file
(see Listing 1-3).

Listing 1-3. todo/src/main/webapp/WEB-INF/dispatcherServlet-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"

10
Chapter 1 Spring Framework 5

       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
            http://www.springframework.org/schema/mvc http://www.
springframework.org/schema/mvc/spring-mvc-4.3.xsd
            http://www.springframework.org/schema/beans http://www.
springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.
springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/data/jpa http://www.
springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
            http://www.springframework.org/schema/tx http://www.
springframework.org/schema/tx/spring-tx-4.3.xsd">

    <context:component-scan base-package="com.apress.todo" />

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.
MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="jsonMapper"/>
            </bean>
            <bean ­class="org.springframework.http.converter.xml.
MappingJackson2XmlHttpMessageConverter">
                <property name="objectMapper" ref="xmlMapper"/>
            </bean>

        </mvc:message-converters>
    </mvc:annotation-driven>

    <bean id="jsonMapper" class="org.springframework.http.converter.json.


Jackson2ObjectMapperFactoryBean">
        <property name="simpleDateFormat" value="yyyy-MM-dd HH:mm:ss" />
    </bean>

11
Chapter 1 Spring Framework 5

    <bean id="xmlMapper" parent="jsonMapper">


        <property name="createXmlMapper" value="true"/>
    </bean>

    <mvc:resources mapping="/webjars/**" location="classpath:META-INF/


resources/webjars/" />

    <jpa:repositories base-package="com.apress.todo.repository" />

    <jdbc:embedded-database id="dataSource" type="H2">


        <jdbc:script location="classpath:META-INF/sql/schema.sql" />
        <jdbc:script location="classpath:META-INF/sql/data.sql" />
    </jdbc:embedded-database>

    <bean id="jpaVendorAdapter"

          class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="showSql" value="true" />
    </bean>

    <bean id="entityManagerFactory"

          class="org.springframework.orm.jpa.
LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    </bean>

    <bean id="transactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean
            class="org.springframework.web.servlet.view.
InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
12
Chapter 1 Spring Framework 5

<bean id="h2WebServer" class="org.h2.tools.Server" factory-­


    
method="createWebServer"
          init-method="start" destroy-method="stop">
<constructor-arg value="-web,-webAllowOthers,-webDaemon,
        
-webPort,8082" />
    </bean>

</beans>

Listing 1-3 shows the Spring web configuration. Take a look at all the XML
namespaces it uses. This can be helpful because if you use an IDE with code completion,
it gives you the components and their attributes for every entry. Let’s analyze it.

• <context:component-scan/>. This tag tells the Spring container that


it needs to scan all the classes; it looks for annotations, including
@Service and @Configuration. This helps Spring to wire up all the
Spring beans, so that your application can run. In this case, it scans
for the marked classes at the com.apress.todo.* package level and
all the subpackages.

• <mvc:annotation-driven/>. This tag tells the Spring container that


this is a web app, and that it needs to look for every @Controller
and @RestController class and their methods that have
@RequestMapping or other Spring MVC annotations, so it can create
the necessary MVC beans for accepting requests from the user.

• <mvc:message-converters/>. This tag informs the MVC beans


about what to use for message conversion when there is a request.
For example, if there is a request that has the HTTP header Accept:
application/xml, it responds as XML, the same way as when it has
application/json.

• jsonMapper and xmlMapper beans. The classes are Spring beans that
help format the data and create the right mapper.

• <mvc:resources/>. This tag tells the Spring MVC which resources to


use, and where to find them. In this case, this app is using WebJars
(declared in the pom.xml file).

13
Chapter 1 Spring Framework 5

• <jpa:repositories/>. This tag tells the Spring container and


the Spring Data module where the interfaces that extend the
CrudRepository interface are located. In this case, it looks for them
in the com.apress.todo.repository.* package level.

• <jdbc:embedded-database/>. Because this app is using JPA and the


H2 driver for an in-memory database, this tag is just a declaration to
use a utility that can execute SQL script at startup; and in this case, it
creates the todo table and inserts some records.

• jpaVendorAdapter bean. This bean declaration is needed for using


the JPA implementation; in this case, it is Hibernate (a dependency
used in the pom.xml file). In other words, the Hibernate framework is
used as an implementation of Java Persistence API (JPA).

• EntityManagerFactory bean. For every JPA implementation, it is


necessary to create an Entity Manager that holds all the sessions and
executes all the SQL statements on the app’s behalf.

• TransactionManager bean. The app needs to have a transaction,


because we don’t want to have duplicates or bad data, right? We
need to apply and be compliant with ACID (Atomicity, Consistency,
Isolation, Durability), so we need transactions.

• <tx:annotation-driven/>. This annotation sets up all the


transactions based on the previous declarations.

• viewResolver bean. It is necessary to state which kind of a view


engine the web app will use because there are a lot of options, such
as Java Server Faces, JSP, and so forth.

• h2WebServer bean. This bean sets up the H2 engine so that it can be


accessed within the application.

As you can see, this part requires a little bit of knowledge on how to wire up Spring.
If you want to understand more, I recommend several books from the Apress, including
Pro Spring 5, by I. Cosmina, et al.
I want to show you what you need to do to run a simpler REST API; and believe me,
if you think that this is too much, try to do the same with Java EE with all the features this
app has (MVC, JPA, SQL initialization, JSP, transactions).

14
Other documents randomly have
different content
ja katseli eteenpäin. Sitten hän kääntyi heiluttaen hattuaan.
Kuormahevoset pysähtyivät yhteen joukkoon. Dale viittasi tyttöjä
seuraamaan ja ratsasti Royn hevosen rinnalle. Helen huomasi tämän
paikan olevan muutaman poikkipäin kulkevan solan reunalla. Dalekin
laskeutui maahan irroittamatta pyssyään satulasta riippuvasta
tupesta ja lähestyi Royta.

"Hirvas ja pari vaadinta", sanoi tämä hiljaa. "Ne ovat vainunneet


meidät jo, mutta ne eivät ole vielä nähneet meitä. Tytöt, tulkaa vain
lähemmäksi."

Seuraten Dalen pitkän käsivarren viittausta katseli Helen rinteelle.


Se oli melko aukea siellä täällä kasvavine pitkine mäntyineen,
salviapensaikkoineen ja haapoineen, jotka näyttivät kullanvärisiltä
aamuauringon valossa. Äkkiä Bo huudahti: "Ah, katso, minä näen ne
jo!" Silloin Heleninkin tarkasteleva katse huomasi jotakin viheriästä,
kullanväristä ja ruskeasta eroavaa. Kiinnitettyään katseensa siihen
näki hän komean uroshirven jalosti kaareutuvine sarvineen seisovan
kuin patsaan pää pystyssä valppaana ja villissä asennossa. Se oli
harmaa väriltään. Sen vieressä oli pari hennompaa ja
miellyttävämpää eläintä, joilla ei ollut sarvia.

"Ne ovat alempana meitä", kuiskasi Dale. "Ja sinä ammut varmasti
yli."

Silloin Helen huomasi Royn ojentaneen pyssynsä.

"Voi, älkää!" huudahti hän.

Dalen huomautus ärsytti nähtävästi Royta. Hän otti pyssyn


poskeltaan.
"Milt, minähän tätä pyssyä suuntaan. Kuinka voit seisoa siinä ja
sanoa minun ampuvan yli? Minulla oli varma tähtäin siihen."

"Roy, et ole tottunut ampumaan myötämäkeen. Kiiruhda nyt, sillä


se on huomannut meidät jo."

Roy ojensi pyssynsä ja otettuaan samanlaisen jyvän kuin äskenkin


hän laukaisi. Hirvi seisoi kumminkin aivan liikkumatonna kuin kivestä
veistetty patsas. Naaraat sitävastoin hypähtivät pelosta ja katselivat
säikähtyneinä kaikille suunnille.

"Sanoinhan sen sinulle jo. Näin, että luotisi sattui mäntyyn puoli
jalkaa sen lautasten yläpuolelle. Koeta jälleen ja tähtää sen
jalkoihin."

Roy tähtäsi nyt nopeammasti ja vetäisi liipaisinta. Hirven jalan


oikealta puolelta nouseva pölähdys ilmaisi, mihin Royn luoti nyt
sattui. Yhdellä laukalla, joka näytti ihmeelliseltä, katosi hirvi metsään
puiden ja pensasten taakse. Vaatimet seurasivat sitä.

"Koira vieköön!" huudahti Roy muuttuen punaiseksi kasvoiltaan,


kun hän aukoi pyssynsä vipua. "En opi milloinkaan ampumaan
myötämaahan, en totisesti!"

Hänen pahoitteleva anteeksipyyntönsä tytöille


onnistumattomuutensa vuoksi pani Bon iloisesti nauramaan.

"En mistään hinnasta maailmassa olisi tahtonut, että olisitte


onnistunut tappamaan tuon kauniin elukan!" hän huudahti.

"Emme missään tapauksessa saa nyt enää paistia siitä, se nyt on


aivan varmaa", huomautti Dale kuivasti. "Ja ehkä emme milloinkaan
mistään hirvestä, jos Roy vain saa ampua."
He jatkoivat matkaansa poiketen oikealle ja kulkien pitkin solan
reunaa. Lopulta laskeutuivat he solan pohjalle, jossa pieni puro
kiemurteli pajupensaiden suojassa. He seurasivat sitä noin
peninkulman, kunnes se yhtyi muutamaan suurempaan virtaan. Siitä
näytti alkavan eräs ruohon peittämä epäselvästi näkyvä tie.

"Tässä me nyt eroamme", sanoi Dale. "Saavutte luultavasti ennen


minua perille leiriini, mutta minäkin tulen varmasti sinne jolloinkin
pimeän aikaan."

"Kuulehan, Milt, unhotin kokonaan tuon sinun kirotun kesyn


puumasi ja muunkin eläinkokoelmasi. Luuletko niiden voivan olla
peloittamatta tyttöjä, erittäinkin vanhan Tomin?"

"Ette näe Tomia ennen minun tuloani sinne", vastasi Dale.

"Eikö se sitten olekaan missään aitauksessa tahi nuorassa?"

"Ei. Se saa juoksennella vapaana siellä."

"Hyvä sitten. Hyvästi nyt ja koeta kiiruhtaa."

Dale nyökäytti päätään tytöille ja kääntäen hevosensa ajoi hän


kuormahevoset edellään metsää kasvavan rinteen ja joen väliseen
aukkoon.

Roy pysähdytti hevosensa tuolla yksinkertaisella tavalla, joka näytti


niin merkilliseltä tempulta Helenistä.

"Luullakseni on parasta, että kiinnitän satulani remmejä", sanoi


hän heittäen toisen jalustimensa satulannupin yli. "Saatte nyt, tytöt,
kerrankin nähdä villiä luontoa?"
"Kuka vanha Tom on?" kysyi Bo uteliaasti.

"Se on Miltin kesy puuma."

"Puumako? Siis jonkunlainen pantteri eli vuorileijona, kuten hän


sanoi?"

"Niin. Tom on kaunis eläin. Ja jos se suopuu teihin, rupeaa se


rakastamaan teitä, leikkii kanssanne ja jauhaa teidät melkein
kuoliaaksi."

Bo muuttui hetkeksi sanattomaksi hämmästyksestä.

"Onko Dalella muitakin kesyjä eläimiä?" kysyi hän kiihkeästi.

"En ole milloinkaan ollut hänen asunnossaan, mutta luullakseni on


siellä paljon lintuja, oravia ja kaikenlaisia muitakin eläimiä, jotka ovat
niin kesyjä kuin lehmät. Liiankin kesyjä, sanoo Milt. En voi
kumminkaan uskoi sitä. Ette varmaankaan milloinkaan halua poistua
tuolta hänen senacastaan, kun kerran vain sinne pääsette."

"Mikä tuollainen senaca on?" kysyi Helen siirtäessään jalkaansa


niin että Roy voi kiinnittää hänen satulansa remmejä.

"Luullakseni nimittävät meksikolaiset puistojaan siten. Tässä


vuoristossa on paljon tuollaisia paikkoja, enkä milloinkaan haluakaan
nähdä kauniimpia seutuja, ennenkuin tulen taivaaseen. Kas niin,
Ranger, vanha veikko, nyt ne kyllä pitävät."

Hän taputteli hevosta hellästi ja mentyään omansa luo hän hypähti


ja keikautti pitkän ruumiinsa satulaan.
"Kahlaamo ei ole syvä. Tulkaa vain jäljessä!" hän huudahti ja
kannusti kimoaan.

Joki oli tässä kohden leveä, mutta ei syvä, vaikka näytti sellaiselta.

"Nyt, tytöt, alkaa toinen oppitunti!" sanoi Roy iloisesti.


"Ratsastakaa peräkkäin, pysytelkää kintereilläni, tehkää kuten
minäkin ja pysähtykää silloin kun haluatte levähtää tahi jotakin
menee hullusti."

Sanottuaan sen ratsasti hän tiheikköön. Bo seurasi häntä ja sitten


Helen. Pajut tarttuivat häneen niin kovasti, että hänen oli
mahdotonta katsella Royta, ja seuraus oli sellainen, että muudan
puunoksa löi häntä kovasti takaraivoon. Se koski kipeästi, säikähdytti
ja suututti häntä. Roy ratsasti tuollaista hölkkää, joka jouduttaa
matkaa niin hyvin, ja suuntasi kulkunsa vastamäkeen aukeaan
mäntymetsään. Siellä voivat he ratsastaa useita peninkulmia aivan
suoraan tasaista ja aukeata kangasta pitkin. Helen piti tänään
metsästä. Se oli ruskea ja viheriä kullanvärisine läikkineen siellä,
mihin auringonsäteet pääsivät tunkeutumaan. Hän näki nyt
ensimmäiset linnutkin. Suuri sinertävä metso pyrähti lentoon juuri
hevosen edestä ja pieni kirjavanharmaa viiriäinen liiteli omituisesti
etemmäksi. Usein kohdisti Roy heidän huomionsa hirviin, jotka
kiisivät jonkun aukeaman poikki, mutta monesti sattui niin, ettei
Helen ennättänyt niitä ollenkaan huomatakaan.

Helen totesi, että tämä ratsastus korvasi tuon eilisen hirveän


matkan. Tähän asti oli hän vain ollut tietoinen kipeistä paikoista ja
pakottavista luista. Nyt hän voi kestää nuo tuskat hyvin. Hän rakasti
kaunista villiä luontoa, jonka mahtavuus yhä vain eneni sitä mukaa
kuin matka kului. Aurinko paistoi lämpimästi, ilma oli raitis ja
tuoksuva, taivas oli aivan kirkkaansininen ja niin läpinäkyvä, että hän
kuvitteli voivansa nähdä sen pohjaan asti.

Äkkiä pysähdytti Roy hevosensa niin tiukasti, että kimo nousi


pystyyn.

"Katsokaa!" huudahti hän kovasti.

Bo karjaisi.

"Ei sinnepäin, vaan tuonne! Nyt se jo katosi."

"Nell, siellä oli karhu! Näin sen! Se ei ollut ollenkaan sirkuksessa


näytettävien karhujen näköinen!" huusi Bo riemuissaan.

Nell oli menettänyt tilaisuutensa.

"Luullakseni se oli harmaakarhu, ja olen melko iloinen, että se


juoksi tiehensä", sanoi Roy. Muuttaen suuntaansa hieman opasti hän
tytöt erään lahonneen puunrungon hio, jota karhu oli kaivanut. "Se
hakee syötävää. Katsokaa sen jälkiä. Se oli varmasti aika suuri
veijari."

Ratsastaessaan eteenpäin saapuivat he muutamalle korkealle


kunnaalle, josta voitiin katsella solia ja metsiä, kuiluja ja harjanteita,
jotka jatkuivat viheriöinä ja mustina niin kauaksi kuin Helen voi
nähdä. Harjanteet olivat jylhiä ja pitkiä kohoten keskustaa kohti,
jossa muutamat terävät vuoret kohottivat huippujaan Old Baldyn
paljasta lakea vasten. Kaukana oikealla aivan silmänkantamattomissa
näkyi aaltoileva mäntymetsä, kaunis ja rauhallinen. Jossakin sen
takana oli varmaankin erämaa, vaikka sitä ei voitu nähdä.
"Tuolla on kalkkunoita", sanoi Roy peräyttäen hevostaan.
"Laskeutukaamme täältä kiertotietä, niin ehkä saan ampua jonkun
niistä."

Laskeutuessaan muutaman kiviröykkiön taakse oli heidän


kuljettava tiheän viidakon läpi. Rinteellä oli monta penkerettä, joilla
kasvoi pensaikkoa, harvaa mäntymetsää ja tammia. Helen ihastui
nähdessään tuon tutun puun, vaikka nämä olivatkin erilaisia kuin
Missourin tammet. Ollen kyhmyisiä ja rosoisia, mutta ei pitkiä,
levittivät nämä puut leveälle oksansa, joissa olevat lehdet olivat
kellertäviä. Roy suuntasi kulkunsa muutamaan ruohoakasvavaan
metsäaukioon ja laskeuduttuaan satulasta, pyssy kourassa
valmistautui hän ampumaan jotakin. Jälleen Bo huudahti, mutta tällä
kertaa ilosta. Silloin huomasi Helen äärettömän suuren parven
kalkkunoita, jotka olivat melkein sen näköisiä kuin kesytkin
kalkkunat, paitsi että nämä olivat ruskean- ja valkoisenkirjavia ja
näyttivät villeiltä. Niitä oli varmaankin tuossa parvessa melkein sata,
enimmäkseen naaraita. Muutamat etäisimmässä laidassa olevat
uroot aloittivat paon juosten nopeasti. Helen kuuli selvästi niiden
jalkojen kumahdukset. Roy ampui kerran, sitten taasen ja vielä
kerran. Sitten seurasi hirveätä hälinää ja tömähtelyä, ja monien
siipien aiheuttamaa äänekästä suhinaa. Tomu ja lehdet liehuivat vain
tuulessa siinä paikassa, josta kalkkunat olivat lähteneet lentoon.

"Sain kumminkin pari", sanoi Roy mennessään sinne päin


hakemaan saalistaan. Palattuaan sitoi hän kaksi kimaltelevaa lihavaa
kalkkunakukkoa satulaansa ja hyppäsi sitten itsekin hevosen selkään.
"Saamme kalkkunaa illalliseksi, jos vain Milt ehtii leiriin ajoissa."

Jatkettiin matkaa. Helen ei olisi milloinkaan väsynyt näiden


tammilehtojen läpi ratsastamiseen. Ne olivat jo ruskeita, lakastuneita
ja keltaisia ja pudottelivat lehtiään ja terhojaan.

"Karhut ovat jo käyneet saalistamassa täällä", sanoi Roy. "Näen


niiden jälkiä kaikkialla. Ne syövät mielellään tammenterhoja niiden
putoamisaikana. Ehkä vielä kohtaamme jonkun niistä."

Kauempana poikkesi hän villimpään ja tiheämpään metsään, jossa


oksien lyöntien varominen ei ollut mikään helppo asia. Ranger ei
näyttänyt välittävän, miten läheltä se sivuutti puun tahi oksan,
kunhan se ei vain raapaissut niihin itseään. Helen kumminkin sai
osakseen muutamia kovia iskuja. Puita sivuuttaessa oli vaikeinta
saada polvensa ajoissa suojaan.

Roy pysähtyi seuraavan kerran paikalle, joka näytti suurelta kasvia


täynnä olevalta lammikolta siellä täällä olevine suurine
vaahtokuplineen. Se poreili kumminkin ja siitä lähti pieni puronen,
joten se osoittautuikin olevan suuri lähde. Roy viittasi erääseen
mutaiseen kohtaan.

"Karhu on piehtaroinut tuossa. Se kuuli tulomme. Katsokaa näitä


pieniä jälkiä. Sillä on penikka mukanaan. Näette kai nuo naarmut
tuossa puussa hieman pääni yläpuolella. Vanha naaraskarhu seisoi
sitä vasten ja iski kyntensä siihen."

Istuen satulassaan ojentautui Roy ylettyäkseen koskemaan noihin


tuoreihin naarmuihin puussa.

"Metsät ovat täynnä suuria karhuja", sanoi hän hymyillen.


"Minusta käyttäytyi tämä vanha rouva erittäin ystävällisesti
mennessään penikkoineen tiehensä. Kun naaraskarhuilla on
penikoita, ovat ne hyvin vaarallisia."
Seuraavan kerran innostui Helen saapuessaan solan pohjalla
olevaan notkoon. Pyökit, vaahterat, haavat ja ilmavat männyt
varjostivat puroa, jonka ruskeissa nopeissa pyörteissä taimenet
polskahtelivat, lehdet seurasivat mukana ja eksyneet kultaiset
auringonsäteet valaisivat hämärää metsää. Täällä oli ratsastaminen
vaikeaa, kun oli aina tämän tästä kahlattava puron poikki,
tunkeuduttava suurten sammalta kasvavien kallioiden välitse ja
läpäistävä niin tiheitä haavikoita, että Helen tuskin sai polvensa
pujotelluksi läpi.

Roy ratsasti vielä kerran pois tästä solasta muutaman harjanteen


yli toiseen, sitten metsäisiä rinteitä pitkin ja pensaikkojen ja
viidakkojen läpi. Aurinko paistoi koko ajan korkealta taivaalta. Sitten
hän pysähtyi hetkeksi lepäämään, irroitti satulat antaakseen
hevosten piehtaroida ja tarjosi tytöille jotakin kylmää haukattavaa,
jota hän oli ottanut mukaansa. Sitten hän läksi pyssyineen jonnekin
kauemmaksi ja palattuaan satuloi hevoset antaen merkin matkan
uudelleen aloittamiseksi.

Tämä oli viimeinen levähdys tytöille ja siihen loppui myöskin


helppo matka. Metsässä, johon Roy nyt poikkesi, oli kuin
pesulaudassa uria, jotka olivat niin syviä ja jyrkkiä, että
ratsastaminen niiden poikki oli hyvin vaarallista. Enimmäkseen
pysytteli Roy jonkun sellaisen pohjalla, missä kuivuneet rämeet
tarjosivat jonkunlaisen tien. Mutta noiden kuilujen poikki oli pakko
kulkea silloin kun ne olivat liian pitkiä kierrettäviksi ja tuollainen
ylimeno oli vaikeata.

Näiden rinteiden viidakkojen luonteenomaisimmat kasvit olivat


jonkunlaiset piikkiset ja sotkuiset pensaat. Ne repivät, raatelivat ja
pistelivät sekä hevosia että ratsastajia. Ranger osoittautui olevan
viisain hevosista ja kärsi senvuoksi vähimmin. Bon valkoinen
mustangi vei Bon useamman kuin yhden risukon läpi. Toiselta puolen
taasen olivat nämä jyrkät rinteet melko vapaat tuollaisesta
pensaikosta. Suuria mäntyjä ja kuusia kasvot kaikilla suunnilla. Maa
oli niin pehmeä, että kaviot vajosivat siihen syvälle. Melkein rinteen
juurella nojautui Ranger etujalkoihinsa ja liukui alas istualleen.
Tällainen helpotti kulkua, mutta se peloitti Heleniä. Kiipeämisen
seuraavalle rinteelle täytyi sitten tapahtua jalan.

Kun puoli tusinaa rinteitä oli sivuutettu sillä tavoin, olivat Helenin
voimat lopussa eikä hän voinut enää juuri hengittääkään. Häntä
pyörrytti eikä hän voinut saada tarpeekseen ilmaa. Hänen jalkansa
tuntuivat lyijynraskailta ja ratsastuskaapu tuntui oikealta kuormalta.
Hänen oli pakko pysähtyä satoja kertoja lämmön, hiostumisen ja
hengästymisen vuoksi. Hän oli aina ennen ollut hyvä kävelijä ja
kiipeilijä, ja täällä vaihteeksi tähän pitkään ratsastusmatkaan oli hän
iloinen saadessaan kävellä. Mutta hän voi vain vetää jalkoja
perässään. Sitten kun hänen nenästään alkoi vuotaa verta, ymmärsi
hän, että syynä tähän kaikkeen oli vain tämän korkealla olevan
seudun ohut ilma. Hänen sydäntään ei kumminkaan pakottanut,
vaikka hän tunsikin jonkunlaista painoa rinnassaan.

Vihdoin Roy johti heidät niin syvään, laajaan ja tiheätä metsää


kasvavaan kuiluun, että sen poikki tuntui mahdottomalta kulkea.
Kumminkin läksi hän laskeutumaan sinne laskeutuen satulasta vähän
ajan kuluttua. Helen tunsi, että Rangerin taluttaminen sinne oli vielä
vaikeampaa kuin sillä ratsastaminen. Se käveli niin nopeasti, että se
oli polkea hänen kantapäänsä rikki. Helen ei ollut tarpeeksi nopea
päästäkseen ajoissa pois sen tieltä. Kahdesti astui se hänen
kantapäilleen ja silloin painoi sen leveä rinta Helenin aivan maahan
asti. Kun se alkoi liukua lähellä rinteen juurta oli Helenin pakko
juosta henkensä edestä.

"Ah, Nell, eikö tämä olekin suurenmoista?" huohotti Bo jostakin


edeltä.

"Bo, olet tullut hulluksi", läähätti Helen vastaukseksi.

Roy koetti monta paikkaa päästäkseen kuilusta, mutta ei


onnistunut. Kuljettuaan kuilun pohjaa pitkin noin sata metriä tahi
hieman enemmän koetti hän uudestaan. Siinä kohden oli lumivyöry
paljastanut maan monesta paikasta. Kun hän oli päässyt laelle,
pysähtyi hän ja huusi:

"Vaikea kohta! Pysytelkää hevosten sivulla!"

Se oli kumminkin helpommin sanottu kuin tehty. Helen ei voinut


pitää silmällä Bota, koska Ranger ei suostunut odottamaan. Se veti
ohjaksista ja korskui.

"Kuta nopeammin tulette, sitä parempi!" huusi Roy heille.

Helen ei voinut ymmärtää sen hyötyä, mutta hän koetti. Roy ja Bo


olivat muodostaneet syvän polvitellen kulkevan tien tuohon
peloittavaan jyrkänteeseen. Helen teki sen erehdyksen, että hän
alkoi seurata heidän jälkiään, ja kun hän huomasi Rangerin kiipeävän
niin nopeasti, että se melkein veti häntä, oli myöhäistä mennä sitä
korkeammalle. Helen alkoi ponnistella, mutta liukuikin suoraan
Rangerin eteen. Tuo ymmärtäväinen eläin hyppäsi korskahtaen
syrjään voidakseen olla astumatta hänen ruumiilleen. Samalla
sivuutti se hänet.
"Olkaa varuillanne siellä!" huusi Roy varoittavasti. "Koettakaa
päästä sen yläpuolelle!"

Se ei ollut kumminkaan mahdollista. Maa alkoi vyöryä Rangerin


alta ja se esti Helenin kulun. Ranger pääsi häntä korkeammalle ja
veti suitsista.

"Päästäkää irti!" huusi Roy.

Helen irroitti suitset käsistään juuri kun suuri vyöry aikoi tempaista
Rangerin mukaansa. Se korskahti hurjasti ja nousten takajaloilleen
pääsi se lujalle maalle mahtavalla hypyllä. Helen hautautui polviaan
myöten, mutta vapautettuaan itsensä ryömi hän turvalliseen
paikkaan ja lepäsi, ennenkuin läksi jatkamaan kiipeämistä.

"Tuo on paha paikka", sanoi Roy, kun Helen lopulta yhtyi häneen
ja
Bohun rinteen laella.

Roy näytti nyt olevan ymmällä, mihinpäin heidän oli lähdettävä.


Hän ratsasti muutamalle korkeammalle paikalle ja katseli sieltä
kaikille suunnille. Helenistä näytti toinen suunta yhtä villiltä ja
luoksepääsemättömältä kuin toinenkin. Länteen painuva aurinko
muutti seudut keltaisiksi, viheriöiksi ja mustiksi. Roy ratsasti lyhyen
matkan toiseen suuntaan ja kääntyi sitten toisaallepäin.

Äkkiä hän pysähtyi.

"Olen varmasti pyörtänyt ympäri", sanoi hän.

"Ette suinkaan ole eksynyt?" huudahti Bo.


"Olen varmasti ollut jo eksyksissä pari tuntia", vastasi Roy iloisesti.
"En ole milloinkaan ratsastanut suoraan tänne. Minulla on kyllä
suunta selvillä, mutta minut voidaan hirttää nyt, jos tiedän, mihin
päin meidän on mentävä."

Helen katsoi häneen hämmästyneenä.

"Eksyksissä!" hän huudahti.


IX.

Seurasi vaitiolo, joka täytti Helenin sydämen sanomattomalla pelolla,


kun hän katsoi Bon vaaleneviin kasvoihin. Hän luki sisarensa
ajatukset. Bo muisteli kertomuksia eksyneistä ihmisistä, joita ei
milloinkaan oltu löydetty.

"Minä ja Milt eksymme joka päivä", sanoi Roy. "Ette suinkaan luule
kenenkään miehen tuntevan perinpohjin tätä laajaa seutua?
Tällainen eksyminen ei merkitse mitään."

"Niin, minäkin eksyin kerran ollessani pieni", sanoi Bo.

"Olisi ollut parempi, etten olisi sanonut sitä teille niin suoraan",
sanoi Roy katuvasti. "Älkää olko pahoillanne nyt. Minun on vain
saatava Old Baldyn huippu näkyviin ja silloin olen taasen varma
suunnasta. No tulkaahan nyt."

Helenin luottamus palasi, kun Roy läksi johtamaan ratsastaen


nopeasti. Hän suuntasi kulkunsa laskeutuvaa aurinkoa kohti
pysytellen harjanteella, jolle he olivat juuri äsken kiivenneet, kunnes
he kerran vielä saapuivat eräälle kallioniemekkeelle. Siihen näkyi Old
Baldykin mustempana, korkeampana ja lähempänä kuin ennen. Sitä
ympäröivässä tummassa metsässä oli pyöreitä, keltaisia ja paljaita
paikkoja kuin puistoja.

"Emme ole poikenneet oikeasta suunnasta paljonkaan", sanoi Roy


kääntäessään hevosensa. "Ennätämme kyllä Miltin asuntoon illaksi."

Hän ratsasti harjanteelta muutamaan laaksoon ja sitten jälleen


korkeammalle seudulle, jossa metsän luonto muuttui. Puut olivat
täällä ohuita ja hyvin pitkiä honkia, joissa oli vain muutamia oksia
latvatupsun alapuolella. Niitä kasvoi niin tiheässä, että metsässä oli
aivan hämärä. Ratsastaminen muuttui vaivalloiseksi. Kaikkialla oli
tuulen kaatamia puita, jotka oli kierrettävä, eivätkä hevoset voineet
ottaa askeltakaan kohtaamatta sellaisia. Hitaasti kulkevat hevoset
vajosivat joskus polviaan myöten johonkin ruskeaan tomuun. Puiden
rungoissa kasvoi harmaata naavaa ja lahoavia runkoja peitti
ambranviheriä sammal paksuin kerroksin.

Helen mieltyi heti tähän aarniometsään. Se oli niin hiljainen, niin


pimeä, niin synkkä, niin täynnä varjoja ja haamuja, ummehtuneen
lahonneen puun hajua ja kuusten suloista tuoksua. Suuret murrot,
joissa oli tusinoittain kaatuneita puita, ilmaisivat myrskyjen voimaa.
Mihin joku yksinäinen suuri jättiläinen oli juurtunut, oli sen
läheisyyteen ilmestynyt kunnianhimoisia poikia, jotka olivat
kateellisia toisilleen taistellessaan paikasta. Puutkin sotivat toisiaan
vastaan. Metsä oli täynnä salaperäisyyttä, mutta jokainen ihminen
voi huomata siellä tapahtuvan taistelun. Salamat olivat halkaisseet
puita juureen asti tahi uurtaneet niihin syviä uria latvasta maahan
asti.

Koitti kumminkin aika, jolloin metsän erinomainen villeys ja


kaatuneiden puiden paljous pakottivat Helenin kiinnittämään kaiken
huomionsa maahan ja läheisyydessä kasvaviin puihin. Siten kiellettiin
häneltä huvi katsella eteensä tuonne kauniiseen korpeen. Matkakin
muuttui nyt vaivalloiseksi ja tunnit äärettömän pitkiksi.

Roy johti ja Ranger seurasi varjojen tummetessa puiden juurilla.


Helen istui kumarruksissa satulassa melkein sokeana ja sairaana,
kun Roy huusi iloisesti, että oltiin jo melkein perillä.

Helen ei ymmärtänyt hänen tarkoitustaan, sillä hän sai seurata


Royta vielä monta peninkulmaa pois tuosta suuripuisesta metsästä
rinteille, joilla kasvoi matalaa, ikiviheriää kuusikkoa ja jotka
laskeutuivat jyrkästi jollekin tasangolle, missä tummat, matalat joet
virtasivat hitaasti ja pyhään hiljaisuuteen sekoittui putoavan veden
kohinaa. Vihdoin loppui metsä ihmeelliseen puistoon, joka oli täynnä
nopeasti tapahtuvan auringonlaskun kullalta hohtavaa kirkasta valoa.

"Tunnetteko savun hajua?" sanoi Roy. "Koira vieköön, Milt on


luullakseni ehtinyt ennen meitä tänne!"

Hän jatkoi matkaansa. Helenin väsyneet silmät tarkastelivat tuota


pyöreätä puistoa, sitä ympäröiviä tummia rinteitä, jotka johtivat
kallioisille, nyt auringon viimeisten säteitten punaisiksi kultaamille
harjanteille. Silloin kaikki jäljellä oleva innostus hänessä puhkesi
ihmettelevään riemuun tämän erinomaisen, villin ja värikkään paikan
kiihoituksesta.

Hevoset kävivät laitumella pitkässä ruohokossa ja niiden joukossa


oli muudan antilooppikin. Roy ratsasti erään rajoittavan
metsäniemekkeen ympäri, ja hieman kauempana ilmavien puiden
suojassa paloi iloinen nuotio, Taustassa oli suuria harmaita kallioita
ja sitten alkoi vuori kohota penkereittäin kukkulan kyljessä olevaksi
ahtaaksi solaksi, josta suihkusi ohut pieni vesiputous. Kun Helen
katsoi riemuissaan, muuttui auringonlaskun kulta valkoiseksi ja kaikki
amfiteatterin läntiset rinteet tummenivat.

Dalen pitkä vartalo ilmestyi näkyviin.

"Olette melkoisesti myöhästyneet", sanoi hän tarkastellen heitä


kaikkia kolmea.

"Milt, satuin eksymään", vastasi Roy.

"Sellaista pelkäsinkin. Te, tytöt, olette sen näköisiä kuin olisitte


tehneet viisaammasti lähtemällä minun mukaani", jatkoi Dale
ojentaessaan kätensä auttaakseen Bon satulasta. Tämä tarttui
siihen, koetti irroittaa jalkojaan jalustimista, mutta liukuikin samalla
satulasta Dalen syliin. Dale laski hänet seisomaan maahan ja
kannattaen häntä sanoi innokkaasti: "Sadan peninkulman ratsastus
kolmessa päivässä on jotakin sellaista, jota ei enonne Al tule
milloinkaan uskomaan. Kävelkää nyt, vaikka luulisitte
kuolevannekin."

Sitten hän talutti Bota melkein kuin pientä lasta kävelemään


opetettaessa. Ettei puheliaalla Bolla ollut mitään sanottavaa, oli
merkityksellistä Helenistä, joka seurasi Royn avustuksella.

Eräs noista suurista kallioista muistutti meriraakkua, jossa oli


syvennys, minkä yli tuo leveä reunake ulottui. Se jatkui melkein
suurten kuusien oksiin asti. Kirkas lähde pulppusi muutamasta
kallionhalkeamasta. Nuotio räiskyi erään kuusen juurella ja sininen
savupatsas kohosi juuri tuon suojelevan kallionkielekkeen edustalta.
Maassa oli paljon myttyjä, joista muutamat oli avattu. Mitkään merkit
eivät ilmaisseet, että metsästäjä asui täällä tavallisesti. Mutta
kauempana oli toisia suuria kallioita, nojollaan olevia, halkinaisia ja
onkaloisia, jollaisen Dale oli ehkä valinnut asunnokseen.

"Asuntoni on aivan tuolla takana", sanoi Dale kuin vastaukseksi


Helenin lausumattomaan kysymykseen. "Huomenna järjestämme
olon teille täällä niin mukavaksi kuin suinkin."

Helenille ja Bolle valmistettiin niin mukava leposija kuin


huopapeitteistä ja satuloista suinkin voitiin saada, ja sitten palasivat
miehet töihinsä.

"Nell, eikö tämä olekin kuin unta?" mumisi Bo.

"Ei, tyttöseni, vaan todellisuutta — peloittavaa todellisuutta",


vastasi Helen. "Nyt kun olemme saapuneet tänne kestettyämme
tuon kauhean ratsastuksen, voimme ajatella."

"Täällä on niin kaunista", huudahti Bo. "Tuntuu oikein


helpotukselta, ettei eno Al löydä nyt meitä hyvinkään nopeasti."

"Bo, hän on sairas. Ajattele, mitä tällainen ikävyys hänelle


merkitsee."

"Lyön vaikka vetoa, että jos hän vain tuntee Dalen hyvin, ei hän
ole hyvinkään huolissaan."

"Dalehan kertoi eno Alin vihaavan häntä."

"Joutavia! Ja mitä se sitten voi vaikuttaa asiaan? Voi, en tiedä,


mikä minun oikeastaan on, olenko nälissäni vaiko väsynyt!"

"En voi syödä mitään tänä iltana", sanoi Helen väsyneesti.


Kun hän ojentautui pitkäkseen, tunsi hän epämääräisesti ja
miellyttävästi, että tämä oli entisen Helen Raynerin loppu, ja hän
iloitsi siitä. Ylhäältä, noiden pitsimäisten ja sananjalkoja
muistuttavien kuusten lehvien välistä näkyi palanen sinistä taivasta
ja muudan kalpea tähti. Hämärä alkoi levitä nopeasti seudulle.
Hiljaisuus oli miellyttävää eikä sitä putouksen pehmeä, hieno ja
uneksiva kohinakaan tuntunut juuri häiritsevän. Helen ummisti
silmänsä valmistautuen nukkumaan hänen ruumiillisen
levottomuutensa vähitellen rauhoittuessa. Toisissa paikoissa
tuntuivat luut tunkeutuneen lihasten läpi, toisissa taasen jäyti tuska
syvällä, hänen lihaksensa olivat vastahakoiset höltymään ja
lientymään viiltävän tuskan värisyttäessä niitä vuorotellen. Lihasten
ja luiden, lyhyesti sanoen, koko ruumiin läpi kohisi polttava virta.

Bon pää painui Helenin olalle. Kaikki muuttui pian epämääräiseksi


Helenillekin. Putouksen hiljainen kohina lakkasi kuulumasta eikä hän
enää käsittänyt, mitä nuotionkaan luona oikein tehtiin. Hänen
viimeinen tietoinen ajatuksensa oli, että hän koetti aukaista
silmänsä, mutta ei voinut.

Kun hän heräsi oli kaikki valoisaa. Aurinko paistoi melkein suoraan
ylhäältä. Hän hämmästyi. Bo nukkui vielä sikeästi, hänen kasvonsa
olivat punaiset, otsassa oli hikipisaroita ja kastanjanruskea tukka oli
aivan kostea. Helen heitti huopapeitteet yltään ja sitten rohkaisten
mieltään, sillä hänestä tuntui kuin hänen selkänsä olisi ollut poikki,
koetti hän nousta istualleen, mutta ei onnistunut. Hänen henkensä
olisi kyllä ollut altis, mutta lihakset kieltäytyivät tottelemasta. Hänen
oli tehtävä toinen suonenvedontapainen voimakas yritys. Hän ryhtyi
siihen suljetuin silmin ja onnistuttuaan hän istui siinä vapisten.
Hänen tekemänsä liikkeet huopapeitteiden alla herättivät Bon, joka
tuijotti nyt hämmästynein sinisin silmin aurinkoon.
"Halloo, Nell, onko minunkin noustava?" kysyi hän unisesti.

"Voitko?" kysyi Helen.

"Voinko mitä?" Bo oli nyt kokonaan hereillä ja tuijotti sisareensa.

"Nousta tietysti!"

"Haluaisin tietää, miksi en voisi", sanoi Bo koettaen samalla. Hän


saikin toisen käsivartensa ja olkansa kohoamaan vaipuakseen sitten
takaisin kuin raajarikko. Hän vaikeroi samalla hyvin surkeasti. "Olen
kuollut! Tiedän, että olen!"

"Jos aiot todella kehittyä todelliseksi Lännen tytöksi, on sinun


rohkaistava luontosi ja noustava."

"Vai niin!" huudahti Bo. Sitten hän kääntyi vatsalleen vaikeroiden,


mutta päästyään kerran siihen asentoon nousi hän käsivarsiensa
varaan ja kääntyi istuvaan asentoon. "Missä kaikki muut ovat? Ah,
Nell, miten täällä onkaan kaunista! Kuin paratiisissa."

Helen katseli ympärilleen. Nuotio palaa loimusi, mutta ei ketään


ollut näkyvissä. Ihmeelliset kaukaiset värit sattuivat hänen silmiinsä,
kun hän koetti katsoa lähellä olevia esineitä. Kaunis pieni viheriä
teltta tahi katos oli rakennettu kuusen oksista. Sen katto aleni
tasaisesti muutamalta kallionkielekkeeltä maahan, puolet päädystä
oli suljettu samoin kuin sivutkin. Kaikki oksat oli nähtävästi asetettu
samaan suuntaan suoden majalle sellaisen sileän ja kiinteän muodon
kuin se olisi kasvanut siihen.

"Tuo turvapaikka ei ollut tuossa eilen", sanoi Bo.


Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

textbookfull.com

You might also like