100% found this document useful (1 vote)
38 views

Practical Spring LDAP: Using Enterprise Java-Based LDAP in Spring Data and Spring Framework 6 2nd Edition Balaji Varanasi - Download the complete ebook in PDF format and read freely

Practical Spring LDAP is a comprehensive guide for developers looking to utilize LDAP in Java applications using the Spring framework. It covers fundamental concepts of LDAP, practical implementation techniques, and testing strategies, along with advanced topics like Object-Directory Mapping and LDAP transactions. The book is aimed at developers with a basic understanding of Spring Framework, providing best practices and examples to enhance their LDAP programming skills.

Uploaded by

turuvarostya
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 (1 vote)
38 views

Practical Spring LDAP: Using Enterprise Java-Based LDAP in Spring Data and Spring Framework 6 2nd Edition Balaji Varanasi - Download the complete ebook in PDF format and read freely

Practical Spring LDAP is a comprehensive guide for developers looking to utilize LDAP in Java applications using the Spring framework. It covers fundamental concepts of LDAP, practical implementation techniques, and testing strategies, along with advanced topics like Object-Directory Mapping and LDAP transactions. The book is aimed at developers with a basic understanding of Spring Framework, providing best practices and examples to enhance their LDAP programming skills.

Uploaded by

turuvarostya
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/ 77

Read Anytime Anywhere Easy Ebook Downloads at ebookmeta.

com

Practical Spring LDAP: Using Enterprise Java-Based


LDAP in Spring Data and Spring Framework 6 2nd
Edition Balaji Varanasi

https://ebookmeta.com/product/practical-spring-ldap-using-
enterprise-java-based-ldap-in-spring-data-and-spring-
framework-6-2nd-edition-balaji-varanasi/

OR CLICK HERE

DOWLOAD EBOOK

Visit and Get More Ebook Downloads Instantly at https://ebookmeta.com


Recommended digital products (PDF, EPUB, MOBI) that
you can download immediately if you are interested.

Spring REST: Building Java Microservices and Cloud


Applications Balaji Varanasi

https://ebookmeta.com/product/spring-rest-building-java-microservices-
and-cloud-applications-balaji-varanasi/

ebookmeta.com

Pro Spring Security: Securing Spring Framework 6 and Boot


3–based Java Applications, Third Edition Massimo Nardone

https://ebookmeta.com/product/pro-spring-security-securing-spring-
framework-6-and-boot-3-based-java-applications-third-edition-massimo-
nardone/
ebookmeta.com

Beginning Spring Data: Data Access and Persistence for


Spring Framework 6 and Boot 3 1st Edition Andres Sacco

https://ebookmeta.com/product/beginning-spring-data-data-access-and-
persistence-for-spring-framework-6-and-boot-3-1st-edition-andres-
sacco/
ebookmeta.com

Beauty in Chaos 1st Edition Nacole Stayton

https://ebookmeta.com/product/beauty-in-chaos-1st-edition-nacole-
stayton/

ebookmeta.com
The Aliens Are Coming 1st Edition Ben Miller

https://ebookmeta.com/product/the-aliens-are-coming-1st-edition-ben-
miller-2/

ebookmeta.com

Vegan Junk Food 200 Vegan Recipes for the Foods You Crave
Minus the Ingredients You Don t Lane Gold

https://ebookmeta.com/product/vegan-junk-food-200-vegan-recipes-for-
the-foods-you-crave-minus-the-ingredients-you-don-t-lane-gold/

ebookmeta.com

Real-Time Twilio and Flybase. Build Real-Time Web Apps


Using Twilio and Flybase with Node.js 1st Edition Roger
Stringer
https://ebookmeta.com/product/real-time-twilio-and-flybase-build-real-
time-web-apps-using-twilio-and-flybase-with-node-js-1st-edition-roger-
stringer/
ebookmeta.com

Worlds Worst Conspiracies The Truth is they dont want you


to know 1st Edition Mike Rothschild

https://ebookmeta.com/product/worlds-worst-conspiracies-the-truth-is-
they-dont-want-you-to-know-1st-edition-mike-rothschild/

ebookmeta.com

America Unbound Encyclopedic Literature and Hemispheric


Studies 1st Edition Antonio Barrenechea

https://ebookmeta.com/product/america-unbound-encyclopedic-literature-
and-hemispheric-studies-1st-edition-antonio-barrenechea/

ebookmeta.com
Let s Taco Bout Love Man of the Month May a fake
relationship curvy girl romance 1st Edition Kat Baxter

https://ebookmeta.com/product/let-s-taco-bout-love-man-of-the-month-
may-a-fake-relationship-curvy-girl-romance-1st-edition-kat-baxter/

ebookmeta.com
Balaji Varanasi and Andres Sacco

Practical Spring LDAP


Using Enterprise Java-Based LDAP in Spring Data
and Spring Framework 6
2nd ed.
Balaji Varanasi
Salt Lake City, UT, USA

Andres Sacco
Buenos Aires, Buenos Aires, Argentina

ISBN 979-8-8688-0001-6 e-ISBN 979-8-8688-0002-3


https://doi.org/10.1007/979-8-8688-0002-3

© Balaji Varanasi and Andres Sacco 2013, 2023

This work is subject to copyright. All rights are solely and exclusively
licensed 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.

The use of general descriptive names, registered names, trademarks,


service marks, etc. in this publication does not imply, even in the
absence of a specific statement, that such names are exempt from the
relevant protective laws and regulations and therefore free for general
use.

The publisher, the authors, and the editors are safe to assume that the
advice and information in this book are believed to be true and accurate
at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the
material contained herein or for any errors or omissions that may have
been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
This Apress imprint is published by the registered company APress
Media, LLC, part of Springer Nature.
The registered company address is: 1 New York Plaza, New York, NY
10004, U.S.A.
To my grandparents who taught me the importance of learning new
things all the time.
To my wife and children for supporting me while writing this book.
Introduction
Practical Spring LDAP provides complete coverage of Spring LDAP, a
framework designed to take the pain out of LDAP programming. This
book starts by explaining the fundamental concepts of LDAP and
showing the reader how to set up the development environment. It
then dives into Spring LDAP, analyzing the problems it is designed to
solve. After that, the book focuses on the practical aspects of unit
testing and integration testing with LDAP. An in-depth treatment of
LDAP controls and Spring LDAP features, such as Object-Directory
Mapping and LDIF (LDAP Data Interchange Format) parsing, follows
this. Finally, it concludes with discussions on LDAP authentication and
connection pooling.
What the Book Covers
Chapter 1 starts with an overview of directory servers. It then discusses
the basics of LDAP and introduces the four LDAP information models. It
finishes with an introduction to the LDIF format used for representing
LDAP data.
Chapter 2 focuses on the Java Naming and Directory Interface
(JNDI). In this chapter, you look at creating applications that interact
with LDAP using plain JNDI.
Chapter 3 explains Spring LDAP and why it is an important option in
an enterprise developer’s repertoire. In this chapter, you set up the
development environment to create Spring LDAP applications and
other important tools, such as Maven and a test LDAP server. Finally,
you implement a basic but complete Spring LDAP application using
annotations.
Chapter 4 covers the fundamentals of unit and integration testing.
You then look at setting up an embedded LDAP server for unit testing
your application code; alternatively, you will see how to use
Testcontainers to run LDAP using a docker image. You also review
available tools for generating test data. Finally, you use the Mockito
library to mock test LDAP code.
Chapter 5 introduces the basics of JNDI object factories and uses
these factories for creating objects that are more meaningful to the
application. You then examine a complete Data Access Object (DAO)
layer implementation using Spring LDAP and object factories.
Chapter 6 covers LDAP search. This chapter begins with the
underlying ideas of LDAP search. I then introduce various Spring LDAP
filters that make LDAP searching easier. Finally, you look at creating a
custom search filter to address situations where the current set is
insufficient.
Chapter 7 provides an in-depth overview of LDAP controls that can
be used for extending LDAP server functionality. Then it moves on to
sorting and paging LDAP results using sort and page controls.
Chapter 8 deals with Object-Directory Mapping (ODM), a feature in
Spring LDAP. In this chapter, you look at bridging the gap between the
domain model and the directory server. You then re-implement the DAO
using ODM concepts.
Chapter 9 introduces the important ideas of transactions and
transactional integrity before analyzing the transaction abstractions
provided by Spring Framework. Finally, it takes a look at Spring LDAP’s
compensating transaction support.
Chapter 10 starts with implementing authentication, the most
common operation against LDAP. It then deals with parsing LDIF files
using another feature introduced in Spring. I end the chapter by looking
at the connection pooling support provided by Spring LDAP.

Target Audience
Practical Spring LDAP is intended for developers interested in building
Java/JEE applications using LDAP. It also teaches techniques for
creating unit/integration tests for LDAP applications. The book
assumes basic familiarity with Spring Framework; prior exposure to
LDAP is helpful but optional. Developers already familiar with Spring
LDAP will find best practices and examples to help them get the most
out of the framework.

Prerequisites
You should install Java JDK1 21 or higher on your machine, Maven2 3.8.0
or higher, and some IDE. Some options for the IDE could be Eclipse,3
IntelliJ IDEA,4 Visual Studio Code,5 and others, but you can choose
which is the best for you.
To reduce the complexity of installing all LDAP vendors on your
machine, I recommend you install Docker6 and use it to run each LDAP.
The use and installation of Docker are outside the scope of this book,
but there are some tutorials7 or cheatsheet8 with the most common
commands.

Note If you don’t have it installed on your machine, you can check
Appendixes A, B, and C, which have information about installing the
different tools and loading the information on LDAP.
After installing all the tools, you must check if they are correctly
installed before reading the different chapters.
In the case of Java, you need to run the following command:

% java -version
openjdk 21 2023-09-19
OpenJDK Runtime Environment (build 21+35-2513)
OpenJDK 64-Bit Server VM (build 21+35-2513, mixed
mode, sharing)

After that, you need to check if the version of Maven is correct using
this command:

% mvn --version
Apache Maven 3.9.1
Maven home: /usr/share/maven

Last, if you want to check whether Docker runs correctly on your


machine, you can do that using the following command:

% docker --version
Docker version 24.0.2, build cb74dfc

Remember that I mentioned that Docker is optional. It’s only


recommended for reducing the complexity of installing LDAP vendors
on your machine.

Downloading Source Code


The source code for the examples in this book can be downloaded from
www.apress.com. For detailed information about locating this book’s
source code, visit www.apress.com/gp/services/source-
code. The code is organized by chapter and can be built using Maven.

