Hacking with Spring Boot 2.3: Reactive Editioninstant download
Hacking with Spring Boot 2.3: Reactive Editioninstant download
https://ebookmass.com/product/hacking-with-spring-
boot-2-3-reactive-edition/
Follow him on Twitter @gregturn and subscribe for all his Spring Boot
videos at YouTube.com/GregTurnquist.
PREFACE
What this book covers
Chapter 1, Building a Web App with Spring Boot - Learn how to build web
applications using Spring WebFlux.
Chapter 2, Data Access with Spring Boot - Access reactive data stores using
Spring Data.
Chapter 4, Testing with Spring Boot - Get a hold of reactive testing tools and
how Spring Boot empowers testing your applications.
Chapter 6, Building APIs with Spring Boot - Build JSON-based APIs using
different tactics and tools from the Spring portfolio.
Chapter 8, RSocket with Spring Boot - Discover a protocol that has reactive
baked right in and supports multiple ways to communicate.
Chapter 9, Securing your Application with Spring Boot - Learn how secure
your application with the most powerful tools available.
What you need for this book
Spring Boot 2.3 supports Java 8 and higher. This book is written using Java
8. Use sdkman to install, manage, and even switch between different
distributions and versions of Java.
Spring Boot 2.3 is able to bake Docker containers. There is also Docker-
based testing support through 3rd party tools like Testcontainers. For those
sections, you’ll need to install Docker.
▪ IDE
◦ IntelliJ IDEA
◦ Spring Tool Suite
◦ VS Code
◦ Eclipse
▪ Editor
◦ Sublime Text 3
◦ Atom
Who should read this book
This book is to help developers new to Spring Boot as well as experienced
Spring developers.
It shows how to get operational, fast, with some of the best coding practices
available.
It helps the reader focus on adding business value to their applications and
not get distracted with infrastructure.
Optimal viewing
Adjust your e-reader to use a smaller font. This book is loaded with code
examples. Attempting to show things too big will cause unneeded wrapping,
culminating in a less than desirable experience.
Conventions
In this book, you will find a number of styles of text.
Code found in the text are shown like this: "A Spring WebFlux controller is
flagged with an @Controller annotation."
@RestController
class WebController {
@GetMapping("/api")
Mono<String> home() {
return Mono.just("Hello, world!");
}
}
When certain parts of the code are described in more detail, they are
annotated with a circled number at the end of the line.
Code with annotated lines
@Component ①
public class RepositoryDatabaseLoader {
@Bean ②
CommandLineRunner initialize(BlockingItemRepository repository)
{ ③
return args -> { ④
repository.save(new Item("Alf alarm clock", 19.99));
repository.save(new Item("Smurf TV tray", 24.99));
};
}
}
① This comment describes the line above with the (1) comment.
Sometimes you’ll see chunks of code that have comments at the end with no
numbering. To improve readability in the code and in the manuscript, line
breaks are sometimes forced.
Warnings appear like this.
Tips appear like this.
@
Notes appear like this.
Important facts appear like this.
Reader feedback
The most valuable feedback you can leave is an honest review.
Please visit Amazon when you finish and share you personal opinion of
Hacking with Spring Boot 2.3: Reactive Edition.
Support
If you have issues with getting your copy, contact the provider.
If you are having issues with the code, please file a ticket at
https://github.com/hacking-with-spring-boot/hacking-with-spring-boot-
code/issues.
Are you ready? Chapter 1, Building a Web App with Spring Boot is waiting!
Building a Web App with Spring Boot
Working with Spring Boot is like pair-
programming with the Spring developers.
Six years ago, something amazing happened. Spring Boot 1.0 was released.
On April 1st, 2014, project lead Phil Webb published a blog article detailing
the first stable release.[1]
And the crowd went wild. The Java community embraced this amazing
culmination of engineering and creative art with fervent excitement.
Searching Twitter for #springboot tweets generated an avalanche of activity.
Three years later, in 2017, the marketing department of Pivotal tweeted that
Spring Boot’s download growth had achieved 19.7MM downloads per
month.[2]
If you’ve never used Spring Boot before, get ready for some fun. This book is
jam-packed with extra goodies that perhaps you weren’t aware of. Your
knowledge will be extended so you can take full advantage of its features.
You can also subscribe to my YouTube channel and see my fun videos about Spring Boot.
Using this powerful and widely adopted stack, you’ll build a system with
speed AND stability.
In Hacking with Spring Boot 2.3: Reactive Edition you will also explore the
new paradigm of reactive programming, introduced in Spring Framework
5.0. As you build bigger and bigger systems with increasing volume of users,
you need an approach that is steady and rock-solid. Such high-end systems
require the ability to process possibly unlimited streams of data arriving
asynchronously and in a non-blocking fashion.
Probably because the number of shops needing it has been rather small. But
the world is entering a new era. Startups are having to serve content to
literally millions of users. International audiences demand around-the-clock
operational support. And as cloud-based hosting of applications grows in
popularity, the concept of "throw some more servers at the problem" isn’t
working.
Throughout this book, you’ll learn more and more about what this means.
But bottom line, the Spring portfolio of projects makes it easy to embrace
scalable solutions without having to start from scratch.
Continuing with this metaphor, the server doesn’t know when the next dish
will be finished by the kitchen. But when it is and when he or she is
available, the server is able to deliver the next dish.
class KitchenService {
Flux<Dish> getDishes() {
// You could model a ChefService, but let's just
// hard code some tasty dishes.
return Flux.just( //
new Dish("Sesame chicken"), //
new Dish("Lo mein noodles, plain"), //
new Dish("Sweet & sour beef"));
}
}
As a server, you can ask that the KitchenService provide you with
Dish objects to walk out to customers. Instead of being handed a batch, you
instead receive this Flux<Dish> object. It means the dishes aren’t
available, yet. But they will be at some point. Exactly when, you can’t be
sure.
But when they are, you can act. Or shall we say, react. That’s because
Reactor is non-blocking. You don’t hold up the "server" thread (see what I
did there?) waiting for the kitchen to do its job.
So what does Flux offer that Future does not? Flux<Dish> has the
following characteristics:
▪ Handles more than one Dish.
A lot of this limited functionality is tied up in the fact that Java’s Future
API was introduced with Java 5, which dates back to 2004. That was long
before Java introduced functional programming constructs. The other factor
is that Future is squarely aimed at providing a single value, while Flux is
meant for multiple values. There have been some updates to Java’s
Future<T> class, but they just don’t cut it when you want to implement
backpressure and demand control.
class SimpleServer {
SimpleServer(KitchenService kitchen) {
this.kitchen = kitchen;
}
Flux<Dish> doingMyJob() {
return this.kitchen.getDishes() //
.map(dish -> Dish.deliver(dish));
}
▪ After asking the kitchen for dishes, it uses .map() to define a handler for
what to do with each dish when it arrives. In this case, invoke the
deliver(dish) function.
Look closely, and you’ll notice that while retrieving a Flux of Dish objects
from the kitchen, it itself returns the same type. The difference being that
t h e kitchen produces a cooked series of entrées, while the
SimpleServer produces a delivered series of entrées.
In the code above, you are using a Java 8 lambda function, dish →
Dish.deliver(dish). "lambda" is a fancy way of saying "anonymous." On the left
side of the arrow are the inputs (dish in this case). On the right side of the arrow is what
you do with it. SimpleServer invokes its deliver() function. This function is
applied to each and every Dish the kitchen sends through this Flux. Because this
map transforms one Flux into another, it’s mapping function must return something!
That’s why your deliver() function can’t have a void return type. So instead, it
returns dish.
Project Reactor provides a rich programming model. Not only can you do
functional transforms, but you can hook into the Reactive Stream lifecycle
which includes onNext(), onError(), and onComplete() signals -
something else missing from Future objects.
class PoliteServer {
PoliteServer(KitchenService kitchen) {
this.kitchen = kitchen;
}
Flux<Dish> doingMyJob() {
return this.kitchen.getDishes() //
.doOnNext(dish -> System.out.println("Thank you for " +
dish + "!")) //
.doOnError(error -> System.out.println("So sorry about "
//
+ error.getMessage())) //
.doOnComplete(() -> System.out.println("Thanks for all
your hard work!")) //
.map(Dish::deliver);
}
This server has the same initialization of the kitchen as well as how each
dish is handled. But it has the following differences in its doingMyJob()
function:
What’s not shown is the fact that you can use these methods more than once.
Register all the handlers you need!
return this.kitchen.getDishes() //
.doOnNext( //
dish -> System.out.println("Thank you for " +
dish + "!")) //
.doOnNext( //
dish -> System.out.println("Marking the ticket as
done.")) //
.doOnNext(dish -> System.out.println("Grabbing some
silverware.")) //
.map(this::deliver);
return this.kitchen.getDishes() //
.doOnNext(dish -> {
System.out.println("Thank you for " + dish + "!");
System.out.println("Marking the ticket as done.");
System.out.println("Grabbing some silverware.");
}) //
.map(this::deliver);
While it may, at first, seem handy to avoid getting things tangled together, it’s actually
more performant to reduce the number of callbacks. You can still maintain separation by
having the functions themselves grouped in proper classes.
Instead, it’s about keeping different tasks and functions free and clear of each other.
So far, you have defined a kitchen and different types of servers. And
you’ve seen how to transform things, while also responding to Reactive
Streams signals.
What’s missing is the fact that you haven’t seen how to actually start the
flow. What does "start the flow" mean? In Project Reactor, you can define all
the flows and all the handlers you need, but nothing actually happens until
you subscribe.
Subscription is key. This isn’t just part of Reactor, but instead a concept
baked into that tiny Reactor Streams spec mentioned earlier.
No data or activity materializes until someone asks for it. The following code
shows what happens when the restaurant asks the server to do his or her job.
Polite restaurant subscribing for activity
class PoliteRestaurant {
server.doingMyJob().subscribe( //
dish -> System.out.println("Consuming " + dish), //
throwable -> System.err.println(throwable));
}
}
The first line inside the main() method creates the kitchen and the server.
It’s a simple way to wire up the server.
It’s the next line where things get interesting. You call
server.doingMyJob() followed by subscribe. doingMyJob(), as
shown earlier, gives you a Flux<Dish>, but nothing happens (yet).
Remember, it’s just a placeholder for when things arrive.
In the KitchenService, it may be hard-wired with three dishes, but
nothing happens when you call doingMyJob()!
@
The phrase "when you subscribe" that is sprinkled throughout this book is shorthand for
"when you subscribe and start asking for results." Project Reactor is inherently lazy.
Nothing happens until someone subscribes and starts pulling. Connections aren’t opened,
web requests aren’t processed, and web filters aren’t activated until someone subscribes
and starts asking for data. In this case, the .subscribe() call includes a Java 8
Consumer which is the "code that pulls" in this scenario.
Looking a little closer, you can see that this usage of subscribe has a Java
8 Consumer as its first argument. This callback is invoked on every Dish
(during the Reactive Streams onNext() signal). In this case, it’s another
one of those lambda functions, dish →
System.out.println("Consuming " + dish). It prints to the
console. (Can you imagine instead serializing the object and writing it to an
HTTP response body?)
Want to run the code and see what you got? Do it!
Thank you for Dish{description='Sesame chicken',
delivered=false}!
Consuming Dish{description='Sesame chicken', delivered=true}
Thank you for Dish{description='Lo mein noodles, plain',
delivered=false}!
Consuming Dish{description='Lo mein noodles, plain',
delivered=true}
Thank you for Dish{description='Sweet & sour beef',
delivered=false}!
Consuming Dish{description='Sweet & sour beef', delivered=true}
Thanks for all your hard work!
Write it on a sticky on your monitor. Chisel it on a tablet and hang it on a wall. Nothing
happens until you subscribe. Reactive connections aren’t opened, reactive databases don’t
produce data, and reactive web services don’t write HTTP responses until you subscribe.
Now stop for a second. We’ve been talking about a server ferrying meals
from the kitchen to the customer. What if all those dining customers were
actually people visiting a web site. And the kitchen in the back was a mixture
of data stores and server-side services?
Your role as the server (taking orders from customers to the kitchen, followed
by delivering the requested items), would quite easily match up with…drum
roll…a web controller!
So where can you find a web controller that honors this Reactive Streams
approach?
And when it comes to building web applications, the most popular toolkit has
been Spring MVC.[3]
Spring Framework 5.0? I thought you were talking about Spring Boot 2.3. What gives?
Spring Framework is the core toolkit underlying Spring Boot. It has become arguably the
most popular toolkit in the Java community. And given that Spring Framework 5.0 has
embraced Reactive Streams through Project Reactor, much of what this book will cover
involves Spring Boot’s strong synergy with the Spring Framework.
In case you are somewhat familiar with the Spring Framework and had heard
of Spring MVC, you may be curious. What is the big difference between
Spring WebFlux and Spring MVC?
Spring MVC is built atop Java’s well-honed servlet API. There are many
assumptions in its underlying contracts. The biggest one being that the servlet
API is blocking. Sure, there is some asynchronous support since Servlet 3.1,
but it’s not completely reactive. It doesn’t come with support for fully
reactive event loops and backpressure signals.
And that is how you are going to developer e-commerce features throughout
this book—using Spring WebFlux along with other reactive parts of the
Spring portfolio.
“I have been reading your legends of the old days in the ‘North
American,’” said the delegate to the Grange Convention, stroking his
long silky mustache, “and they remind me of many stories that my
mother used to tell me when I was a little shaver, while we were
living on the Pucketa, in Westmoreland County. There was one story
that I used to like best of all. It was not the one about old Pucketa
the Indian warrior for whom the run was named, but about a less
notable Indian, but more esteemed locally, known as ‘Poplar George.’
“It isn’t nearly as interesting an Indian story as the one that
Emerson Collins tells, of the time when his mother, as a little girl on
the Quinneshockeny, went to the spring for a jug of water, finding a
lone Indian sitting there all by himself, looking as if he was in deep
thought. As he made no move to molest her, she filled her jug, and
then scampered back to the house as fast as she could tote the jug
there.
“She was a little shy about telling of her strange experience, but
finally, when she mentioned the subject, her mother said, ‘maybe
the poor fellow was hungry.’ Quickly spreading a ‘piece,’ she hurried
back to the spring, but no Indian was to be found, only a few prints
of his mocassined feet in the soft earth by the water course. If it
hadn’t been for those footprints she would have always felt that she
had not seen a real live Indian, but a ghost.
“It was the last Indian ever heard of on the Quinneshockeny, and
he had probably come back to revive old memories of his happy
childhood. No, Poplar George was hardly like Emerson Collins’ ‘last
Indian,’ as he, my mother averred, was part Indian, part ghost. He
was also the last Indian that ever visited the Pucketa, which had
been a famous stream in its day for redmen, from the time when old
Pucketa, himself, came there to spend his last days, after having
been driven out from his former hunting grounds at the head of Lost
Creek, which runs into the ‘Blue Juniata’ above Mifflintown.
“The principal part of this story revolves around two large trees
that used to stand near the Pucketa, one a big tulip or ‘whitewood’
tree, hollow at the butt, so much so that a half grown person could
hide in it, and a huge water poplar tree, or ‘cottonwood,’ a rare tree
in Pennsylvania, you know, that stood on lower ground directly in
line with it, but on the far side of the creek, which ran parallel with
the road. It wasn’t much of a road in those days, I’m told, isn’t much
of one yet, little better than a cow path, with grass and dandelions
growing between the wagon tracks, and worn foot-path on the creek
side of it. Many’s the time I’ve gone along that path to and from
school, or to fetch the cows.
AGED FLAX-SPINNER AT WORK,
SUGAR VALLEY
“In my boyhood there were two big stumps which always arrested
my attention, the stumps of the ‘cottonwood’ and the tulip which I
have already mentioned. The native poplar stump, which was
chopped breast high for some reason, had been cut before my day,
but the tulip tree had stood a dead stab for many years, and was not
finally cut until my babyhood. I was too young to recall it, and its
stump had been sawed off almost level with the ground.
“When my mother was old enough to notice things, say along six,
or seven or eight years of age, both trees was standing, and despite
their venerable age, were thrifty and green; the hollow trunk of the
tulip did not seem to lessen its vitality. Trees in those days, of all
kinds, were pretty common, and regarded as nuisances; the farmers
were still having ‘burning bees’ in the spring and fall when all hands
would join in and drag with ox-spans the logs of the trees that had
been cut when they were clearing new ground, and making huge
bonfires, burn them like a modern section foreman does a pile of old
railroad ties, and by the way, the time is going to come soon when
tie burners will be as severely condemned as the instigators of the
‘burning bees’ in the olden days.
“Trees were too plentiful to attract much attention or create
affection or veneration, but these two trees had a very special
human interest.
“Long after the Indians passed out of our country they came back
as ghosts or ‘familiars,’ just as the wolves, panthers and wild pigeons
do, so that the stories of folks seeing them after they became
extinct, while not literally true, are in a sense correct. Closely
associated with the life of the big cottonwood was an old Indian,
mother said; he wasn’t a real live Indian, yet not a ghost, was
probably a half ghost, half Indian, if there could be any such thing.
“The tulip tree was inhabited by a very attractive spirit, an Indian
girl, an odd looking one too, for her smooth skin was only a pumpkin
color and her eyes a light blue. They all called her ‘Pale Eyes,’ and
she was described as slight, winsome and wonderfully pretty. The
Indian man, because he spent so much time under the cottonwood
or water poplar, became generally known as ‘Poplar George.’ He
would appear in the neighborhood early in the spring, in time to
gather poke, milkweed, dandelion and bracken for the farmer’s
wives, and to teach the young folks to fish, to use the bow and
arrow, and snare wild pigeons and doves.
“It was a sure sign of spring when the young people would see
him squatting before a very small fire of twigs under the still leafless
branches of the ancient poplar tree. He would remain about all
summer long, helping with the harvest, so he must have been real
flesh and blood, in a sense, and in the fall he gathered nuts, and
later cut some cordwood for those who favored him–but in truth he
never liked hard, downright work overly much.
“He was a creature of the forests and streams. When he went
away in the fall, after the wild pigeons had left, he always said that
he wintered south, on the Casselman River, where the weather was
not so severe, in that wonderful realm of the Pawpaw, the
Persimmon and the Red Bud.
“Often when he took the young folks of the neighborhood on
fishing trips, and his skill with the angle and fly were unerring, the
pretty Indian maiden, ‘Pale Eyes,’ would turn up, and be with the
party all day. When asked who she was, he would sometimes say
that she was his daughter, other times his niece, or grand-daughter,
but when anyone asked of ‘Pale Eyes,’ she would shake her pretty
head, indicating that she only spoke the Indian language. Poplar
George could speak Dutch and a little English.
“No one knew where Poplar George slept, if it wasn’t in the open,
under the cottonwood tree. If he slept in barns, or under haystacks,
no one had ever seen him coming or going, but a detail like that,
mattered nothing as long as he was kindly and harmless, and took
good care of the children.
“He was a master of woodcraft, much like that old Narragansett
Indian ‘Nessmuk,’ who furnished the late George W. Sears with his
inspiration as well as ‘nom de plume.’ Poplar George could call the
wild birds off the trees, so that they would feed on the ground
before him, the squirrels and even the shy chipmunks climbed all
over him, and extracted nuts from his pockets.
"The old Indian was an odd person to look at, so my mother said;
of medium height, meagre, wrinkled and weazened, tobacco
colored, with little black shoe-button eyes, and a sparse mustache
and beard. He dressed in rags, and was often bare-footed, yet he
never complained of the cold. He was always jolly and cheerful, had
always been the same; he had been coming to the Pucketa Valley
for several generations before my mother’s day; in fact, no one could
remember when he hadn’t been there, but that wasn’t saying much,
as it was a new country, dating only from the time when Pucketa
and his tribesmen had enjoyed it as a hunting ground for big game.
"Once when some hunters killed a bear, they were going to nail
the paws on the end of a log barn, but Poplar George begged for
them, and invited the children to a feast of ‘bear paw cutlets’ under
the cottonwood tree. My mother sat beside ‘Pale Eyes,’ and took a
great fancy to her; she was able to talk with her in sign language,
and Poplar George, seeing how well they got on together,
occasionally interpreted for them.
"Mother managed to learn that ‘Pale Eyes’’ abode was in a huge
hollow tulip tree, but that she, too, wintered in the south, but
beyond the Maryland line. Those were all gloriously care-free, happy
days, and my mother, in later life, never tired talking about them.
"Once in the fall when the buckwheat harvest was in progress,
millions of wild pigeons came in, and mother could never forget the
sight of old Poplar George sitting on a ‘stake and rider’ fence, with a
handsome cock pigeon resplendent with its ruddy breast, pearched
on one of his wrists, while it pecked at some buckwheat seeds in his
other hand. Beside him sat the demure ‘Pale Eyes,’ a speckled squab
of the year in her lap, stroking it, while other pigeons, usually so
wild, were feeding in the stubble about them, or perched on the
stakes of the fence.
"Some of the boys of sixteen years or thereabouts, grown lads
they seemed to my mother, wanted to be attentive to ‘Pale Eyes,’ but
she was so shy that she never let them get close to her. As it was a
respectable backwoods community, and all minded their own
business, no further efforts were made to have her mingle in society.
"There was a rich boy, Herbert Hiltzheimer from Philadelphia,
whose father was a great land owner, and who sometimes came
with his parents to stay with their Agent while inspecting their
possessions, who, at first sight of ‘Pale Eyes,’ fell violently in love
with her. On rainy days he was not allowed out of doors, and sent
word to Poplar George that ‘Pale Eyes’ should go to the Agent’s
house, and play with him. Old Poplar George replied that he was
willing if his niece would consent, but she always ran away into the
depths of the forest, and was never once induced to play with him
indoors. She did not dislike the city boy, only was very timid, and
was afraid to go inside of a house.
"My mother was made a confidante of by Herbert,who offered her
five dollars, a collosal sum in those days, if she would induce ‘Pale
Eyes’ to at least come into the Agent’s yard, and play with him
alone. He had her name cut on everything, even on the window
frames, and wrote verses about her which he carried in his pocket,
and sometimes tried to read to her.
"In the fall he was taken back to Philadelphia to school, but said
that, the evening before, when he walked up the lane, weeping over
his misfortune, he opportunately met the fair Indian maid alone at
the tulip tree, and actually kissed her. She broke away and ran into
the hollow trunk, and while he quickly followed her into the
aperture, she had disappeared.
"The lands on which the cottonwood and the tulip tree stood were
a part of a farm belonging to ’Squire George Garnice, an agreeable,
but easy going old gentleman, who never learned to say ‘no’ to any
one, though not much to his detriment for he was very generally
respected.
"One fall some of the Fiedler boys suggested to him, that he let
them go on his property and cut up a lot of old half-dead good-for-
nothing trees for cordwood and of course he assented. The first tree
they attacked was Poplar George’s favorite, the mighty cottonwood.
They were skilled axemen, and cut a level stump but too high for
these days of conservation. Soon the big poplar was down, and the
boys were trimming off the sweeping branches. Before cutting into
stove lengths, they hopped across the creek and started on their
next victim, the hollow tulip tree, the home of ‘Pale Eyes.’
"One of the boys, the youngest, Ed, had gotten a new cross-cut
saw, and begged them to try it on the tulip. They notched, and then
getting down on their knees, started to saw a low stump, for some
reason or other. They had sawed in quite a distance on both edges
of the hollow side when they heard a piteous shrieking and wailing
down the road, toward the old ’Squire’s barn.
"Leaving saw, axes and wedges, they ran to where the cries came
from, and to their horror, found ‘Pale Eyes’ lying on the grassy bank
beside the road at the orchard, her ankles terribly lacerated, front
and back, clear in to the bones, and bleeding profusely. On this
occasion she was able to speak in an intelligible tongue.
“‘Run quick to the ’Squire’s, and get help,’ she said, in
Pennsylvania German; ‘I am dying, but I want something to ease
this dreadful pain.’
“The sympathetic boys, without waiting to inquire where she
received her grevious hurts, scurried down the road and through the
’Squire’s gate. The old gentleman was in his library, drawing up a
legal document, when the long, lanky youths, hatless and
breathless, burst in on him.
“‘Oh, sir,’ they chorused, ‘the Indian girl, ‘Pale Eyes,’ you know, has
cut herself, and is dying up the road, and wants help.’
"The ’Squire always kept an old-fashioned remedy chest in his
desk, so seizing it, and adjusting his curly wig, so that it would not
blow off, he ran out after the nimble mountaineers. As they left the
gate they saw old Poplar George running across the orchard in the
direction of the wounded girl. Evidently he, too, had heard her cries.
"When they reached the spot where marks on the greensward
showed where ‘Pale Eyes’ had been lying, she was nowhere to be
found, neither was Poplar George. There were no signs of blood,
only a lot of sawdust like comes from the workings of a cross-cut
saw.
"The old ’Squire was nonplussed, but consented to accompany the
boys to the scene of their wood cutting operations. ‘Pale Eyes’ was
not there either, nor Poplar George. The newly formed leaves of the
cottonwood–it was in the month of May–although the tree had only
been cut and sawed into but an hour before, were scorched and
withered.
"The ’Squire showed by his face how heartbroken he was to see
the two picturesque trees so roughly treated, but he was too kindly
and forgiving to chide the boys for their sake. As he was standing
there, looking at the ruin, a number of school children, among them
my mother, came along, for it was during the noon recess, or dinner
hour. They saw the butchered trees, and learned of the events of the
morning; several of them, prosaic backwoods youngsters, though
they were, shed bitter tears.
“‘Dry your eyes,’ the ‘’Squire urged them, ‘else your people will
think that the teacher licked you.’ Then they all chorused that it was
a shame to have ruined the retreats of Poplar George and ‘Pale
Eyes.’
“Evidently ’Squire Garnice was wise in the lore of mysticism, for he
shook his head sadly, saying, ‘Never mind, you’ll never see Poplar
George nor ‘Pale Eyes’ again.’
“It was a dejected company that parted with him at his gate. The
old ’Squire was right, for never more was anything seen or heard of
Poplar George and the mysterious ‘Pale Eyes.’ They must have been
in some unknowable way connected with the lives of those two
trees, the cottonwood and the tulip–their lives or spirits maybe, and
when they were cut into, their spirits went out with them.
“I knew of a wealthy man who had a cedar tree in his yard, that
when he fell ill, the tree became brown, but retained a little life.
Finally it was cut down as an eyesore, and the gentleman died
suddenly a few days afterward. That tree must have contained a
vital part of his spirit.
“By fall the tulip tree looked as if it had been dead for years, and
the bark was peeling off. As the wood of the poplar would not burn,
and set up a fetid odor, the Fieldler boys never bothered to finish
cutting down the hollow tulip tree, of which the shy wood sprite,
‘Pale Eyes,’ had been the essence.
"Much of the mystery and charm of that old grass-grown way
along the gently flowing Pucketa had vanished with its Indian
frequenters. But the memory of Poplar George and ‘Pale Eyes’ will
never be forgotten as long as any of those children who were lucky
enough to know them, remain in this world."
XIV
Black Alice Dunbar
ebookmasss.com