Frequently-Asked Questions
General Questions
-
What is the UnboundID LDAP SDK for Java?
-
What advantages does the UnboundID LDAP SDK have over other LDAP APIs?
-
How can I get the LDAP SDK?
-
Where can I find the documentation for the LDAP SDK?
-
Does the LDAP SDK work with any LDAP directory server?
-
What LDAP specifications does the LDAP SDK support?
-
Does the LDAP SDK support LDAPv2?
Licensing and Legal Questions
-
Is the LDAP SDK free to use?
-
Can I redistribute the LDAP SDK with my application? What do I need to
include?
-
What license does the LDAP SDK use?
-
Why is the LDAP SDK available under two different licenses? Which should I
choose for my application?
-
Is the LDAP SDK open source?
-
Can the LDAP SDK be used in closed source or proprietary applications?
-
Can the LDAP SDK be used in applications which are intended only for private
use and will not be redistributed?
Support Questions
-
Can I get support for the LDAP SDK?
-
How can I ask questions, report bugs, or provide feedback?
-
How can I keep up to date with new releases and the latest news about the LDAP
SDK?
-
How can I debug problems in which the LDAP SDK isn't behaving as I expected?
API Questions
-
Is the LDAP SDK suitable for production use?
-
Is backward compatibility maintained between releases?
-
Is the LDAP SDK threadsafe?
-
Is the LDAP SDK extensible?
-
How can I determine the version number for the LDAP SDK build that I have?
Usage Questions
-
Where can I find examples that demonstrate how to use the LDAP SDK?
-
How do I create a connection to an LDAP directory server?
-
How do I create secure connections?
-
How do I perform searches?
-
How do I modify entries?
-
How do I add new entries?
-
How do I use connection pools?
-
How do I process asynchronous operations?
-
How do I read and write LDIF files?
What is the UnboundID LDAP SDK for Java?
The UnboundID LDAP SDK for Java is a fast, powerful, user-friendly, and completely
free Java API for communicating with LDAP directory servers. It is an alternative
to other APIs like JNDI, the Netscape Directory SDK for Java, and JLDAP. If you
need to perform LDAP communication (or perform other directory-related processing
like reading and writing LDIF files), then this is the API that you should be
using.
What advantages does the UnboundID LDAP SDK have over other LDAP APIs?
The UnboundID LDAP SDK for Java provides a number of advantages over other
Java-based LDAP APIs. See this document
for a detailed overview of the advantages that our LDAP SDK provides over the
alternatives, including a single-page
comparison that summarizes many of the
benefits.
How can I get the LDAP SDK?
The UnboundID LDAP SDK for Java is available for download at
http://www.unboundid.com/products/ldapsdk/.
Where can I find the documentation for the LDAP SDK?
The LDAP SDK documentation (including this FAQ) is included with the LDAP SDK in
the "docs" directory. The documentation for the latest release is also
available online at
http://www.unboundid.com/products/ldapsdk/docs/.
Does the LDAP SDK work with any LDAP directory server?
Yes. The UnboundID LDAP SDK for Java supports the standard LDAP protocol, and
will work with any directory server that supports LDAPv3. Note that LDAP is an
extensible protocol and there are a number of optional features. Not all
directory servers support all of the features offered by the LDAP SDK, and some
directories may provide controls, extended operations, or SASL mechanisms not
explicitly supported by the LDAP SDK (although the LDAP SDK is also extensible and
it is possible to add support for custom controls, extended operations, and SASL
mechanisms that it doesn't provide out of the box).
What LDAP specifications does the LDAP SDK support?
The LDAP SDK provides full support for the core LDAPv3 protocol as described in
RFC 2251 and updated in
RFC 4511. It also supports a
number of controls, extended operations, and other capabilities described in a
number of other RFCs and IETF drafts. See
this page for information about some
of the specifications supported by the LDAP SDK.
Does the LDAP SDK support LDAPv2?
No, it does not. LDAPv2 is an older version of the protocol with a much more
limited feature set than LDAPv3 and using a somewhat arcane encoding. It was
declared "historic" by
RFC 3494 in 2003 and shouldn't
be used for new development.
Is the LDAP SDK free to use?
The Standard Edition of the UnboundID LDAP SDK is completely free to use and
redistribute by itself or under the terms of the
GPLv2, the
LGPLv2.1, or the
UnboundID LDAP SDK Free Use License.
Commercial support and indemnification are available for a fee, but are not
required to be able to use the SDK.
Can I redistribute the LDAP SDK with my application? What do I need to
include?
Yes. You can redistribute the UnboundID LDAP SDK for Java with your application.
The only requirements are that you include the appropriate license file (one or
more of the GPLv2, the
LGPLv2.1, or the
UnboundID LDAP SDK Free Use License,
depending on which you have decided to use) along with the
unboundid-ldapsdk-se.jar file.
What license does the LDAP SDK use?
The UnboundID LDAP SDK for Java Standard Edition is available under three
licenses: the GNU General Public License version 2
(GPLv2), the GNU Lesser General Public License
version 2.1 (LGPLv2.1), and the
UnboundID LDAP SDK Free Use License.
Why is the LDAP SDK available under multiple licenses? Which should I
choose for my application?
We want to make it as easy and painless as possible to use the UnboundID LDAP SDK,
so we have three licenses that should cover a broad range of possible use cases.
The GPLv2 is a popular OSI-approved open source
license, and if your application is licensed under GPLv2 or a compatible license,
then you should choose this license.
The LGPLv2.1 is similar to the GPLv2, but it is
designed to be compatible with a wider range of licenses, including those for
proprietary or closed-source applications. If you wish to use the LDAP SDK under
an OSI-approved open source license but your license is not compatible with the
terms of the GPLv2, then you should choose this license.
The UnboundID LDAP SDK Free Use License
is not an OSI-approved open source license, but has been designed to be compatible
with a very broad range of applications. If you wish to use the LDAP SDK with a
license that is not open source and has fewer requirements than the GPLv2 or
LGPLv2.1, then you should choose this license. Note that you may not distribute a
modified version of the LDAP SDK under the terms of this license, although you may
create your own classes which extend classes or implement interfaces defined in
the LDAP SDK that have been marked with the "@Extensible" annotation
type.
If you do not believe that any of these licenses are suitable for your
application, then send an e-mail message to
ldapsdk-support@unboundid.com
to inquire about other options.
Is the LDAP SDK open source?
Yes. The Standard Edition is available under the
GPLv2 and
LGPLv2.1, which are OSI-approved open source
licenses. The full source for the LDAP SDK is available in the src.zip
file which is included in the SDK download.
The LDAP SDK is also available under the terms of the
UnboundID LDAP SDK Free Use License.
This is not an OSI-approved open source license, but should be fully compatible
with many existing open source licenses.
Can the LDAP SDK be used in closed source or proprietary applications?
Yes. The LDAP SDK may be used in closed source or proprietary applications under
the terms of either the LGPLv2.1 or the
UnboundID LDAP SDK Free Use License.
Can the LDAP SDK be used in applications which are intended only for private use
and will not be redistributed?
Yes. There are no restrictions on the use of the LDAP SDK in an application that
is for internal use only and will not be redistributed outside of your
organization. If you later decide to redistribute the application, then you may
only do so under the terms of the GPLv2, LGPLv2.1, or the UnboundID LDAP SDK Free
Use License.
Can I get support for the LDAP SDK?
Yes. Commercial support is available for purchase from UnboundID. This includes
providing patches to fix problems identified within the LDAP SDK, the ability to
request enhancements and additional functionality, and assistance in developing
applications which use the UnboundID LDAP SDK for Java. See the
LDAP SDK home page for
more information.
How can I ask questions, report bugs, or provide feedback?
The following options are available for submitting questions, comments, bug
reports, feature requests, or any other feedback for the LDAP SDK:
Assistance will be on a best-effort basis, and priority will be given to customers
with commercial support contracts.
How can I keep up to date with new releases and the latest news about the LDAP
SDK?
You can join the
ldap-sdk-announce@lists.sourceforge.net
mailing list, which will be used to provide notification of new releases and
significant updates.
How can I debug problems in which the LDAP SDK isn't behaving as I
expected?
The LDAP SDK provides access to debugging information using the standard Java
logging framework. It can be enabled either programmatically or by setting Java
properties. See the Debugging SDK
Operations page for information about accessing enabling and accessing
debugging capabilities.
Is the LDAP SDK suitable for production use?
The current version of the LDAP SDK is very stable and is suitable for use in
production applications. We have developed an extensive test suite specifically
for the LDAP SDK, and it also undergoes significant testing as it is used in our
other products.
Is backward compatibility maintained between releases?
Whenever possible, we will avoid making incompatible changes in the LDAP SDK. In
fact, we have unit tests in place which compare the current API against that of
previous releases to ensure that no incompatibilities have been introduced.
However, if there is sufficient justification, we reserve the right to break
backward compatibility under the following conditions:
-
For any new additions to the API, we reserve the right to make incompatible
changes within the same minor version if there is sufficient justification. For
example, if a new class is added in version 1.2.3, then that API may be changed
in incompatible ways in subsequent 1.2.x releases, but it should be considered
stable in 1.3.x and later releases.
-
For any established APIs, we reserve the right to make incompatible changes
between major versions if there is sufficient justification. For example, it is
possible that if there is a strong enough reason to do so then we may change
the interface for a class between 2.x.y and the 3.0.0 releases.
In the event that we do make such an incompatible change, it will be documented in
the release notes for the new version.
Is the LDAP SDK threadsafe?
The LDAP SDK has been designed to be highly concurrent and scalable. As much of
the LDAP SDK has been made threadsafe as is possible to do without adversely
impacting performance or flexibility. Connections can be used to process multiple
requests at the same time as long as none of them does something that will impact
the state of that connection (e.g., tries to close or re-establish the connection,
tries to perform a bind, or tries to initiate StartTLS negotiation).
The com.unboundid.util.ThreadSafety annotation type may be used to
determine whether a given class or interface is threadsafe. All public classes
and interfaces in the LDAP SDK should be marked with this annotation type to
indicate whether instances may be safely accessed via multiple threads at the
same time. This annotation type appears in the generated javadoc documentation,
and for special cases in which a class may be partially threadsafe (like the
LDAPConnection caveats mentioned above) the class-level documentation
provides additional information about how such objects may be used concurrently.
Is the LDAP SDK extensible?
The LDAP SDK does provide various forms of extensibility. In particular, it
contains a number of non-final classes that may be extended to provide additional
functionality. It is possible to define custom controls, extended requests and
results, SASL mechanisms, matching rules, server sets, and command-line tools by
extending classes provided by the LDAP SDK.
Similarly, the LDAP SDK provides a number of interfaces that may be implemented
by third-party code for various purposes, including notification of certain types
of events or messages received from the server, establishing connections for
following referrals, and transforming entries read from LDIF files.
However, the LDAP SDK also includes a number of interfaces and non-final classes
that are intended to be extended only by code within the LDAP SDK itself and not
by third-party code outside of the LDAP SDK. To help developers distinguish which
classes and interfaces may be extended by external code and which are only allowed
for classes in the LDAP SDK itself, all public interfaces and all non-final public
classes have been updated to include an annotation which indicates whether new
implementations may be provided in third-party code. If a class or interface
contains the @Extensible annotation, then it is safe for third-party code
to extend. Conversely, if a class or interface contains the
@NotExtensible annotation then it is not intended to be implemented by
code outside of the LDAP SDK (although objects of that type may be used by
third-party code). These annotations are visible in the generated Javadoc
documentation.
How can I determine the version number for the LDAP SDK build that I have?
There are a number of ways to determine the version of the LDAP SDK that you are
using:
-
The zip file in which the LDAP SDK was downloaded will include the version
number. For example, the zip file containing files for the 1.2.3 release will
be named "unboundid-ldapsdk-1.2.3-se.zip".
-
The javadoc documentation provided with the
LDAP SDK will include the version number in the page title, as well as on the
initial page summarizing the packages included in the SDK. For example, the
page title for javadoc documentation for the 1.2.3 release will be "UnboundID
LDAP SDK for Java 1.2.3 (Standard Edition)".
-
You may issue the command "java -jar unboundid-ldapsdk-se.jar" to
write version information for the LDAP SDK to standard output.
-
The com.unboundid.ldap.sdk.Version class provides a number of constant
fields that may be used to obtain information about the SDK version.
Where can I find examples that demonstrate how to use the LDAP SDK?
The UnboundID LDAP SDK for Java comes with many examples demonstrating its use.
The following kinds of examples are available:
-
The examples directory in the zip archive
in which the LDAP SDK was downloaded contains source for complete programs that
demonstrate the use of various APIs within the LDAP SDK, and may also serve as
useful utilities for general use.
-
The Getting Started Guide provides
discussion and code snippets demonstrating a number of components within the
LDAP SDK.
-
The javadoc documentation provides a large
number of examples in the class-level documentation for classes throughout the
LDAP SDK.
How do I create a connection to an LDAP directory server?
The com.unboundid.ldap.sdk.LDAPConnection class provides the main API for
communicating with LDAP directory servers. To create a new
LDAPConnection object, establish the connection, and authenticate to the
directory server, you can use code like:
LDAPConnection connection = new LDAPConnection();
connection.connect("server.example.com", 389);
connection.bind("uid=john.doe,ou=People,dc=example,dc=com", "password');
You can also create the connection and establish it at the same time, like:
LDAPConnection connection = new LDAPConnection("server.example.com", 389);
connection.bind("uid=john.doe,ou=People,dc=example,dc=com", "password');
And you can also do all three in a single step:
LDAPConnection connection = new LDAPConnection("server.example.com", 389,
"uid=john.doe,ou=People,dc=example,dc=com", "password");
How do I create secure connections?
The LDAP SDK supports the use of SSL and StartTLS for secure communication. SSL
should be used to create connections that are always secure (and will generally
use a different port from that used for LDAP communication, typically port 636).
StartTLS may be used to add security to an existing insecure connection (and will
communicate over the same port used for insecure LDAP communication, typically
port 389). In both cases, the com.unboundid.util.ssl.SSLUtil class may
be used to help configure the underlying security layer.
In order to create an SSL-based connection, you should provide a custom socket
factory when establishing the connection. For example, the following code may be
used to establish an SSL-based connection that will blindly trust any certificate
that the Directory Server provides:
SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory();
LDAPConnection connection = new LDAPConnection(socketFactory,
"server.example.com", 636);
In order to use the StartTLS extended operation to add encryption to an existing
connection, you will need to use the
com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest and you should
provide a custom SSLContext to use when processing. For example:
SSLUtil sslUtil = new SSLUtil(new TrustAllTrustManager());
SSLContext sslContext = sslUtil.createSSLContext();
ExtendedResult extendedResult = connection.processExtendedOperation(
new StartTLSExtendedRequest(sslContext));
if (extendedResult.getResultCode() == ResultCode.SUCCESS)
{
// The connection is now secure.
}
else
{
// The StartTLS negotiation failed for some reason. The connection can no
// longer be used.
connection.close();
}
How do I perform searches?
There are two primary ways in which you can perform searches in a synchronous
manner. For simple searches that are expected to match a small number of
entries, you can allow the SDK to capture all of the entries in a list that it
will make available in the SearchResult object that is returned.
For example:
SearchResult searchResult = connection.search("dc=example,dc=com",
SearchScope.SUB, "(uid=john.doe)");
System.out.println(searchResult.getEntryCount() + " entries returned.");
for (SearchResultEntry e : searchResult.getSearchEntries())
{
System.out.println(e.toLDIFString());
System.out.println();
}
For searches that are expected to match a large number of entries, or that may
take a long time to complete and you want to ensure that entries are processed as
quickly as they are returned, then you can implement the
com.unboundid.ldap.sdk.SearchResultListener interface. This interface
contains methods that will be called whenever a search result entry or reference
is returned by the server for the search. The LDAPConnection.search
method will still block until the search has completed. For example:
// The searchEntryReturned method of the provided searchListener will be
// invoked for each entry returned. The searchReferenceReturned method of the
// searchListener will be invoked for each reference returned. The call to
// the LDAPConnection.search method will not return until the search has
// completed, and the entries will not be available in the result, although the
// number of entries returned will still be included.
SearchResult searchResult = connection.search(searchListener,
"dc=example,dc=com", SearchScope.SUB, "(givenName=John)");
System.out.println(searchResult.getEntryCount() + " entries returned.");
How do I modify entries?
The com.unboundid.ldap.sdk.Modification class may be used to describe the
change or set of changes that should be made to a single attribute. A modify
operation may be processed using one or more modifications, like:
Modification modification = new Modification(ModificationType.REPLACE,
"description", "This is the new description for the user");
LDAPResult result = connection.modify(
"uid=john.doe,ou=People,dc=example,dc=com", modification);
As a convenience, it is also possible to process modifications using the LDIF
representation, with a separate value per line of the LDIF. For example:
LDAPResult result = connection.modify(
"dn: uid=john.doe,ou=People,dc=example,dc=com",
"changetype: modify",
"replace: description",
"description: This is the new description for the user");
How do I add new entries?
Entries can be added using a distinguished name and collection of attributes,
like:
Attribute[] attributes =
{
new Attribute("objectClass", "top", "person", "organizationalPerson",
"inetOrgPerson"),
new Attribute("uid", "john.doe"),
new Attribute("givenName", "John"),
new Attribute("sn", "Doe"),
new Attribute("cn", "John Doe")
};
LDAPResult result = connection.add("uid=john.doe,ou=People,dc=example,dc=com",
attributes);
As with the modify operation, add operations can be processed using the LDIF
representation of the entry to add. For example:
LDAPResult result = connection.add(
"dn: uid=john.doe,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: john.doe",
"givenName: John",
"sn: Doe",
"cn: John Doe");
How do I use connection pools?
The UnboundID LDAP SDK for Java provides support for connection pools that can be
used to maintain multiple connections to a directory server, or even multiple
connections spread across multiple directory servers. The easiest way to create a
connection pool is to provide an established (and optionally authenticated)
connection to use as the template for creating new connections and the initial and
maximum number of connections that should be maintained in the pool. For example:
LDAPConnection connection = new LDAPConnection("server.example.com", 389,
"uid=john.doe,ou=People,dc=example,dc=com", "password");
LDAPConnectionPool pool = new LDAPConnectionPool(connection, 1, 10);
As with traditional connection pool implementations, it is possible to check out
a connection, do something with it, and return it back to the pool, like:
LDAPConnection connection = pool.getConnection();
try
{
SearchResult searchResult = connection.search("dc=example,dc=com",
SearchScope.SUB, "(objectClass=*)");
// Do something with the result.
pool.releaseConnection(connection);
}
catch (LDAPSearchException lse)
{
// The search failed. See if the connection is still valid and either
// release it back to the pool or notify the pool that it is no longer valid
// so that it will create a new one in its place.
if (ResultCode.isConnectionUsable(lse.getResultCode()))
{
pool.releaseConnection(connection);
}
else
{
pool.releaseDefunctConnection(connection);
}
}
However, it is also possible to perform operations in the context of the
connection pool without the need to explicitly check out the connection and
perform all of the appropriate error handling. The LDAPConnectionPool
class implements the same interface (LDAPInterface) as the
LDAPConnection class, so it is possible to perform operations against
a pool in much the same way as with a single connection. For example, the
following is the logical equivalent to the above search:
SearchResult searchResult = pool.search("dc=example,dc=com", SearchScope.SUB,
"(objectClass=*)");
// Do something with the result.
How do I process asynchronous operations?
The LDAP SDK provides relatively simple interfaces that may be used to process
add, compare, delete, modify, modify DN, and search operations in an asynchronous
manner. In this case, the LDAP SDK will return control to the caller immediately
after sending the request to the server without waiting for the response. This
allows the client to perform other processing in the meantime, and it will be
notified when the response message(s) arrive for that operation.
This page describes
the process for performing asynchronous operations in the LDAP SDK.
How do I read and write LDIF files?
The com.unboundid.ldif package provides classes that may be used to read
and write entries and change records using the LDAP Data Interchange Format (LDIF)
syntax. The LDIFReader class can be used to read entries and change
records, and the LDIFWriter class can be used to write them. The
following code provides a simple example demonstrating the process that could be
used to read entries from one file and write them to another:
LDIFReader ldifReader = new LDIFReader("/path/to/source.ldif");
LDIFWriter ldifWriter = new LDIFWriter("/path/to/target.ldif");
while (true)
{
Entry entry = ldifReader.readEntry();
if (entry == null)
{
// There are no more entries to be read.
break;
}
ldifWriter.writeEntry(entry);
}
ldifReader.close();
ldifWriter.close();
|