Questions?
If you have any questions or suggestions, contact the author at
sacco.andres@gmail.com.
Any source code or other supplementary material referenced by the
author in this book is available to readers on GitHub
(https://github.com/Apress). For more detailed information, please
visit https://www.apress.com/gp/services/source-code.
Acknowledgments
I would like to thank my family members and friends for their
encouragement and support during the writing of this book:
My wife, Gisela, who was always patient when I spent long hours at
my computer desk working on this book
My little daughter, Francesca, who helped me relax while writing
each chapter
My baby, Allegra, who is the new family member and my inspiration
to write this book
My friends, German Canale and Julian Delley, who always trusted me
to write a book and supported me during tough times
Specially mentioning Manuel Jordan for guiding me in improving
the quality of the book.
My sincere thanks to the beautiful team at Apress for their support
during the publication of this book. Thanks to Shonmirin P.A. for
providing excellent support. Finally, thanks to Mark Powers and Melissa
Duffy for suggesting and allowing me to write a book. Also, I want to
mention the great job that Balaji Varanasi did with the first edition of
this book which gave the base to write the second edition.
Table of Contents
Chapter 1:​Introduction to LDAP
LDAP Overview
Directory vs.​Database
Information Model
Object Classes
Directory Schema
Naming Model
Functional Model
Security Model
LDIF Format
LDAP History
LDAP Vendors
Sample Application
Summary
Chapter 2:​Java Support for LDAP
LDAP Using JNDI
Connect to LDAP
LDAP Operations
Closing Resources
Creating a New Entry
Updating an Entry
Removing an Entry
Searching Entries
Check How the Operations Work
JNDI Drawbacks
Summary
Chapter 3:​Introducing Spring LDAP
Motivation
Documentation and Source Code Spring LDAP
Spring LDAP Packaging
Installing Spring LDAP Using Maven
Spring LDAP Archetypes
Creating Projects Using IntelliJ
Spring LDAP Hello World
Spring ApplicationConte​xt
Spring-Powered Search Client
Spring LdapTemplate Operations
Add Operation
Modify Operation
Deleting Operation
Summary
Chapter 4:​Testing LDAP Code
Concepts About Testing
Unit Testing
Mock Testing
Integration Testing
Libraries to Do Tests
JUnit
Mockito
Testcontainers
Creating the Tests
Mocking the Templates
Testing Using Embedded Server
Moving to Tests with Testcontainers
Summary
Chapter 5:​Advanced Spring LDAP
JNDI Object Factories
Spring and Object Factories
DAO Implementation Using Object Factory
Implementing Finder Methods
Create Method
Update Method
Delete Method
Summary
Chapter 6:​Searching LDAP
LDAP Search Criteria
Base Parameter
Scope Parameter
Filter Parameter
Optional Parameters
LDAP Injection
Spring LDAP Filters
EqualsFilter
LikeFilter
PresentFilter
NotPresentFilter​
Not Filter
GreaterThanOrEqu​alsFilter
LessThanOrEquals​Filter
AndFilter
OrFilter
HardcodedFilter
WhitespaceWildca​rdsFilter
Handling Special Characters
LDAP Query Builder Parameters
Summary
Chapter 7:​Sorting and Paging Results
LDAP Controls
Identifying Supported Controls
JNDI and Controls
Spring LDAP and Controls
Sort Control
Implementing Custom DirContextProces​sor
Paged Search Controls
Summary
Chapter 8:​Object-Directory Mapping
Spring ODM Basics
ODM Metadata
ODM Service Class
Creating Custom Converter
Summary
Chapter 9:​LDAP Transactions
Transaction Basics
Local vs.​Global Transactions
Programmatic vs.​Declarative Transactions
Programmatically​
Declaratively
Spring Transaction Abstraction
Declarative Transactions Using Spring
LDAP Transaction Support
Spring LDAP Transaction Support
Compensating Transactions
Summary
Chapter 10:​Odds and Ends
Authentication Using Spring LDAP
Handling Authentication Exceptions
Parsing LDIF Data
LDAP Connection Pooling
Built-In Connection Pooling
Spring LDAP Connection Pooling
Pool Validation
Summary
Appendix A:​Setting Up Environment Tools
Appendix B:​Recommended and Alternative Tools
Appendix C:​Set Up LDAP Server
Appendix D:​Opening a Project
Appendix E:​Further Reading
Index
About the Authors
Balaji Varanasi
is a software development manager and technology entrepreneur. He
has over 13 years of experience architecting and developing Java/.NET
applications and, more recently, iPhone apps. During this period, he has
worked in the areas of security, web accessibility, search, and
enterprise portals. He has a master’s degree in computer science and
serves as adjunct faculty, teaching programming and information
system courses. When not programming, he enjoys spending time with
his lovely wife in Salt Lake City, Utah.

Andres Sacco
has been working as a developer since
2007 in different languages, including
Java, PHP, Node.js, Scala, and Kotlin. His
background is mostly in Java and the
libraries or frameworks associated with
this language. At most of the companies
he worked for, he researched new
technologies to improve the
performance, stability, and quality of the
applications of each company. In 2017,
he started to find new ways to optimize
the transference of data between
applications to reduce the cost of
infrastructure. He suggested some
actions, some applicable in all of the manual microservices and others
in just a few. All of this work includes creating a series of theoretic-
practical projects (available on Manning.com). Recently, he coauthored
an Apress book titled Beginning Scala 3. He also published a set of
theoretic-practical projects about uncommon ways of testing, such as
architecture tests and chaos engineering.
About the Technical Reviewer
Manuel Jordan
is an autodidactic developer and researcher who enjoys learning new
technologies for his own experiments about creating new integrations
among them.
Manuel won the 2010 Springy Award – Community Champion and
Spring Champion 2013. In his little free time, he reads the Bible and
composes music on his bass and guitar.
You can reach him through his Twitter account, @dr_pompeii.
© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023
B. Varanasi, A. Sacco, Practical Spring LDAP
https://doi.org/10.1007/979-8-8688-0002-3_1

1. Introduction to LDAP
Balaji Varanasi1 and Andres Sacco2
(1) Salt Lake City, UT, USA
(2) Buenos Aires, Buenos Aires, Argentina

We all deal with directories daily. We use a telephone directory to look up phone numbers. When visiting a
library, we use the library catalog to look up the books we want to read. We use the file system directory
with computers to store our files and documents. Simply put, a directory is a repository of information. The
information is usually organized so that it can be retrieved easily.
Directories on a network are typically accessed using the client/server communication model.
Applications wanting to read or write data to a directory communicate with specialized servers. The
directory server performs a read or write operation on the actual directory. Figure 1-1 shows this
client/server interaction.

Figure 1-1 Directory server and client interaction

The communication between the directory server and client applications is usually accomplished using
standardized protocols. The Lightweight Directory Access Protocol (LDAP) provides a standard protocol for
communicating with a directory. The directory servers that implement the LDAP protocol are usually called
LDAP servers. The LDAP protocol is based on an earlier X.5001 standard but is significantly simpler
(lightweight) and easily extensible. Over the years, the LDAP protocol went through iterations and is
currently at version 3.0.

LDAP Overview
LDAP defines a message protocol used by directory clients and directory servers. LDAP can be better
understood by considering the following four models it is based on:
The Information model determines the structure of information stored in the directory.
The Naming model defines how information is organized and identified in the directory.
The Functional model defines the operations performed on the directory.
The Security model defines how to protect information from unauthorized access.
We will look at each of these models in the following sections.

Directory vs. Database


Beginners often need clarification and picture an LDAP directory as a relational database. Like a database,
an LDAP directory stores information. However, several key characteristics set a directory apart from
relational databases.
LDAP directories typically store data that is relatively static. For example, employee information stored
in LDAP, such as their phone number or name, does not change daily. However, users and applications look
up this information very frequently. Since the data in a directory is accessed more often than updated, LDAP
directories follow the WORM principle2, 3 and are heavily optimized for read performance. Placing data that
change quite often in LDAP does not make sense.
Relational databases employ referential integrity and locking techniques to ensure data consistency. The
type of data stored in LDAP usually does not warrant such strict consistency requirements. Hence, most of
these features need to be present on LDAP servers. Also, transactional semantics to roll back transactions
are not defined under LDAP specification.
Relational databases follow normalization principles to avoid data duplication and redundancy. On the
other hand, LDAP directories are organized in a hierarchical, object-oriented way. This organization violates
some of the normalization principles. Also, there needs to be a concept of table joins in LDAP.
Even though directories lack several of the RDBMS4 features mentioned earlier, many modern LDAP
directories are built on top of relational databases such as DB2,5 MySQL,6 and PostgreSQL.7
At some point, LDAP has similar characteristics to nonrelational databases like Cassandra,8 MongoDB,9
and many others where the performance of the write/read, high availability, and scalability are more
relevant than the consistency.

Information Model
The basic unit of information stored in LDAP is an entry. Entries hold information about real-world objects
such as employees, servers, printers, and organizations. Each entry in an LDAP directory comprises zero or
more attributes. Attributes are key-value pairs that hold information about the object the entry represents.
The key portion of an attribute is also called the attribute type and describes the information that can be
stored in the attribute. The value portion of the attribute contains the actual information. Table 1-1 shows a
portion of an entry representing an employee. The left column in the entry contains the attribute types, and
the right column holds the attribute values.

Table 1-1 Employee LDAP Entry

Employee Entry
objectClass inetOrgPerson

givenName John
surname Smith
mail john@inflix.com
jsmith@inflix.com
mobile +1 801 100 1000

Note Attribute names, by default, are case-insensitive. However, it is recommended to use camel case
format in LDAP operations.

You will notice that the mail attribute has two values. Attributes that are allowed to hold multiple values are
called multivalued attributes. Single-valued attributes, on the other hand, can only hold a single value. The
LDAP specification does not guarantee the order of the values in a multivalued attribute.
Each attribute type is associated with a syntax that dictates the format of the data stored as an attribute
value. For example, the mobile attribute type has a telephoneNumber syntax. This forces the attribute to
hold a string value with a length between 1 and 32.
Additionally, the syntax also defines the attribute value behavior during search operations. For example,
the givenName attribute has the syntax DirectoryString. This syntax enforces that only alphanumeric
characters are allowed as values. Table 1-2 lists some common attributes and their associated syntax
description.
Table 1-2 Common Entry Attributes

Attribute Type Syntax Description


commonName DirectoryString Stores the common name of a person.
company DirectoryString Stores the company’s name.
employeeNumber DirectoryString Stores the employee’s identification number in the organization.
givenName DirectoryString Stores the user’s first name.
jpegPhoto Binary Stores one or more images of the person.
mail IA5 String Stores a person’s SMTP mail address.
mobile TelephoneNumber Stores a person’s mobile number.
postalAddress Postal Address Stores the user’s ZIP or postal code.
postalCode DirectoryString Stores the user’s ZIP or postal code.
st DirectoryString Stores the state or province name.
street DirectoryString Stores the street address.
surname DirectoryString Stores the last name of the person.
telephoneNumber TelephoneNumber Stores the person’s primary telephone number.

uid DirectoryString Stores the user id.


title DirectoryString Stores the name of the position or the company’s function.
wwwhomepage DirectoryString Stores the official web page of the company.
The attributes in Table 1-2 are the most used for the developers and tools. Still, there is a big list of other
attributes depending on whether your vendor or the tool supports it or not; for example, on the official web
page10 of Microsoft, all the attributes are supported for the Active Directory.

Object Classes
In object-oriented languages, such as Java, we create a class and use it as a blueprint for creating objects. The
class defines the attributes/data (and behavior/methods) that these instances can have. Similarly, object
classes in LDAP determine the attributes an LDAP entry can have. These object classes also define which
attributes are mandatory and which are optional. Every LDAP entry has a special attribute aptly named
objectClass that holds the object class it belongs to. Looking at the objectClass value in the employee
entry in Table 1-1, we can conclude that the entry belongs to the inetOrgPerson class. Table 1-3 shows
the required and optional attributes in a standard LDAP person object class. The cn attribute holds the
person’s common name, whereas the sn attribute holds the person’s family name or surname.

Table 1-3 Person Object Class

Required Attributes Optional Attributes


sn description

telephoneNumber

cn userPassword
objectClass seeAlso

As in Java, an object class can extend other object classes. This inheritance will allow the child object
class to inherit parent class attributes. For example, the person object class defines attributes such as
common name and surname. The object class inetOrgPerson extends the person class and thus inherits
all the person’s attributes.
Additionally, inetOrgPerson defines attributes required for a person working in an organization, such
as departmentNumber and employeeNumber. One special object class, namely, top, does not have any
parents. All other object classes are decedents of top and inherit all the attributes declared in it. The top
object class includes the mandatory objectClass attribute. Figure 1-2 shows the object inheritance.
Figure 1-2 LDAP object inheritance
Most LDAP implementations come with standard object classes that can be used out of the box. Table 1-4
lists some of these LDAP object classes and their commonly used attributes.
Table 1-4 Common LDAP Object Classes

Object Class Attributes Description


top objectClass Defines the root object class. All other object classes must
extend this class.
organization o Represents a company or an organization.
The o attribute typically holds the name of the organization.
organizationalUnit ou Represents a department or similar entity inside an
organization.
person sn Represents a person in the directory and requires the sn
cn (surname) and cn (common name) attributes.
telephoneNumber
userPassword

organizationalPerson registeredAddress Subclasses that represent a person in an organization.


postalAddress postalCode
inetOrgPerson uid departmentNumber It provides additional attributes and can be used to represent a
employeeNumber givenName person working in today’s Internet- and intranet-based
manager organization. The uid attribute holds the person’s username or
user id.

On Oracle’s official website,11 you can find the list of LDAP object classes with information about the
Request for Comments (RFC), which added each object class.

Note In this book, you will see many references to RFCs. Request for Comments (RFC) is a series of
technical documents produced by the Internet Engineering Task Force (IETF)12 that specify certain
standards.
Each RFC has a number as part of the name and a series of sections with the specification. An RFC
could become obsolete to many other RFCs because a new specification about certain technology
appears, for example, a new version of LDAP.
On the RFC Editor web page,13 you can find information about RFCs and the publication process of the
new one.

Directory Schema
The LDAP directory schema is a set of rules determining the type of information stored in a directory.
Schemas can be considered packaging units and contain attribute type definitions and object class
definitions. The schema rules are verified before an entry can be stored in LDAP. This schema checking
ensures that the entry has all the required attributes and contains no attributes not part of the schema.
Figure 1-3 represents a generic LDAP schema.
Figure 1-3 LDAP generic schema
Like databases, directory schemas must be well designed to address issues like data redundancy. Before
implementing your schema, it is worth looking at publicly available standard schemas. These standard
schemas often contain all definitions to store the required data and, more importantly, ensure
interoperability across other directories.

Naming Model
The LDAP Naming model defines how entries are organized in a directory. It also determines how a
particular entry can be uniquely identified. The Naming model recommends that entries be stored logically
in a hierarchical fashion. This entry tree is often called a directory information tree (DIT). Figure 1-4
provides an example of a generic directory tree.

Figure 1-4 Generic DIT

The tree’s root is usually referred to as the base or suffix of the directory. This entry represents the
organization that owns the directory. The format of suffixes can vary from implementation to
implementation, but generally, there are three recommended approaches, as listed in Figure 1-5.

Figure 1-5 Directory suffix naming conventions

Note DC stands for domain component.

The first recommended technique is to use the organization’s domain name as the suffix. For example, if the
organization’s domain name is example.com, the directory suffix will be o=example.com. The second
technique also uses the domain name, but each name component is prepended with “dc=” and joined by
commas. So the domain name example.com would result in a suffix dc=example, dc=com. This technique
is proposed in RFC 224714 and is popular with Microsoft Active Directory. The third technique uses the
X.500 model and creates a suffix in the format o=organization name, c=country code. In the United States,
the suffix for the organization example would be o=example, c=us.
The naming model also defines naming and uniquely identifying entries in a directory. Entries with a
common immediate parent are uniquely identified via their relative distinguished name (RDN), also called
distinguished name (DN). The RDN is computed using one or more attribute/value pairs of the entry. In its
simplest case, RDN is usually of the form attribute-name = attribute value. Figure 1-6 provides a simplified
representation of an organization directory. Each person entry under ou=employees has a unique uid. So the
RDN for the first person entry would be uid=emp1, where emp1 is the employee’s user id.

Figure 1-6 Example of an organization directory

Note The distinguished name is not an actual attribute in the entry. It is a logical name associated with
the entry.

It is important to remember that RDN cannot be used to uniquely identify the entry in the entire tree.
However, this can be easily done by combining the RDNs of all the entries in the path from the top of the tree
to the entry. The result of this combination is referred to as distinguished name (DN). In Figure 1-6, the DN
for person 1 would be uid=emp1, ou=employees, dc=example, dc=com. Since the DN is made by combining
RDNs, if an entry’s RDN changes, the DNs of that entry and all its child entries also change.
There can be situations where a set of entries does not have a unique attribute. In those scenarios, one
option is to combine multiple attributes to create uniqueness. For example, we can use the consumer’s
common name and email address in the previous directory as an RDN. Multivalued RDNs are represented by
separating each attribute pair with a +, like so:

cn = Balaji Varanasi + mail=balaji@inflinx.com

Some special characters on the RDN must be escaped to prevent different problems. The special
characters are + (plus), = (equals), < (less than), > (greater than), ; (semicolon), , (comma), \ (backslash), #
(number sign), and ”.
There are different approaches to escape the characters, like adding the backslash (“\” ASCII 92) before
the special character; this approach is the most commonly used. The other replaces the special characters
with a backslash and hexadecimal digit, and the last one surrounds the attribute’s value with quotation
marks (“”).

Note Multivalued RDNs are usually discouraged. Creating a unique sequence attribute is recommended
in those scenarios to ensure uniqueness.

Functional Model
The LDAP Functional model describes the access and modification operations that can be performed on the
directory using the LDAP protocol. These operations fall into three categories: query, update, and
authentication.
The query operations are used to search and retrieve information from a directory. So whenever some
information needs to be read, a search query must be constructed and executed against LDAP. The search
operation takes a starting point within DIT, the search depth, and the attributes an entry must have for a
match. In Chapter 6, you’ll delve deep into searching and look at all the available options.
The update operations add, modify, delete, and rename directory entries. As the name suggests, the add
operation adds a new entry to the directory. This operation requires the DN of the entry to be created and a
set of attributes that constitute the entry. The delete operation takes a fully qualified DN of the entry and
deletes it from the directory. The LDAP protocol allows only the leaf entries to be deleted. The modified
operation updates an existing entry. This operation takes the entry’s DN and a set of modifications, such as
adding a new attribute, updating a new one, or removing an existing one. The rename operation can rename
or move entries in a directory.
The authentication operations are used for connecting and ending sessions between the client and the
LDAP server. A bind operation initiates an LDAP session between the client and server. Typically, this would
result in an anonymous session. The client can provide a DN and credentials to authenticate and create an
authenticated session. On the other hand, the unbind operation can be used to terminate an existing session
and disconnect from the server.
LDAP V3 introduced a framework for extending existing operations and adding new ones without
changing the protocol. You will take a look at these operations in Chapter 7.

Security Model
The LDAP Security model protects LDAP directory information from unauthorized access. The model
specifies which clients can access which parts of the directory and what kinds of operations (search vs.
update) are allowed.
The LDAP Security model is based on the client authenticating to the server. As discussed earlier, this
authentication process or bind operation involves the client supplying a DN identifying itself and a
password. An anonymous session is established if the client does not provide a DN and password. RFC
282915 defines a set of authentication methods that LDAP V3 servers must support. After successful
authentication, the access control models are consulted to determine whether the client has sufficient
privileges to do what is requested. Unfortunately, no standards exist for access control models, and each
vendor provides their implementations.

LDIF Format
The LDAP Data Interchange Format (LDIF) is a standard text-based format for representing directory
content and update requests. The LDIF format is defined in RFC 2849.16 LDIF files are typically used to
export data from one directory server and import it into another. It is also popular for archiving directory
data and applying bulk updates to a directory. You will use LDIF files to store your test data and refresh the
directory server between unit tests.
The basic format of an entry represented in LDIF is as follows:

#comment
dn: <distinguished name>
objectClass: <object class>
objectClass: <object class>
...
...
<attribute type>: <attribute value>
<attribute type>: <attribute value>
...

Lines in the LDIF file starting with a # character are considered comments. The dn and at least one
objectClass entry definition are considered required. Attributes are represented as name/value pairs
separated by a colon. Multiple attribute values are specified in separate lines and will have the same
attribute type. Since LDIF files are purely text based, binary data needs to be Base64 encoded before it is
stored as part of the LDIF file.
Blank lines separate multiple entries in the same LDIF file. Listing 1-1 shows an LDIF file with three
employee entries. Notice that the cn attribute is multivalued and is represented twice for each employee.

# Barbara’s Entry
dn: cn=Barbara J Jensen, dc=example, dc=com
# multi valued attribute
cn: Barbara J Jensen
cn: Babs Jensen
objectClass: personsn: Jensen
# Bjorn’s Entry
dn: cn=Bjorn J Jensen, dc=example, dc=com
cn: Bjorn J Jensen
cn: Bjorn Jensen
objectClass: person
sn: Jensen
# Base64 encoded JPEG photo
jpegPhoto:: /9j/4AAQSkZJRgABAAAAAQABAAD/2wBDABALD
A4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQ
ERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVG
# Jennifer’s Entry
dn: cn=Jennifer J Jensen, dc=example, dc=com
cn: Jennifer J Jensen
cn: Jennifer Jensen
objectClass: person
sn: Jensen
Listing 1-1 LDIF file with three employee entries

LDAP History
LDAP was developed by Tim Howes, Steve Kille, and Wengyik Yeong to create a network protocol to get data
out. In 1993 appeared the first draft of the RFC 1487,17 which contained the specification of LDAP based on
the access of X.500.
The first version acts as a proxy or gateway to X.500 directories, a comprehensive directory service
developed in the 1980s.
Tim Howes, with his colleagues, created the Open Source University of Michigan LDAP Implementation,
which became the reference for all the LDAP servers. The project’s website is active18 and accessible only for
historical reference.
The second version, the first to be operative (LDAPv2), was released in 1993 as an Internet Engineering
Task Force (IETF) Proposed Standard with basic operations like searching and modifying information. This
version offers limited functionality and has some problems related to the security mechanisms.
The third version, the latest available, was released in 1997, including many improvements related to
security, like Transport Layer Security (TLS) and the possibility of supporting referrals. It was based on RFCs
like RFC 225119 and RFC 4519,20 which explain the protocol and the supported data models. This version
became the de facto standard for directory services, and many applications have support to integrate and
use LDAP to obtain certain information.

LDAP Vendors
LDAP gained wide support from various vendors. There has also been a strong open source movement to
produce LDAP servers. Table 1-5 outlines some of the popular directory servers and include the information
about which is the docker image to run each of them with a small configuration.
Table 1-5 LDAP Vendors
Directory Vendor Open URL
Name Source?
Apache DS Apache Yes https://directory.apache.org/apacheds/ https://hub.docke
OpenLDAP OpenLDAP Yes https://www.openldap.org/ https://hub.d

Tivoli IBM No https://www.ibm.com/docs/en/i/7.5?topic=services-tivoli- No existing official i


Directory directory-server-i-ldap
Server
Active Microsoft No https://learn.microsoft.com/en-us/windows/win32/adsi/so- No existing official i
Directory what-is-active-directory?redirectedfrom=MSDN
eDirectory Novell No https://www.microfocus.com/en-us/cyberres/identity- No existing official
access-management/edirectory

Oracle Oracle No https://www.oracle.com/security/identity- No existing official i


Directory (formerly management/technologies/directory-server-enterprise-
Server Sun) edition
Enterprise
Edition
(ODSEE)
Oracle No https://www.oracle.com/middleware/technologies/internet- No existing official i
Internet directory.html
Directory
(OID)
OpenDJ ForgeRock Yes https://github.com/OpenIdentityPlatform/OpenDJ https://hub.docker
ApacheDS and OpenDJ are pure Java implementations of LDAP directories. You will be using these two
servers for unit and integration testing of the code throughout this book.

Sample Application
Throughout this book, you will be working with a directory for a hypothetical book library. I have chosen the
library because the concept is universal and easy to grasp. A library usually stores books and other
multimedia that patrons can borrow. Libraries also employ people to take care of daily library operations. To
keep things manageable, the directory will not store book information. A relational database is suitable for
recording book information. Figure 1-7 shows the LDAP directory tree for our library application.

Figure 1-7 Library DIT

I have used the RFC 224714 convention in this directory tree to name the base entry. The base entry has
two organizational unit entries that hold the employees’ and patrons’ information. The ou=employees part
of the tree will hold all the library employee entries. The ou=patrons part of the tree will hold the library
patron entries. Both library employee and patron entries are of the type inetOrgPerson objectClass.
Both employees and patrons access library applications using their unique login id. Thus, the uid attribute
will be used as the RDN for entries.
Summary
LDAP and applications that interact with LDAP have become a key part of every enterprise today. This
chapter covered the basics of the LDAP directory. You learned that LDAP stores information as entries. Each
entry is made up of attributes that are simply key-value pairs. These entries can be accessed via their
distinguished names. You also saw that LDAP directories have schemas that determine the type of
information that can be stored.
The next chapter will look at communicating with an LDAP directory using Java Naming and Directory
Interface (JNDI). In the chapters following Chapter 2, you will focus on using Spring LDAP for developing
LDAP applications.

Footnotes
1 https://docs.oracle.com/javase/jndi/tutorial/ldap/models/x500.html

2 https://en.wikipedia.org/wiki/Write_Once_Read_Many

3 https://www.techtarget.com/searchstorage/definition/WORM-write-once-read-many

4 https://www.oracle.com/in/database/what-is-a-relational-database/

5 https://www.ibm.com/products/db2

6 https://www.mysql.com/

7 https://www.postgresql.org/

8 https://cassandra.apache.org/_/index.html

9 https://www.mongodb.com/

10 https://learn.microsoft.com/en-us/windows/win32/adschema/attributes-all

11 https://docs.oracle.com/cd/E24001_01/oid.1111/e10035/schema_objclass.htm

12 https://www.ietf.org/

13 https://www.rfc-editor.org/

14 https://www.ietf.org/rfc/rfc2247.txt

15 https://www.ietf.org/rfc/rfc2829.txt
16 https://www.ietf.org/rfc/rfc2849.txt

17 https://datatracker.ietf.org/doc/html/rfc1487

18 www.umich.edu/~dirsvcs/ldap/ldap.html

19 https://datatracker.ietf.org/doc/html/rfc2251

20 https://datatracker.ietf.org/doc/html/rfc4519
© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023
B. Varanasi, A. Sacco, Practical Spring LDAP
https://doi.org/10.1007/979-8-8688-0002-3_2

2. Java Support for LDAP


Balaji Varanasi1 and Andres Sacco2
(1) Salt Lake City, UT, USA
(2) Buenos Aires, Buenos Aires, Argentina

As the name suggests, the Java Naming and Directory Interface (JNDI) provides a standardized
programming interface for accessing naming and directory services. It is a generic Application
Programming Interface (API) that can access various systems, including file systems, Enterprise Java Beans
(EJB),1 Common Object Request Broker Architecture (CORBA),2 and directory services such as the Network
Information Service and LDAP. JNDI’s abstractions to directory services can be viewed as similar to Java
Database Connectivity (JDBC)’s abstractions to relational databases.
The JNDI architecture consists of an Application Programming Interface or API and a Service Provider
Interface or SPI. Developers program their Java applications using the JNDI API to access directory/naming
services. Vendors implement the SPI with details that deal with actual communication to their particular
service/product. Such implementations are referred to as service providers. Figure 2-1 shows the JNDI
architecture and a few naming and directory service providers. This pluggable architecture provides a
consistent programming model and prevents the need to learn a separate API for each product.

Figure 2-1 JNDI architecture

The JNDI has been part of the standard JDK distribution since Java version 1.3 and has not moved to
Jakarta like other packages. The API itself is spread across five packages:
The javax.naming3 package contains classes and interfaces for looking up and accessing objects in a
naming service.
The javax.naming.directory4 package contains classes and interfaces that extend the core javax.naming
package. These classes can access directory services and perform advanced operations such as filtered
searching.
The javax.naming.event5 package has functionality for event notification when accessing naming and
directory services.
The javax.naming.ldap6 package contains classes and interfaces that support the LDAP Version 3
controls and operations. Later chapters will examine controls and operations.
The javax.naming.ldap.spi7 package contains classes to support defining custom DNS for LDAP. The
support of this feature has appeared since Java 12.
The javax.naming.spi8 package contains the SPI interfaces and classes. As mentioned earlier, service
providers implement SPI, and we will not cover these classes in this book.
LDAP Using JNDI
While JNDI allows access to a directory service, it is essential to remember that JNDI is not a directory or a
naming service. Thus, we need a running LDAP directory server to access LDAP using JNDI.
Accessing LDAP using JNDI usually involves three steps:
Connect to LDAP
Perform LDAP operations
Close the resources

Note Check if you have installed the correct version of Java on your machine. To do this, look at
Appendix A, which explains how to do it.
If you don’t have a test LDAP server available, please refer to the steps in Appendix B for installing a
local LDAP server or running it using Docker. The explanation about how to install Docker and check if
everything is okay appears in Appendix A.
This chapter aims to show how you can do different operations on LDAP using Java without any
framework. With this approach, you will see the complexity of doing certain operations and writing
many lines of code to do something simple with the assistance of some framework like Spring LDAP.

Connect to LDAP
All the naming and directory operations using JNDI are performed relative to a context. So the first step in
using JNDI is to create a context that acts as a starting point on the LDAP server. Such a context is referred to
as an initial context. Once an initial context is established, it can look up other contexts or add new objects.
The Context interface and InitialContext class in the javax.naming package can be used for creating an
initial naming context. Since we are dealing with a directory here, we will use a more specific DirContext
interface and its implementation InitialDirContext. Both DirContext and InitialDirContext are available
inside the javax.naming.directory package. The directory context instances can be configured with
properties that provide information about the LDAP server. The code in Listing 2-1 creates a context for an
LDAP server running locally on port 1389.

Properties environment = new Properties();


environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://localhost:11389");
DirContext context = new InitialDirContext(environment);
Listing 2-1 How to create a basic connection with LDAP

Note In the following parts of the chapter, I will explain in detail the most relevant parts to connect
and execute some operations to LDAP.
By the end of this chapter, you will see the different outputs of the execution of the different methods.

In Listing 2-1, we have used the INITIAL_CONTEXT_FACTORY constant to specify the service provider class
that needs to be used. Here, we use the sun provider com.sun.jndi.ldap.LdapCtxFactory, which is part of
the standard JDK distribution. The PROVIDER_URL is used to specify the fully qualified URL of the LDAP
server. The URL includes the protocol (LDAP for nonsecure or LDAPs for secure connections), the server
hostname, and the port.

Note The declaration of the type on a variable has been optional since Java 14, so you don’t need to
declare that the variable environment has the type Properties; you can replace the keyword var, and the
compiler will infer the correct type.
This change does not add any feature related to the performance, so I decided to keep the code
simple.
Once a connection to the LDAP server is established, the application can identify itself by providing
authentication information. Contexts like the one created in Listing 2-1, where authentication information
is not provided, are called anonymous contexts. LDAP servers usually have ACLs (access list controls) that
restrict operations and information to certain accounts. So it is very common in enterprise applications to
create and use authenticated contexts. Listing 2-2 provides an example of creating an authenticated context.
Notice that we have used three additional properties to provide the binding credentials. The
SECURITY_AUTHENTICATION property is set to simple, indicating that we will use a plain text username
and password for authentication.

Properties environment = new Properties();


environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://localhost:11389");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
environment.setProperty(DirContext.SECURITY_PRINCIPAL, "Directory Manager");
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "secret");
DirContext context = new InitialDirContext(environment);
Listing 2-2 How to connect on LDAP using the credentials

