# 故障排除提示

> 原文： [https://docs.oracle.com/javase/tutorial/jndi/ops/faq.html](https://docs.oracle.com/javase/tutorial/jndi/ops/faq.html)

以下是尝试运行使用 JNDI 类的成功编译程序时可能遇到的最常见问题。

* * *

1.  [没有初始背景](#1)
2.  [拒绝连接](#2)
3.  [连接失败](#3)
4.  [程序挂起](#4)
5.  [找不到名称](#5)
6.  [无法连接到任意主机](#6)
7.  [无法访问配置的系统属性](#7)
8.  [无法使用 CRAM-MD5](#8) 进行身份验证

* * *

。

_ 原因 _：您没有指定要用于初始上下文的实现。具体来说， [`Context.INITIAL_CONTEXT_FACTORY`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY)环境属性未设置为将创建初始上下文的工厂的类名。或者，您没有向程序提供由 `Context.INITIAL_CONTEXT_FACTORY` 命名的服务提供者的类。

_ 解决方案 _：将 `Context.INITIAL_CONTEXT_FACTORY` 环境属性设置为您正在使用的初始上下文实现的类名。有关详细信息，请参见[配置](index.html)部分。

如果设置了属性，那么确保类名没有错误输入，并且命名的类可用于您的程序（在其类路径中或安装在 `jre / lib / ext` 目录中 JRE）。 包括 LDAP，COS 命名，DNS 和 RMI 注册表的服务提供程序。必须安装所有其他服务提供程序并将其添加到执行环境中。

_ 原因 _：服务器不提供由 `Context.PROVIDER_URL` 环境属性标识的服务器和端口。也许某人已禁用或关闭运行服务器的计算机。或者，您可能错误输入了服务器的名称或端口号。

_ 解决方案 _：检查该端口上是否确实有服务器正在运行，并在必要时重新启动服务器。执行此检查的方式取决于您使用的 LDAP 服务器。通常，可以使用管理控制台或工具来管理服务器。您可以使用该工具验证服务器的状态。

_ 原因 _：服务器不响应 LDAP v3 连接请求。某些服务器（尤其是公共服务器）无法正确响应 LDAP v3，忽略请求而不是拒绝它们。此外，某些 LDAP v3 服务器在处理 Oracle 的 LDAP 服务提供程序自动发送的控件时遇到问题，并且通常会返回特定于服务器的故障代码。

_ 解决方案 _。尝试将环境属性`“java.naming.ldap.version”`设置为`“2”`。默认情况下，LDAP 服务提供程序尝试使用 LDAP v3 连接到 LDAP 服务器;如果失败，则使用 LDAP v2。如果服务器静默忽略 v3 请求，则提供程序将假定请求有效。要解决此类服务器，必须显式设置协议版本以确保服务器的正确行为。

如果服务器是 v3 服务器，则在创建初始上下文之前尝试设置以下环境属性：

```
env.put(Context.REFERRAL, "throw");

```

这将关闭 LDAP 提供程序自动发送的控件。 （有关详细信息，请查看 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/index.html)。）

_ 原因 _：如果您尝试执行会产生太多结果或需要服务器检查太多的搜索，某些服务器（尤其是公共服务器）将不会响应（即使是否定答案）条目以生成答案。这些服务器试图限制它们在每个请求的基础上花费的资源量。

或者，您尝试对不支持它的服务器/端口使用安全套接字层（SSL），反之亦然（也就是说，您尝试使用普通套接字与 SSL 端口通信）。

最后，由于负载过重或者由于某种原因根本没有响应，服务器要么响应得非常慢。

_ 解决方案 _：如果您的程序因服务器试图限制其资源的使用而挂起，请使用将返回单个结果或仅返回少量结果的查询重试您的请求。这将帮助您确定服务器是否处于活动状态。如果是，那么您可以扩大初始查询并重新提交。

如果您的程序由于 SSL 问题而挂起，那么您需要确定该端口是否为 SSL 端口，然后适当地设置 [`Context.SECURITY_PROTOCOL`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_PROTOCOL)环境属性。如果端口是 SSL 端口，则此属性应设置为`“ssl”`。如果它不是 SSL 端口，则不应设置此属性。

如果程序因上述原因而挂起，则 `com.sun.jndi.ldap.read.timeout` 属性可以方便地指定读取超时。此属性的值是一个整数的字符串表示形式，表示 LDAP 操作的读取超时（以毫秒为单位）。如果 LDAP 提供程序在该时间段内无法获得 LDAP 响应，则会中止读取尝试。整数应大于零。小于或等于零的整数表示没有指定读取超时，这相当于在收到响应之前无限等待响应。

如果未指定此属性，则默认为等待响应，直到收到响应。

 会导致 LDAP 服务提供商中止读取尝试。

。

_ 原因 _：初始化 LDAP 的初始上下文时，提供了根区别的名称。例如，如果将初始上下文的 `Context.PROVIDER_URL` 环境属性设置为`“ldap：// ldapserver：389 / o = JNDITutorial”`，并随后提供名称，如`“cn = Joe，c = us”`，然后传递给 LDAP 服务的全名是`“cn = Joe，c = us，o = JNDITutorial”`。如果这确实是您想要的名称，那么您应该检查您的服务器以确保它包含这样的条目。

此外，如果您提供不正确的可分辨名称以进行身份​​验证，Oracle Directory Server 将返回此错误。例如，如果将 [`Context.SECURITY_PRINCIPAL`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL)环境属性设置为`，则 LDAP 提供程序将抛出 [`NameNotFoundException`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameNotFoundException.html)“cn = Admin，o =教程“`和`”cn = Admin，o = Tutorial“`不是 LDAP 服务器上的条目。实际返回的 Oracle Directory Server 的正确错误应该是与身份验证相关的内容，而不是“找不到名称”。

_ 解决方案 _：验证您提供的名称是服务器上存在的条目的名称。您可以通过列出条目的父上下文或使用其他工具（如目录服务器的管理控制台）来执行此操作。

* * *

以下是尝试部署使用 JNDI 类的 applet 时可能遇到的一些问题。

_ 原因 _：您的 applet 未签名，因此它只能连接到加载它的机器。或者，如果 applet 已签名，则浏览器尚未授予 applet 连接到目录服务器计算机的权限。

_ 解决方案 _：如果你想允许 applet 连接到在任意机器上运行的目录服务器，那么你需要你的 applet _ 和 _ 签署所有 JNDI 您的 applet 将使用的 JAR。有关签名 jar 的信息，请参阅[签名和验证 JAR 文件](../../deployment/jar/signindex.html)。

_ 原因 _：Web 浏览器限制对系统属性的访问，如果您尝试读取它们，则抛出 `SecurityException` 。

_ 解决方案 _：如果您需要获取 applet 的输入，请尝试使用 applet params。

_ 原因 _：Firefox 禁止访问 `java.security` 软件包。 LDAP 提供程序使用 `java.security.MessageDigest` 提供的消息摘要功能来实现 CRAM-MD5。

_ 解决方案 _：使用 Java Plug-in。

* * *