Note On the declaration of the different properties, you can see the class DirContext appear many
times, which is not the best approach, so if you want to reduce the duplicates, you can simplify using
static imports. For example, you can declare the static import like this: import static
javax.naming.directory.DirContext.INITIAL_CONTEXT_FACTORY, and on the declaration of the variable,
just use PROVIDER_URL.

Any problems occurring during the context creation will be reported as instances of
javax.naming.NamingException. NamingException is the superclass of all the exceptions thrown by the
JNDI API. This is a checked exception and must be handled properly for the code to compile. Table 2-1 lists
common exceptions we will likely encounter during JNDI development.
Table 2-1 Common LDAP Exceptions

Exception Description
AttributeInUseException Thrown when an operation tries to add an existing attribute.
AttributeModificationException Thrown when an operation tries to add/remove/update an attribute and violates the
attribute’s schema or state. For example, adding two values to a single-valued attribute
would result in this exception.
CommunicationException Thrown when an application fails to communicate (network problems) with the LDAP
server.
InvalidAttributesException Thrown when an operation tries to add or modify an attribute set that has been specified
incompletely or incorrectly. For example, adding a new entry without specifying all the
required attributes would result in this exception.
InvalidAttributeValueException Thrown when an operation tries to add or modify a value of an attribute that enters a
conflict with the schema definition.
InvalidSearchFilterException Thrown when a search operation is given a malformed search filter.
LimitExceededException Thrown when a search operation abruptly terminates as a user- or system-specified result
limit is reached.
NameAlreadyBoundException Thrown to indicate that an entry cannot be added as the associated name is already bound
to a different object.
NotContextException Thrown when an operation process until the context is required to continue.
OperationNotSupportedException Thrown when a context implementation does not support a specific operation when
invoked.
PartialResultException Thrown to indicate that only a portion of the expected results is returned and the
Exception Description
operation cannot be completed.
SizeLimitExceededException Thrown when a method produces a result that exceeds a size-related limit.
TimeLimitExceededException Thrown when a method produces a result that exceeds a time-related limit.

LDAP Operations
Once we obtain an initial context, we can perform various operations on LDAP using the context. These
operations can involve looking up another context, creating a new one, and updating or removing an
existing one. Here is an example of looking up another context with DN
uid=emp1,ou=employees,dc=inflinx,dc=com:

DirContext
anotherContext = context.lookup("uid=emp1,ou=employees,dc=inflinx,dc=com");

We will closely examine each of these operations in the coming section.

Closing Resources
After completing all desired LDAP operations, it is important to close the context and any other associated
resources properly. Closing a JNDI resource simply involves calling the close method on it. Listing 2-3 shows
the code associated with closing a DirContext. The code shows that the close method also throws a
NamingException that needs to be properly handled.

try {
context.close();
} catch (NamingException e) {
//Do something with the exception, like log the error.
}
Listing 2-3 How to close the connection with LDAP

Note The previous block does not use “try-with-resources” because DirContext does not implement
the auto closeable.

Creating a New Entry


Consider the case where a new employee starts with our hypothetical library, and we are asked to add their
information to LDAP. As we have seen earlier, before an entry can be added to LDAP, it is necessary to obtain
an InitialDirContext. Listing 2-4 defines a reusable method for doing this.

private DirContext getContext() throws NamingException{


Properties environment = new Properties();
environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL,
"ldap://localhost:1389");
environment.setProperty(DirContext.SECURITY_PRINCIPAL, "cn=Directory
Manager");
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "secret");
return new InitialDirContext(environment);
}
Listing 2-4 Create a method to connect with LDAP
Once we have the initial context, adding the new employee information is straightforward, as shown in
Listing 2-5.

public void addEmployee(Employee employee) {


DirContext context = null;
try {
context = getContext();
// Populate the attributes
Attributes attributes = new BasicAttributes();
attributes.put(new BasicAttribute("objectClass", "inetOrgPerson"));
attributes.put(new BasicAttribute("uid", employee.getUid()));
attributes.put(new BasicAttribute("givenName",
employee.getFirstName()));
attributes.put(new BasicAttribute("surname", employee.getLastName()));
attributes.put(new BasicAttribute("commonName",
employee.getCommonName()));
attributes.put(new BasicAttribute("departmentNumber",
employee.getDepartmentNumber()));
attributes.put(new BasicAttribute("mail", employee.getEmail()));
attributes.put(new BasicAttribute("employeeNumber",
employee.getEmployeeNumber()));
Attribute phoneAttribute =
new BasicAttribute("telephoneNumber");
for(String phone : employee.getPhone()) {
phoneAttribute.add(phone);
}
attributes.put(phoneAttribute);
// Get the fully qualified DN
String dn = "uid="+employee.getUid() + "," + BASE_PATH;
// Add the entry
context.createSubcontext("dn", attributes);
} catch(NamingException e) {
// Handle the exception and show the description of the problem
} finally {
closeContext(context);
}
}
Listing 2-5 Add a new entry on LDAP

As you can see, the first step in the process is to create a set of attributes that needs to be added to the
entry. JNDI provides the javax.naming.directory.Attributes interface and its implementation
javax.naming.directory.BasicAttributes to abstract an attribute collection. We then add the employee’s
attributes one at a time to the collection using JNDI’s javax.naming.directory.BasicAttribute class. Notice
that we have taken two approaches in creating the BasicAttribute class. In the first approach, we added the
single-valued attributes by passing the attribute name and value to BasicAttribute’s constructor. To handle
the multivalued attribute telephone, we first created the BasicAttribute instance by just passing in the
name. Then, we individually added the telephone values to the attribute. Once all the attributes are added,
we invoked the createSubcontext method on the initial context to add the entry. The createSubcontext
method requires the fully qualified DN of the entry to be added.
Notice that we have delegated the closing of the context to a separate method closeContext. Listing 2-6
shows its implementation.

private void closeContext(DirContext context) {


try {
if (null != context) {
context.close();
}
} catch (NamingException e) {
// Handle the exception and show the description of the problem
}
}
Listing 2-6 How to close the connection with LDAP

Updating an Entry
Modifying an existing LDAP entry can involve any of the following operations:
Add a new attribute and value(s) or add a new value to an existing multivalued attribute.
Replace an existing attribute value(s).
Remove an attribute and its value(s).
To allow modification of the entries, JNDI provides an aptly named
javax.naming.directory.ModificationItem class.
A ModificationItem consists of the type of modification to be made and the attribute under modification.
The following code creates a modification item for adding a new telephone number:

Attribute telephoneAttribute = new BasicAttribute("telephone",


"80181001000");
ModificationItem modificationItem = new ModificationItem(DirContext.
ADD_ATTRIBUTE, telephoneAttribute);

Notice that in the preceding code, we have used the constant ADD_ATTRIBUTE to indicate that we want
an add operation. Table 2-2 provides the supported modification types along with their descriptions.

Table 2-2 LDAP Modification Types

Modification Type Description


ADD_ATTRIBUTE Adds the attribute with the supplied value or values to the entry. If the attribute does not exist, then it
will be created. If the attribute is multivalued, this operation adds the specified value(s) to the
existing list. However, this operation on an existing single-valued attribute will result in the
AttributeInUseException.
REPLACE_ATTRIBUTE Replaces existing attribute values of an entry with the supplied values. If the attribute does not exist,
then it will be created. If the attribute already exists, all its values will be replaced.
REMOVE_ATTRIBUTE Removes the specified value from the existing attribute. If no value is specified, the entire attribute
will be removed. If the specified value does not exist in the attribute, the operation will throw a
NamingException. If the value to be removed is the only value of the attribute, then the attribute is
also removed.

The code for updating an entry is provided in Listing 2-7. The modifyAttributes method takes the entry’s
fully qualified DN and an array of modification items.

public void update(String dn, ModificationItem[] items) {


DirContext context = null;
try {
context = getContext();
context.modifyAttributes(dn, items);
} catch (NamingException e) {
// Handle the exception and show the description of the problem
} finally {
closeContext(context);
}
}
Listing 2-7 How to update an entry
Removing an Entry
Removing an entry using JNDI is a straightforward process shown in Listing 2-8. The destroySubcontext
method takes the fully qualified DN of the entry that needs to be deleted.

public void remove(String dn) {


DirContext context = null;
try {
context = getContext();
context.destroySubcontext(dn);
} catch (NamingException e) {
// Handle the exception and show the description of the problem
} finally {
closeContext(context);
}
}
Listing 2-8 How to remove an entry

Many LDAP servers don’t allow an entry to be deleted if it has child entries. In those servers, deleting a
non-leaf entry would require traversing the subtree and deleting all the child entries. Then the non-leaf
entry can be deleted. Listing 2-9 shows the code involved in deleting a subtree.

public void removeSubtree(DirContext ctx, String root) throws


NamingException {
NamingEnumeration enumeration = null;
try {
enumeration = ctx.listBindings(root);
while (enumeration.hasMore()) {
Binding childEntry = (Binding) enumeration.next();
LdapName childName = new LdapName(root);
childName.add(childEntry.getName());

try {
ctx.destroySubcontext(childName);
} catch (ContextNotEmptyException e) {
removeSubtree(ctx, childName.toString());
ctx.destroySubcontext(childName);
}
}
} catch (NamingException e) {
// Handle the exception and show the description of the problem
} finally {
try {
enumeration.close();
} catch (Exception e) {
// Handle the exception and show the description of the problem
}
}
}
Listing 2-9 How to remove a subtree of elements

Note The OpenDJ LDAP server supports a special subtree delete control that can cause the server to
delete the non-leaf entry and all its child entries when attached to a delete request. We will look at using
LDAP controls in Chapter 7.
Searching Entries
Searching for information is usually the most common operation against an LDAP server. To perform a
search, we need to provide information such as the scope of the search, what we are looking for, and what
attributes need to be returned. In JNDI, this search metadata is provided using the SearchControls class.
Listing 2-10 provides an example of a search control with subtree scope and returns the givenName and
telephoneNumber attributes. The subtree scope indicates that the search should start from the given base
entry and should search all its subtree entries. We will look at the different scopes available in detail in
Chapter 6.

SearchControls searchControls = new SearchControls();


searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[]{"givenName",
"telephoneNumber"});
Listing 2-10 The attributes to return for each entry

Once the search controls are defined, the next step is invoking one of the many search methods in the
DirContext instance. Listing 2-11 provides the code that searches all the employees and prints their first
name and telephone number.

public void search() {


DirContext context = null;
NamingEnumeration<SearchResult> searchResults = null;
try {
context = getContext();
// Setup Search meta data
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[] { "givenName",
"telephoneNumber" });
searchResults = context.search("dc=inflinx,dc=com", "
(objectClass=inetOrgPerson)", searchControls);

while (searchResults.hasMore()) {
SearchResult result = searchResults.next();
Attributes attributes = result.getAttributes();
String firstName = (String) attributes.get("givenName").get();

// Read the multi-valued attribute


Attribute phoneAttribute = attributes.get("telephoneNumber");
String[] phone = new String[phoneAttribute.size()];
NamingEnumeration phoneValues = phoneAttribute.getAll();

for (int i = 0; phoneValues.hasMore(); i++) {


phone[i] = (String) phoneValues.next();
}
//You can use logback or system.out
logger.info(firstName + "> " + Arrays.toString(phone));
}
} catch (NamingException e) {
// Handle the exception and show the description of the problem
} finally {
try {
if (null != searchResults) {
searchResults.close();
}
closeContext(context);
} catch (NamingException e) {
// Handle the exception and show the description of the problem
}
}
}
Listing 2-11 How to search elements
Here, we used the search method with three parameters: a base that determines the search’s starting
point, a filter that narrows down the results, and a search control. The search method returns an
enumeration of SearchResults. Each search result holds the LDAP entry’s attributes. Hence, we loop through
the search results and read the attribute values. Notice that we obtain another enumeration instance for
multivalued attributes and read its values one at a time. In the final part of the code, we close the result
enumeration and the context resources.

Check How the Operations Work


After that, reading all the source code of the different operations could be a good idea to check if everything
works fine or not. To do this, a possible approach is to create a class that invokes the different methods of
accessing LDAP using JNDI.
Listing 2-12 shows you a class App that creates an instance of a class JndiLdapDaoImpl, which contains
all the methods of the different operations you see from Listings 2-4 to 2-11. In the case of Listing 2-12, you
only will execute one operation because it’s more simple to analyze the logs.

public class App {


public static void main(String[] args) {
JndiLdapDaoImpl jli = new JndiLdapDaoImpl();
//Search
jli.search();
}
}
Listing 2-12 A class that invokes the method search

If you run the application with the previous block of code, you will see something like Listing 2-13.

12:23:40.978 [main] INFO com.apress.book.ldap.dao.impl.JndiLdapDaoImpl -


Chie> [+1 622 858 9026]
12:23:40.978 [main] INFO com.apress.book.ldap.dao.impl.JndiLdapDaoImpl -
Chin> [+1 191 452 7983]
12:23:40.978 [main] INFO com.apress.book.ldap.dao.impl.JndiLdapDaoImpl -
ChinFui> [+1 439 500 8383]
12:23:40.978 [main] INFO com.apress.book.ldap.dao.impl.JndiLdapDaoImpl -
Ching-Long> [+1 407 407 2419]
12:13:14.186 [main] INFO com.apress.book.ldap.dao.impl.JndiLdapDaoImpl -
Chip> [+1 833 470 1660]
Listing 2-13 The result of obtaining all the employees from LDAP

The next step is to add an employee and obtain all the employees to check whether the operations were
okay. Let’s make some little modifications to the class App, like Listing 2-14.

public class App {


public static void main(String[] args) {
JndiLdapDaoImpl jli = new JndiLdapDaoImpl();

//Add and search


jli.addEmployee(getEmployee());
Exploring the Variety of Random
Documents with Different Content
The same now became the case with Burrel. He had been once
received as an intimate in the house of the Delawares, and the door
was open to him whenever he chose. There was something to be
said, it is true, upon the score of a great service rendered, which, of
course, formed a tie between him and every member of the
Delaware family, which existed in no other case. But still there was a
great deal of habit in the matter; and Burrel, having now his purpose
to carry too, took care that the good custom should not drop.

He became almost a daily visiter. Many a long-ramble he took with


Captain Delaware; many a sweet intoxicating walk beside Blanche.
Many, too, were the long and pleasant discussions he held with Sir
Sidney, upon every subject under the sun--the customs and manners
of our ancestors--the glorious works of past ages--the stores of
classical knowledge, or the beauties and perfections, follies and
absurdities, of our own and other lands.

As some French writer has said, "C'est dans les petites choses que
l'on temoigne son amitié. L'amour propre a trop de part à ce qu'on
fait dans les grandes occasions;" and it is this truth that makes small
attentions always pleasant to those who receive them--great
services often painful. Burrel felt that it was so; and took infinite
care to conceal that he had the slightest thought of relieving Sir
Sidney Delaware from his difficulties; but, at the same time, by the
display of elegant manners and a polished mind, and by the constant
outbreakings of a generous and a noble heart, he rendered himself
both so agreeable and so much esteemed, that Sir Sidney learned to
think, "If I required any great service, I would ask it of Henry Burrel
sooner than of any other man I know."

Very soon the worthy baronet began to look for his appearance
shortly after breakfast; and, as he had always something--perhaps
of little consequence--but still something on which he wished to
speak with him, he twice caught himself saying, when Burrel was a
few minutes after the usual hour, "I wish Mr. Burrel would come;"
and then remembered, with a sort of cynical smile, springing from
very mixed feelings, that he had no right to expect that he would
come at all.

Burrel always did come, however; and, finding that he was ever
made most welcome by the baronet, greeted with a hearty shake of
the hand by Captain Delaware, and found a bright, though timid,
smile on the sweet lips of Blanche, he did not find it very difficult to
assign motives for his each day's visit, or to discover an excuse for
the call of the next morning. Sir Sidney Delaware soon began to give
him stronger marks of his esteem; and on more than one occasion,
when accidentally alone with Burrel, referred frankly to the state of
his own affairs, and the causes which had combined to produce their
embarrassment.

Burrel, on his part, of course found the subject difficult to


converse upon, and the more so, perhaps, from the previous
knowledge, which he did not choose to display. However, when on
one occasion the baronet directly mentioned the annuity granted to
the Earl of Ashborough, he replied--"But the interest is enormous,
and the earl would, of course, suffer you to redeem it."

"I am sorry to say, my young friend," replied Sir Sidney, "that at


the time you met William in the coach coming from London, the poor
fellow was returning full of disappointment from an unsuccessful
attempt to persuade Lord Ashborough to permit the repayment of
the original sum. But his lordship refused in the most peremptory
manner; and, on the deed being produced, no clause of redemption
was found in it, although, in the original letter of instructions for the
preparation of that instrument, the introduction of such a clause is
expressly enjoined."

"If I might advise, Sir Sidney," replied Burrel; but then breaking
off again, he added--"But perhaps I am taking too great a liberty
with you, in even offering advice upon your private affairs."
"Not in the least, my dear sir!" replied the baronet. "Speak, speak,
my dear sir! I have forgotten all my legal learning, and shall be very
glad of any advice upon the subject."

"I know nothing of law, either," answered Burrel smiling; "but I


know a little of Lord Ashborough, and I know the character he bears
in the world. Of his faults and failings, I do not pretend to speak; but
his lordship has, of course, his share. He has, however, always
maintained a grave and dignified name, and high character in
society; and it is very generally believed that his lordship values the
reputation of a just, stern, upright peer, more than"----

"The reality!" added Sir Sidney Delaware, with one of those


sneers which had made him many an enemy in his youth--Strange
that a turn up of the nostril should make men cut each other's
throats!

"I was not going to be quite so severe," said Burrel, somewhat


gravely; "but I was going to add, that he values that reputation
more than any part of his estate; and I should think that if your son
were to go to London once more, and were to show him the letter of
instructions for the preparation of the annuity deed, pointing out to
him that the clause has been omitted, either by the mistake or the
fraud of a lawyer, and hinting at the publicity of a court of justice--I
think, I say--indeed I feel sure, that his lordship's care for his
reputation, coming in support of what I believe to be his natural
sense of equity, would make him at once accept the redemption."

"Perhaps you are right in regard to his care for his reputation, Mr.
Burrel," replied Sir Sidney Delaware. "But I, who know him better
perhaps than you do, cannot reckon much upon his sense of equity.
I know him well--thoroughly! In early years, before these children
were born, Lord Ashborough and myself were unfortunately involved
in a dispute, which did not arise in any great demonstrations of a
sense of equity on his part; and since that time, I have reason to
believe that disappointment, added to a bitter quarrel, has caused
him to watch an opportunity of treading on the head of one, against
whom Time even--the great mollifier of all things--has not been able
to abate his rancour."

"I would fain believe that you do not quite do him justice," replied
Burrel. "May not a little personal dislike on your own part, my dear
sir, influence your mind against him?"

"No, indeed, Mr. Burrel! No, indeed!" answered Sir Sidney


Delaware. "I know him intus et in cute novi. He was, and is, and
ever will be, the same man. The cause of our quarrel now lies in the
cold forgetful dust, where all such dissensions cease. Besides, I was
naturally the least offended of the two, being the injured person. I
also was successful--he disappointed--notwithstanding all his arts;
and therefore the matter with me was soon forgotten, while with
him it has been, I am afraid, long remembered. Nevertheless," he
added, "do not for a moment fancy that I am saying all this because
I do not intend to follow your advice. Far from it--William shall go
up. Indeed, I should think myself very wrong, were I to leave any
means untried to remove those embarrassments which shut my
children out from the society to which by birth they are entitled."

Captain Delaware soon joined the conference; and, although he


shook his head at all idea of changing the determination of Lord
Ashborough, yet he undertook to try, with a readiness that the cold
and haughty demeanour which he described that nobleman to have
maintained towards him, rendered a little extraordinary. The
resolution, however, once taken, William Delaware was not a man,
either by temperament or habit, to lose a moment in putting it into
execution, and his place was instantly secured in the next morning's
coach for London. Burrel agreed to dine at the mansion, and the day
passed over with that additional drop of excitement, which renewed
hope and expectation, however faint, are still sure to let fall into the
cup of life.
Either it was really so, or Burrel fancied it, that Blanche Delaware
was more lovely and more fascinating than ever; and, indeed, the
feelings that had been growing upon her for several days, had added
an indescribable and sparkling charm to all the attractions of youth,
and grace, and beauty. The soul always did much in her case to
increase the loveliness that nature had bestowed upon her face and
form, and Burrel could not help imagining--even long before--that
the graceful movement of each elegant limb, and finely modelled
feature, was but the corporeal expression of a bright and generous
mind within. But now the heart, too, was called into play, and all the
warm and sunny feelings of a young and ardent bosom, sparkled
irrepressibly up to the surface, calling forth new charms, both in
their accidental flash, and in the effort to suppress them.

All Burrel's enthusiasm, too--brought as he was by every


circumstance into nearer connexion with that fair being, than any
other events could possibly have produced--having been admitted to
that intimate friendship which no other man shared--having become
the friend and adviser of her father and brother, and having saved
her own life--all his own natural enthusiasm of character, therefore,
unchained by any opposing motive, broke through all the habitual
restraints of the state of life to which he had so long been
accustomed; and during that afternoon, Henry Burrel, with very little
concealment of his feelings, sat beside Blanche Delaware, full of that
bright unaccountable thing--love.

The matter was so evident, and indeed had been so evident for
the last two or three days, that the eyes of Captain Delaware
himself--not very clear upon such subjects--had been fully opened;
and now, as Burrel bent over his sister's drawing-frame with a look
of tenderness and affection that would bear but one interpretation,
he turned his eyes upon his father to see whether it were really
possible that he did not perceive the feelings that were kindling up
before him.
No one perhaps had ever in his day felt more deep and sincere
love than Sir Sidney Delaware, yet--it is wonderful! quite wonderful!-
-Burrel might almost, as the old romances term it, have died of love
at his daughter's feet, without his perceiving that any thing was the
matter. Burrel was bending over Blanche Delaware with a look, and a
tone, and a manner, that all declared, "Never, in the many mingled
scenes which I have trod, did I meet with any thing so beautiful, so
gentle, so graceful as yourself!" Captain Delaware, as I have said,
turned his eyes upon his father; but Sir Sidney, with his fine head a
little thrown back, a pair of tortoiseshell spectacles upon his nose,
and his face to the bookcases, was walking quietly along, looking
earnestly for Pliny.

Oh, had you not forgotten all your lessons in the natural history of
the heart, you might have marked much. Sir Sidney Delaware, that
would have given you more to study than could be found in Pliny, ay,
or Plato either!

"I must look to it myself," thought Captain Delaware. "Poor


Blanche! It would not do to have the dear girl's affections trifled
with.--Yet, I do not think he is one to play such a part either--Oh,
no!--yet I must speak to him!"

With this doughty resolution, and a thousand thoughts and


difficulties in regard to what he was to say when he did begin,
Captain Delaware sat down to dinner, somewhat absent and pensive;
and after Blanche had left them, and Sir Sidney had retired to his
dressing-room to indulge in a somewhat usual nap after dinner, the
gallant officer invited his friend to ramble through the park till tea-
time, fully prepared to do a great deal that a man of the world would
never have thought of doing at all. Burrel saw that something was
weighing upon his companion's mind; but as his own determinations
in regard to Blanche were completely formed, and he feared no
questions upon the subject, he did not anticipate any. He left
Captain Delaware, however, to bring forth his own thoughts at
leisure, and walked on by his side as silent as himself, though not
quite so much embarrassed.

At length. Captain Delaware began--"I have wished," he said, "Mr.


Burrel"----

Burrel started, for the epithet Mister had long been dropped
towards him by his companion, and he evidently perceived that
something very formal was working its way through his friend's
mind.

"I have wished, Burrel," repeated Captain Delaware, correcting


himself on seeing the surprise expressed by the other's
countenance--"I have wished to speak with you about my sister;"
and, as he mentioned that dear name, a sense of deep affection for
her made him proceed more boldly, though his face glowed warmly
as he spoke. "You have been much with her of late, and perhaps
may be so for some time longer. Now--do not misunderstand me,
Burrel--do not think 1 doubt you, or seek to question you: but I wish
first to put you in mind that she sees very few persons besides
yourself, and next to tell you--as most men of station and fortune
expect to receive some portion with their wives--to tell you that the
greater part even of the small sum which Blanche and I inherited
from our mother, is engaged to support as far as possible, and that
is little enough, our father's station in society."

"And did you, my dear Delaware, suppose for a moment"--said


Burrel, in reply, "did you imagine, from what you have hitherto seen
of my conduct and sentiments, that so long as I had enough myself
to offer any woman I might love, I would consider her fortune for an
instant?"

"No, no! I did not suppose you would," replied Captain Delaware,
hesitating in some degree how to proceed. "But the truth is, Burrel, I
have heard that women's hearts are delicate things, and as easily
wounded as the wing of a butterfly. However, let us say no more of
it. I begin to think that I have got out of my depth, and meddled
with matters I had better have left to themselves."

For some reason, or reasons--from some simple or complex


motive, which I do not know, and shall not stop to discover--men,
however fully their minds may be made up in such matters as that
on which I write, never like to be questioned upon the subject till
they choose to explain themselves; and, although Burrel was fully
determined to offer his hand to Blanche Delaware, as soon as he
had convinced himself that not a shadow of hesitation on her part
would hurt his pride; and though he completely understood Captain
Delaware's feelings upon the subject, and was amused at his
straightforwardness, yet some internal little devil of perversity made
him feel almost offended at the sentences we have just recorded. He
resisted, however, and the devil fled from him.

"My dear Delaware," he said, after a moment's pause, which he


employed in clearing his bosom of the enemy, "although no man
likes to make a declaration, except at his own choice and
convenience, yet, situated as you are, I can enter into all your
feelings for your sister. Set your mind at rest then," he added, laying
his hand frankly and kindly on his companion's arm. "Set your mind
at rest then, as far as I am concerned. It is my intention, as soon as
I can entertain any hope of success, to offer my hand to your sister.
If she refuse me, it is not my fault you know; but this much you will,
I am sure, take upon my word, that I would not presume for one
moment to solicit the hand of a daughter of Sir Sidney Delaware,
unless in rank I could aspire to that honour, and in fortune could
maintain her in that circle which she is calculated to adorn. Let us
say no more upon the subject, if you can trust me."

Captain Delaware grasped his hand warmly, "You have made me


very happy," he said.

"Well, then, keep my secret," added Burrel with a smile, "and let
your sister decide the rest."
William Delaware could well have told, at least he thought so,
what his sister's decision would be; but delicacy prevented him from
speaking his belief; and with a lightened heart he changed the
subject, and returned with Burrel to the mansion.

CHAPTER XII.

William Delaware set out from Emberton, and arrived in London.


His next step was to send a note to Lord Ashborough, informing him
of his being in town, and requesting an interview the following
morning; and in answer he received a very polite though somewhat
formal billet, inviting him to breakfast in Grosvenor Square, and
promising as long an audience after that meal as he might think
necessary.

At the appointed hour--for Captain Delaware never considered


that appointed hours mean nothing--he approached Lord
Ashborough's house, and was ushered up stairs, where he found
housemaids and empty drawing-rooms enow; and, planting himself
at a window that looked out into the square, he gazed forth with
somewhat unpleasant anticipations occupying his mind, and
rendering his eye sightless as to all that was passing before it.

In a few minutes the housemaids withdrew from the farther


rooms, and the whole suit became vacant for some time, till a light
step caught Captain Delaware's ear, and, turning round, he beheld a
young lady whom he had seen there before, when last he had
visited London. At that time he had found her surrounded by a
whole bevy of strangers, whose gay appearance and supercilious
manner had somewhat repelled the young sailor, although Miss
Beauchamp herself. Lord Ashborough's niece, had spoken to him
with frank kindness, and claimed relationship with him at once.

Miss Beauchamp now advanced towards him, while he


acknowledged her approach by a bow, which was stiff though not
awkward. The young lady, however, held out her hand with a gay
smile, and, as he took it, added, in a tone of playful sharpness, "Tell
me, sir, are you my cousin, or are you not?"

"I believe I have some right to claim that honour," replied Captain
Delaware.

"Well, then," continued the young lady, "lay aside, immediately, all
that stiff, chilly reserve, or I will disown you henceforth and for ever."
Captain Delaware smiled, and she continued. "I know that this house
has a very icy atmosphere; but that does not extend to my part of it,
and while my noble and stately uncle may be as frigid as the north
pole in his peculiar territories, the library and the dining-room, I
must have a pleasanter climate in my domains, the drawing-rooms
and breakfast-room."

"Your own presence must always produce such an atmosphere,"


replied Captain Delaware. "But you must remember. Miss
Beauchamp, that I have been but a short time within its influence,
so that I have scarcely had leisure to get thawed."

"Oh, I must unfreeze you quite, erelong, my good cousin," replied


Miss Beauchamp, laughing. "But now, listen to me for five minutes,
for I have a great deal more to say to you than you know any thing
about. Calculating that you would come early, when I heard that my
uncle had asked you to breakfast, I determined to rise a full hour
sooner than usual, on purpose to give you your lesson for the day."

Captain Delaware expressed his thanks as warmly as possible,


acknowledging, however, that his gratitude was somewhat mingled
with surprise, to find that his fair cousin was prepared to be
interested in behalf of one, who, though akin by blood, was nearly a
stranger as far as acquaintance went.

"That would be a severe reproach to my forwardness, William


Delaware," replied the young lady, "if I had not a good motive in
petto. Besides, I find, that in days of yore, when we were all
children, and my good father was alive, that you and I and Blanche,
and my brother Henry, have had many a rude game of play amongst
the old trees of Emberton Park. But, let us speak to the point, as we
may have little time to speak at all--An old friend of yours and mine,
good Dr. Wilton, has written to me a long letter, two or three days
ago, giving me an account of all this unfortunate business between
your father and my uncle, and desiring me, if you ever came to town
again, to do my best to forward your views. Now, the truth is, I have
no more influence with Lord Ashborough than that screen."

"With a thousand thanks for your kind interest," replied Captain


Delaware; "I should still be sorry to owe, even to your influence,
what I could not obtain from justice."

"Pride! Pride!" cried Miss Beauchamp, "the fault of men and


angels! But let me tell you, my dear cousin, that no man or men
have any right to be proud in a woman's presence; for ye are a mere
race of bullies at the best, and bow like the veriest slaves whenever
we chose to tyrannize over you. But to the point.--Listen to my sage
advice. I was saying, that I had no more influence with my Lord
Ashborough than that screen.--I am a mere piece of household
furniture; and, I dare say, that I am to be found, written down in the
inventory thus:--'Front drawing-room--Three tables, four-and-twenty
chairs, four sofas, three chaises longues, a niece.'--I do believe, my
uncle, when I refused the Honourable Mr. What's-his-name, the
other day, which mortally offended his lordship, thought of having
me transferred to the schedule of fixtures forthwith. But,
nevertheless, as I am a hearing and seeing piece of furniture, I have
learned that the only way to manage the Earl of Ashborough, is to
be firm, steady, somewhat haughty, and a good deal stern.
Remember all this, my dearly beloved cousin, and make use of the
hint. But I hear his lordship's morning step, when the neat boot is
first, for that day, fitted on to the neat foot. So I will to the
breakfast-room; and do not forget, when you meet me, to wish me
good-morrow in set form, and civil terms, and take care that you do
not look conscious."

Thus saying, the gay girl ran lightly through the long suite of
rooms, leaving Captain Delaware standing nearly where she had
found him, with a good deal of admiration at her beauty, and a good
deal of surprise at the mingling of kindness both with levity, and with
the slightest possible spice of coquetry, which she had displayed in
their brief conversation.

Ere she was well out of sight, the step that had been heard
above, might be distinguished descending the stairs. There is not a
little character in a step, and the sound of Lord Ashborough's was
peculiar. Perhaps the enfeebling power of time--which, what with
one aid or another, was not very apparent in his person--marked its
progress more decidedly in his step than in any thing else. There
was a certain degree of creaking feebleness in it, especially at an
early hour of the morning, when he was just out of bed, which,
joined with a slow precision of fall, indicated a declension in the firm
and sturdy manhood. His lordship felt it, and in society he covered
the slight falling off by an affectation of grave and thoughtful dignity
of movement,--but his valet-de-chambre knew better.

Captain Delaware, however, did not; and as the earl entered the
room, with a roll of papers in his hand, like Talma in Sylla--he acted
a good deal, by the way--his young relative thought him a very
grave and reverend signor; and would rather have lain for an hour
along side an enemy's frigate, yard-arm to yard-arm, than have
grappled with so stern and thoughtful a personage, on so
disagreeable a business as that which he came to discuss. He had
undertaken it resolutely, however, and he was not a man to flinch
before any coward apprehensions, moral or physical.
The first expression of his lordship's countenance, when his eyes
fell upon his visiter, was not certainly of a nature greatly to
encourage him. For a moment--a single instant--nature got the
better, and a slight shade of that loathing dislike, with which one
regards some poisonous reptile, or the object of some peculiar
antipathy, passed over Lord Ashborough's features. It was gone as
quickly; and with a much more condescending and agreeable smile
than he had bestowed upon him on his former visit, the earl
advanced, and welcomed him to London.

Captain Delaware was of course very well disposed to welcome


any show of kindness; and he said a few words in regard to his
regret at having to trouble Lord Ashborough again.

"Oh! we will speak of all that after breakfast," said the earl.
"When last I saw you I was hurried and fretted by a thousand
things, and had no opportunity of showing you any attention.
Indeed, I have but little leisure now, the duties of my office--he held
a sinecure post, which required him to sign his name twice a-year--
the duties of my office claiming great part of my time. But you must
really, as long as you remain in London, spend your days here; and
my niece, Maria, who has nothing to do, will show you all over the
world, under the fair excuse of your cousinship. But let us to
breakfast. Maria will not be down for this hour; but I never wait for
that lazy girl."

Lord Ashborough was not a little surprised to find his niece in the
breakfast-room, and praised her ironically on her habits of early
rising; but Miss Beauchamp answered at once, "Oh! I had a reason
for getting up soon to-day, otherwise I should certainly not have
done so. To contemplate my dear uncle for an hour, with one foot
crossed over the other, letting his coffee get cold, and reading the
newspaper, is too great a treat to be indulged in every morning."

"And pray, my fair niece," demanded Lord Ashborough, smiling at


a picture of himself, which was not without the cold sort of
importance he chose to assume; "and pray, my fair niece, what was
the particular cause of your infringing your ancient and beloved
habits this morning?"

"First and foremost, of course," replied Miss Beauchamp, with a


graceful bend of the head to her cousin, "to see Captain Delaware,
whose visit you yesterday evening led me to expect; but, in the next
place, my full resolution and determination was to take possession of
your lordship during breakfast, and tease you in every sort of way,
till you agree to leave this horrid place London, now that you are
positively the last gentleman remaining in it, except the men in red-
coats that walk up and down St. James's Street, and look
disconsolate from June till January. But they are forced to stay, poor
fellows! You are not."

"There is no use of going out of town, Maria, to come up again


the next day," replied Lord Ashborough. "Parliament will certainly sit
for a few days this month, and I must be present. But, in regard to
your cousin, I intend to make him over to you for the whole day, as I
have some business to transact; and, therefore, you see you would
not have been deprived of his visit."

"Sad experience making me doubtful," replied Miss Beauchamp


laughing, "in regard to how far your lordship's civility might extend
to your kindred, I did not know whether I might ever see Captain
Delaware again."

She spoke in jest, but it cut home, and Lord Ashborough,


reddening, took his coffee and the newspaper, and left his cousin
and his niece to entertain themselves, while he soon became
immersed in the idle gossip of the day. After breakfast, he led the
way to the library with renewed complacence, and, begging Captain
Delaware to be seated, he listened to him calmly and good
humouredly, while he spoke of the cause of his coming. He then
read attentively the first instructions for the annuity deed, and
returning the paper, fell--or affected to fall--into deep thought.
"Why, this certainly does make a great difference," he replied at
length; "and I am sure, Captain Delaware, you will exculpate me
from any desire to take advantage either of an accident or a
misfortune. My plan through life has been to do clear and simple
justice to all, and never to fall into the absurd error of mingling all
the feelings of private life with matters of business. Matters of
business should be transacted as matters of business, and without
the slightest regard to whether you be my cousin or a perfect
stranger. I can be generous when it is necessary, as well as other
men; but you applied to me not on a point of generosity, but on a
point of right and of justice, and therefore in that light did I consider
and decline your last proposal. In the same light do I consider your
present statement; but the paper you have produced, according to
my present views, so far alters the question, that without returning
you any direct answer at present, I will, in going out, call upon my
solicitor, consult with him, and, if you will see him to-morrow at
eleven o'clock, he shall tell you my final views, and, depend upon it,
they shall be those of substantial justice."

Captain Delaware was somewhat disappointed; for, from the first


impression which the production of the paper he had shown Lord
Ashborough, had made upon that nobleman, he had concluded that
the matter would be settled at once. He saw, however, that it would
be useless to press the subject farther at the time; and, after
promising to spend his days, though not his nights, at the house of
his noble kinsman, during his stay in London, he left him in
possession of the library.

Lord Ashborough almost immediately after mounted his horse,


and rode slowly on down all those filthy streets and long, which
conduct to Clement's Inn; in one of the dark and dusty staircases of
which, stinking of parchment and red tape, he met the identical Mr.
Peter Tims, of whom he was in search, and who led him instantly
into the penetralia. Their conversation was keen and long, but a few
sentences of it will be sufficient here. After relating Captain
Delaware's visit, the earl demanded eagerly, "Now, Mr. Tims, can the
matter be done? Have you seen to it?"

"I have, my lord, and it can be done," replied the lawyer. "I have
this morning been at the house of Messrs. Steelyard and Wilkinson.
Both partners are out of town, but their head clerk was there, and I
have made the following arrangement with him"----

"You have not compromised my name, I hope," interrupted the


earl.

"Not in the least, my lord," replied the other. "I explained to the
clerk that you would sell out at this moment to a great
disadvantage--that fourteen days would in all probability alter the
position of affairs--and that therefore your lordship would give a bill
at that date for the ten thousand pounds which you were to pay
them for Mr. Beauchamp.

"But how will that forward the matter?" demanded the earl. "It
will seem as if I were shuffling with my nephew concerning his
money matters, and not promote the other purpose."

"Your pardon, my lord--your pardon!" cried the lawyer. "You shall


demand of Sir Sidney Delaware to give you bills for the whole sum at
a fortnight's date, and give him up the annuity deed at once, and we
will arrange it so that you shall be out of town when the draft on you
becomes due, so as to stop the ten thousand pounds at the very
nick."

"Ay, but Harry will write up to know whether it be paid!" said the
earl.

"I will write to him as soon as you have given the bill, my lord,
telling him that the money is paid," answered the lawyer; "and I will
direct the letter to his house in John Street, to be forwarded. I have
a good excuse for writing, in regard to this business of the valet he
kicked down stairs--so there will be no suspicion."
"You know that he is a good man of business, Mr. Tims," replied
the earl, doubtingly. "Do you think he will take your word without
writing to enquire?"

"Oh yes, my lord!" answered the lawyer boldly. "You know your
own plans, and therefore think he may suspect them. That is the
way with all gentlemen, when they first do any little business of this
kind. They always fancy that other people know that we are wanting
to keep them in the dark. Remember Mr. Beauchamp has no
suspicion.--He does not know that you know where he is.--He is not
aware that you have heard he is going to squander away his money
at all; still less, that you are good enough to take such pains to
prevent him. He will believe it at once, that the money is paid, and
will simply give a draft for it on Messrs. Steelyard and Wilkinson
when the money is wanted. Besides, from all I can learn, although
he be in general a good man of business enough, I hear he has got
hold of one of those pieces of business that put every thing else out
of a man's head altogether."

"What do you mean, sir?" demanded the earl, in a strong tone of


aristocratical pride; for there was a sort of sneer upon the
countenance of Mr. Tims, which he did not at all admire, coupled
with the mention of his rich nephew--and here, be it remarked, that
it made a great difference in Lord Ashborough's estimation, whether
the person spoken of was a rich or a poor nephew. He had a sort of
indescribable loathing towards poverty, or rather towards poor
people, which was only increased by their being his relations. He
hated poverty--he could not bear it--in his eyes it was a disease--a
pestilence--a vice; and therefore--although, had his nephew been
poor, Mr. Tims might have sneered at him to all eternity--as he was
rich, Lord Ashborough felt very indignant at the least want of
reverence towards him. The tone in which he demanded, "What do
you mean, sir?" frightened Mr. Tims, who hastened to reply, that he
had heard from his respected and respectable relative in the country,
that the Mr. Burrel who had proposed to lend the money to Sir
Sidney Delaware, was now continually at Emberton Park; and that it
was very well understood in the country that he was to be married
immediately to Miss Delaware.

Lord Ashborough gazed in the face of the lawyer, with that


mingled look of vacancy and horror, which we may picture to
ourselves on the countenance of a person suddenly blinded by
lightning. When he had collected his senses, it was but to give way
to a more violent burst of rage, and, with clenched hands and teeth,
he stamped about the office of the attorney, till the clerks in the
outer room began to think that he was breaking the hard head of
their master against the floor. A few words, however, served to give
vocal vent to his fury. "The hypocritical, artful, despicable race of
beggarly fortune-hunters!" he exclaimed; and, turning out of Mr.
Tims's office, impelled by the sole impetus of passion, he was
standing by his horse almost ere the attorney knew he was gone.
The groom held the stirrup tight, and Lord Ashborough had his foot
on the iron, when cooler thoughts returned, and, walking back to
the chambers, he again entered the lawyer's room.

"Do all that you proposed, Mr. Tims," he said; "get the bills--
retard the payment--arrest the old reptile--manage it so that he may
not get bail; and the day you lodge him in the King's Bench--if it can
be done--you receive a draft for a thousand pounds.--They must be
crushed, Mr. Tims," he continued, grasping him tight by the arm;
"they must be crushed--ground down into the earth--till their very
name be forgotten;--but mark me," he added, speaking through his
set teeth--"mark me--if you let them escape, my whole agency and
business goes to another for ever."

"Oh! no fear, my lord, no fear!" replied Mr. Tims, in a sharp,


secure tone, rubbing his little, fat, red hands, with some degree of
glee. "No fear, if your lordship will consent to leave it to my
guidance.--But I will send for a bill stamp, and we will draw up the
bill directly, send it to Messrs. Steelyard and Wilkinson, and then I
will give due notice to Mr. Beauchamp that the money is paid--which,
indeed, it may be said to be, when your lordship has given your bill
for it--you know."

"I care not, sir!" exclaimed Lord Ashborough, vehemently,


"whether it may be said to be so or not. My nephew must be saved
from this cursed entanglement, by any means or all means. I will do
my part--see that you do yours. Crush these mean-spirited vipers,
somehow or another, and that as soon as may be;--but mind," he
added more quietly, "mind, you are to do nothing beyond the law!"

"I will take care to do nothing that the law can take hold of,"
replied the lawyer. "But you cannot think, my lord, how many things
may be done lawfully when they are done cautiously, which might
treat one with a sight of New South Wales, if they were to be
undertaken without due consideration--but I will send for the bill, my
lord."

The bill was accordingly sent for, drawn, and signed by Lord
Ashborough; and the attorney, after having despatched it to Mr.
Beauchamp's solicitor, wrote to that gentleman himself a letter, upon
the business to which he had referred, while speaking to Lord
Ashborough; and in a postscript, mentioned that he had handed
over to his agents a note for ten thousand pounds, on behalf of Lord
Ashborough. That nobleman stood by while all this proceeding was
taking place, and marked, with a well pleased smile, the double
language of the lawyer, and the quiet and careless manner in which
he contrived to offer a false impression in regard to the payment of
the money. When all was concluded, he paced slowly to the vacant
park, calmed his disturbed feelings by a quiet ride round its dusty
roads, and then returned with renewed self-command, to shower
upon William Delaware civilities, in proportion to his increased
detestation.
CHAPTER XIII.

Oh, if people would but take as much pains to do good as they


take to do evil--if even the well-disposed were as zealous in
beneficence, as the wicked are energetic in wrong--what a pleasant
little clod this earth of ours would be, for us human crickets to go
chirping about from morning till night!

The Right Honourable the Earl of Ashborough could think of but


one thing; and what between the active working of his own brain,
and the unceasing exertion of the pineal gland of Peter Tims, Esq.,
following keenly the plans and purposes which we have seen them
communicating to each other, the scheme for ruining the family at
Emberton was brought to that degree of perfection which rendered
its success almost certain. Mr. Tims, indeed, did wonder that the
noble earl had forgotten to propose to him any plan for detaining Sir
Sidney Delaware in prison after his arrest, and for consummating the
persecution so happily begun. He concluded that it had slipped his
lordship's memory; but, as he foresaw that, of course, Mr.
Beauchamp would immediately come forward to liberate the
baronet, and clear him of his embarrassments, Mr. Tims revolved a
thousand schemes for entangling him still more deeply, in order to
be found prepared as soon as his noble patron should apply to him
for assistance on this new occasion.

In truth, however, Lord Ashborough had calculated all; and from


what he had formerly known of Sir Sidney Delaware, as well as from
what he had lately heard of his impaired constitution, he felt assured
that even three or four days of imprisonment for debt would
terminate either life or reason, and thus leave his vengeance and his
hatred sated to the full.
It must not be always supposed that the motives and the feelings
which are here stated, in what is vulgarly called black and white,
appeared in their original nakedness before the minds of the various
actors in this my little drama. On the contrary, they came before
their master's eyes, like poor players on the stage, robed in
gorgeous apparel that little belonged to them. Revenge flaunted
away before the eyes of Lord Ashborough, clothed in princely purple,
and calling itself noble indignation. Mortified vanity, and mean
delight in wealth, tricked out in silks and satins, called themselves
honest scorn for deceivers, and careful consideration for his
nephew's interest, "and so they played their part;" while deadly
enmity, which would have acted murder, had it dared, now mocked
the Deity, and impiously assumed the name of retributive justice.

Nevertheless, there was in the bosom of Lord Ashborough at least


so much consciousness that all this was but a pageant, that he
found it necessary to redouble the careful guard he had put upon his
feelings towards Captain Delaware; and though he came back to
dinner meditating the destruction of his race and family, he
showered on the young sailors head civilities which might have
raised doubts had he dealt with one of the suspicious. Captain
Delaware, however, was not one of the suspicious. He had not
acquired the quality of suspiciousness in any of the three ways by
which it reaches the human heart--neither by the consciousness of
evil designs in his own breast, by experience of the world's
baseness, or by the exhortations of others. He was susceptible
indeed, and easily perceived when a slight was intended, or when
the least approach to scorn was felt towards him or his; but deeper
and blacker feelings escaped his observation, if covered by even a
slight disguise. In the present instance he was completely deceived.
His drive out with his fair cousin in the morning had proved so
delightful, that he began to doubt the efficacy of the water of the
prior's fountain, and to feel that many such drives might make him
either very happy, or very much the contrary. But the kind attention
of Lord Ashborough, his changed demeanour, and the hopes to
which it gave rise, were all sources of unmixed pleasure. The
evening passed away in delight; and when, on visiting Mr. Tims next
morning, he found that he was prepared to concede every thing that
he desired, on the simple formality of his father giving a bill at a few
days' date for the money, his satisfaction was complete. Nor was it
the less so, that the necessity of awaiting an answer to his letter,
communicating these tidings, and of obtaining his father's signature
to the bill, obliged him, whether he would or not, to enjoy the
society of Maria Beauchamp for at least two days longer.

On the part of that young lady herself, no dislike was felt to her
cousin's society--every one else was out of town--she had no one
with whom she could dance, or flirt, or talk, and still less any one to
whom she could communicate any of the deeper and better feelings
which formed the warp of her character, and across which the
threads of a sparkling sort of levity were intimately woven. With
Captain Delaware she did all but the first, and probably she would
have danced too, had minuets still been in vogue. She laughed, she
talked, she jested; and there was a sort of simple candour about his
nature, together with fine feelings and gentlemanly habits,
preserved, fresh and unadulterated, by a life spent either on the
green waters or in the green fields--which altogether wooed forth
those points in her own character, which as things most estimable,
lay hid in the deeper casket of her heart.

In short, the two days that followed were two very pleasant days
indeed; and it was almost with a sigh that Captain Delaware opened
his father's letter, which arrived at the end of them, and found the
bills duly signed. Mr. Tims had before told him, that he had made the
money payable at Emberton, in order to save him or his father the
trouble of coming or sending again to London. That excuse,
therefore, for either prolonging his stay or returning, was not to be
had; and, even if it had still been ready, the lawyer also informed
him gratuitously, that Lord Ashborough's motive for settling the
matter in the manner proposed, was in order to spare himself all
correspondence in the country, to which he was immediately about
to retire for the remainder of the year. The simple fact was, that Mr.
Tims--with the same over anxiety of which he had accused Lord
Ashborough to remove all suspicion of a latent motive--had assigned
these causes for his noble patron's conduct, simply to account
reasonably for his having demanded a bill for the money, payable at
Emberton, instead of following the usual legal routine in such cases,
accepting the redemption money when ready, and then cancelling
the deed. But Captain Delaware, with constitutional susceptibility,
instantly concluded that the whole was intended as a hint to him,
that any farther intimacy was not desired.

He could not feel indignant, because he felt that he had no right


to demand a continuance of the communication which had been
accidentally created between himself and the family of his wealthy
cousin; but he determined at once to show that there was no
necessity for such warnings; and, after having pleaded other
engagements, in order to absent himself from his cousin's house
during the rest of his stay in London, he took his place in the
identical stage which had whirled him down to Emberton on the
preceding occasion. He did not, however, in that sort of burning at
the heart which people feel on such occasions, neglect to take all
those steps which, to the best of his judgment, were necessary to
secure his father, and to conclude the business on which he had
come to London. On the contrary, he demanded and received, by
the hands of Mr. Tims, an acknowledgement, on the part of Lord
Ashborough, that a promissory-note had been given by Sir Sidney
Delaware for the sum of twenty-five thousand pounds, which, when
duly taken up, would be received as a full and due redemption of the
annuity chargeable upon the Emberton estate.

When all this was concluded, and he had eaten in melancholy


wise of the dinner which the people of the pseudo hotel at which he
lodged, set before him, in that den of congregated discomforts, a
public coffee-room--when he had done this, and taken an idle walk
round the black thing that spits water by table-spoonfuls nearly
opposite to Devonshire House, for the purpose of digesting his
dinner and his vexation, he could not refrain; but returning home--or
rather to the place of his dwelling for the time--he dressed and
walked to Grosvenor Square.

Lord Ashborough was in his library; Miss Beauchamp was alone--


somewhat in low spirits, too, and looking none the worse for being
so. She was in one of those moods in which a man may make a
great deal of a woman in a short time--if he knows how--but,
unhappily, Captain Delaware did not know how. He talked
sentimentally, and she talked sentimentally; and they made tea
between them, and poured it out and drank it--but it all came to
nothing--otherwise Maria Beauchamp might, perhaps, have been
William Delaware's wife before the end of the volume. Never did a
man who was bred and born a sailor miss stays so completely as
Captain Delaware did; and just when, towards the close of the
evening, he was making up his mind to say something sensible and
pertinent, in came Lord Ashborough, and the whole went to the--
budget.

Within half an hour after, William Delaware was on his way to his
hotel, and in the yellow of the next morning, he was once more
rolling away, to join the coach for Emberton. His journey was as dull
as it well could be. Two quaker ladies occupied one seat, and a deaf
man shared the other. Therefore--as it is a very laudable object to
wind up all sorts of matters here, in such a manner as to enable the
courteous reader to have done with the book at the end of this
volume, and to imagine, if he like, that the story is finished, when in
fact it is not begun--we shall give one paragraph to Mr. Tims, while
Captain Delaware rolls on.

The worthy and beneficent lawyer, full of zeal in the service of his
patron, set boldly to work to accomplish the object in view, and
added so many thoughtful means and contrivances to support those
which we have already seen him propose, that, at the end of eight
days, there was hardly a human possibility of his prey escaping him.
As, in some instances, he thought fit to prepare engines which went
a little beyond the clear limit of the law, he took good care to add a
safety valve for himself, by cautiously mingling Lord Ashborough's
name with all those particular matters which were most delicate and
dangerous, and thus insuring the whole power and influence of that
nobleman's rank and fortune to shield him, even if the blame itself
did not fall solely on the earl. He wrote, too, to his uncle, Mr. Tims,
at Ryebury, directing him on no account to advance money to the
gentleman calling himself Mr. Burrel, who was, in fact, Lord
Ashborough's nephew; and he added many a hint and caution,
calculated to make the miser of Ryebury throw every impediment in
the way of a liquidation of the debts on Sir Sidney Delaware's estate.
At the same time, a vague threat of Lord Ashborough's displeasure,
in case of recusancy, was held out; and by the end of the week, Mr.
Tims, as we have said, sat down perfectly certain of having drawn
those spider toils round the family of Emberton, which it would be
impossible for them to evade.

In the mean time, William Delaware arrived at Emberton Park,


and found every thing precisely as he had left it. Burrel's visits were
still continuing daily. Indeed--during his son's absence, which
occasioned a sort of gap in the things to which Sir Sidney Delaware
was accustomed--the baronet had more than ever sought the
presence of Mr. Burrel to supply the want.

The affection of Burrel for Blanche Delaware, seemed exactly the


same--if any thing, there was perhaps an additional shade of
tenderness in his manner, towards her, which for a moment caused
Captain Delaware to believe, that his sister had been made
acquainted with her lover's feelings. But it was not so. On the
contrary, during her brother's stay in London, Blanche had lost many
of those pleasant hours which she had before spent in Burrel's
society. Her long rambles with him through the park and the
neighbouring country, were of course at an end for the time; and,
although Mrs. Darlington took a house in the immediate vicinity, and
pressed Miss Delaware to join her there for a few days--though
Blanche, perhaps, might feel that there she could, with propriety,
hold freer intercourse with one who had obtained so strong a hold of
her affection, yet filial duty overcame even the wish, and she refused
to leave her father during her brother's absence.

Captain Delaware's return, therefore, was a matter of joy and


delight to every one; and immediately after having heard all those
viva voce particulars, which a letter could not convey, Sir Sidney
Delaware visited Mr. Tims, who assured him that the money would
be ready full twenty-four hours before the stipulated time, and
instantly began to prepare the mortgage which was to secure the
sum to the lender. The tidings were, of course, communicated to
Blanche, whose young heart beat high, to think of even a part of the
dark cloud which had so long overshadowed her dear father's fate,
being blown away for ever. If, too, a thought crossed her mind, in
regard to her own situation, and the improvement of her relative
position towards him by whom she was beloved, who shall say a
word of blame? It was but nature; and perhaps that thought might
take away the only thorn that she saw encumbering the fate before
her. All eyes sparkled--all hearts beat high at Emberton. The news
insensibly was spread abroad--The prospects of the Ruined Family
seemed brightening--Those to whom they had been kind, even in
their adversity, blessed the day that saw their changing fortune--and
those who had despised their poverty, began to bow down and
worship, now that the storms no longer hung above them.

Sir Sidney Delaware walked with a firmer step. His son felt that
one-half of the load of life was gone, and Blanche raised her eyes
timidly to meet those of Burrel, as if there had been some secret
voice which told her, that--how, or why, she knew not--all the
happiness that was growing up around them, was of his planting.

Oh, deceitful Fortune! why wilt thou often smile so sweetly, while
opening thy store of evils to pour upon the devoted head!
END OF VOLUME FIRST.

EDINBURGH:

M. AITKEN, 1, ST. JAMES'S SQUARE.


*** END OF THE PROJECT GUTENBERG EBOOK DELAWARE; OR,
THE RUINED FAMILY. VOL. 1 ***

Updated editions will replace the previous one—the old editions will
be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States copyright in
these works, so the Foundation (and you!) can copy and distribute it
in the United States without permission and without paying
copyright royalties. Special rules, set forth in the General Terms of
Use part of this license, apply to copying and distributing Project
Gutenberg™ electronic works to protect the PROJECT GUTENBERG™
concept and trademark. Project Gutenberg is a registered trademark,
and may not be used if you charge for an eBook, except by following
the terms of the trademark license, including paying royalties for use
of the Project Gutenberg trademark. If you do not charge anything
for copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such as
creation of derivative works, reports, performances and research.
Project Gutenberg eBooks may be modified and printed and given
away—you may do practically ANYTHING in the United States with
eBooks not protected by U.S. copyright law. Redistribution is subject
to the trademark license, especially commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the free


distribution of electronic works, by using or distributing this work (or
any other work associated in any way with the phrase “Project
Gutenberg”), you agree to comply with all the terms of the Full
Project Gutenberg™ License available with this file or online at
www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand, agree
to and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to abide by all
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg™ electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg™ electronic work and you do not agree to be
bound by the terms of this agreement, you may obtain a refund
from the person or entity to whom you paid the fee as set forth in
paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only be


used on or associated in any way with an electronic work by people
who agree to be bound by the terms of this agreement. There are a
few things that you can do with most Project Gutenberg™ electronic
works even without complying with the full terms of this agreement.
See paragraph 1.C below. There are a lot of things you can do with
Project Gutenberg™ electronic works if you follow the terms of this
agreement and help preserve free future access to Project
Gutenberg™ electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law
in the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name associated
with the work. You can easily comply with the terms of this
agreement by keeping this work in the same format with its attached
full Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.

1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears,
or with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1

You might also like