开发使用 JNDI 的应用程序

对企业 Bean (EJB) Home 接口和其他工件 (例如数据源) 的引用将绑定到 WebSphere® Application Server 名称空间。 可以通过 Java™ 命名和目录接口 (JNDI) 获取这些对象。 在您可执行任何 JNDI 操作前,您需要获取初始上下文。 您可以使用初始上下文来查找绑定到该名称空间的对象。

有关此任务

在这些示例中,将使用特定于 WebSphere Application Server JNDI 上下文实现的功能部件的缺省行为。

WebSphere Application Server JNDI 上下文实现包含特殊功能部件。 JNDI 高速缓存增强同一对象上重复查找操作的性能。 名称语法选项提供名称语法的选项,一个优化为典型 JNDI 客户机,而一个优化为与 CosNaming 应用程序的互操作性。 大多数情况下,这些功能部件的缺省行为是首选的行为。 然而,有时您应该修改特定情况的行为。

JNDI 高速缓存和名称语法选项与 javax.naming.InitialContext 实例相关联。 要为这些功能部件选择选项,请设置 WebSphere Application Server 初始上下文工厂可识别的属性。 要设置初始上下文工厂可视的 JNDI 高速缓存或名称语法属性,请执行以下操作:

过程

  1. 可选: 配置 JNDI 高速缓存

    JNDI 高速缓存可大大增加 JNDI 查看操作的性能。 缺省情况下,启用 JNDI 高速缓存。 在大多数情况下,此缺省是需要的行为。 然而,在特定情况下,使用其他 JNDI 高速缓存选项。

    当查找对象时,本地高速缓存它们。 在高速缓存对象上的后继查找在本地解决。 然而,高速缓存内容可变成旧的。 此情况通常不是什么问题,因为您查询的大多数对象不会频繁更改。 如果您需要查询更改相对频繁的对象,更改 JNDI 高速缓存选项。

    JNDI 客户机可使用一些属性来控制高速缓存行为。

    您可设置属性:
    • 从命令行,输入实际字符串值。 例如:
      java -Dcom.ibm.websphere.naming.jndicache.maxentrylife=1440
    • jndi.properties 文件中,通过创建名为 jndi.properties 的文件,作为带有所期望属性设置的文本文件。 例如:
      ...
      com.ibm.websphere.naming.jndicache.cacheobject=none
      ...

      如果使用此技巧,请注意类路径中可能存在 jndi.properties 文件的其他实例,并且这些实例可能包含冲突属性设置。 属性设置按类装入器选择 jndi.properties 文件的顺序确定。 无法控制类装入器定位类路径中的文件时使用的顺序。 WebSphere Application Server 最初不包含或创建任何设置 com.ibm.websphere.naming.jndicache.cacheobject 属性的 jndi.properties 文件。

    • 在 Java 程序中,可以在使用在 com.ibm.websphere.naming.PROPS 文件中定义的 PROPS.JNDI_CACHE* Java 常量。 常量定义如下所示:
      public static final String JNDI_CACHE_OBJECT =
       "com.ibm.websphere.naming.jndicache.cacheobject";
      public static final String JNDI_CACHE_OBJECT_NONE      = "none";
      public static final String JNDI_CACHE_OBJECT_POPULATED = "populated";
      public static final String JNDI_CACHE_OBJECT_CLEARED   = "cleared";
      public static final String JNDI_CACHE_OBJECT_DEFAULT   =
       JNDI_CACHE_OBJECT_POPULATED;
      
      public static final String JNDI_CACHE_NAME =
       "com.ibm.websphere.naming.jndicache.cachename";
      public static final String JNDI_CACHE_NAME_DEFAULT = "providerURL";
      
      public static final String JNDI_CACHE_MAX_LIFE =
       "com.ibm.websphere.naming.jndicache.maxcachelife";
      public static final int    JNDI_CACHE_MAX_LIFE_DEFAULT = 0;
      
      public static final String JNDI_CACHE_MAX_ENTRY_LIFE =
       "com.ibm.websphere.naming.jndicache.maxentrylife";
      public static final int    JNDI_CACHE_MAX_ENTRY_LIFE_DEFAULT = 0;

      要在 Java 程序中使用先前的属性,添加属性设置到散列表,并将它传递给 InitialContext 构造函数,如下所示:

      java.util.Hashtable env = new java.util.Hashtable();
      ...
      
      // Disable caching
      env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE); ...
      javax.naming.Context initialContext = new javax.naming.InitialContext(env);

    下面是说明您可以如何使用 JNDI 高速缓存属性实现期望的高速缓存行为的示例。 高速缓存属性在构造 InitialContext 对象时起效。

    示例:通过程序控制 JNDI 高速缓存行为

    import java.util.Hashtable;
    import javax.naming.InitialContext;
    import javax.naming.Context;
    import com.ibm.websphere.naming.PROPS;
    
    /*****
     Caching discussed in this section pertains to the WebSphere Application Server initial context factory.
     Assume the property, java.naming.factory.initial, is set to
     "com.ibm.websphere.naming.WsnInitialContextFactory" as a java.lang.System property.
    *****/
    
    Hashtable env;
    Context ctx;
    
    // To clear a cache:
    
    env = new Hashtable();
    env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_CLEARED);
    ctx = new InitialContext(env);
    
    // To set a cache's maximum cache lifetime to 60 minutes:
    
    env = new Hashtable();
    env.put(PROPS.JNDI_CACHE_MAX_LIFE, "60");
    ctx = new InitialContext(env);
    
    // To turn caching off:
    
    env = new Hashtable();
    env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE);
    ctx = new InitialContext(env);
    
    // To use caching and no caching:
    
    env = new Hashtable();
    env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_POPULATED);
    ctx = new InitialContext(env);
    env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE);
    Context noCacheCtx = new InitialContext(env);
    
    Object o;
    
    // Use caching to look up home, since the home should rarely change.
    o = ctx.lookup("com/mycom/MyEJBHome");
    // Narrow, etc. ...
    
    // Do not use cache if data is volatile.
    o = noCacheCtx.lookup("com/mycom/VolatileObject");
    // ...

    示例:使用 JNDI 查找 JavaMail 会话

    以下示例显示了 JavaMail 资源的查找:

    // Get the initial context as shown previously
    ...
    Session session =
         (Session) initialContext.lookup("java:comp/env/mail/MailSession");
  2. 可选: 指定名称语法

    INS 语法是为需要与 CORBA 应用程序进行互操作的 JNDI 客户机设计的。 此语法允许 JNDI 客户机正确映射至 CORBA 名称,或从 CORBA 名称映射。 INS 语法与带有附加特殊字符点 (.) 的 JNDI 语法非常相似。 点用于对名称组件中的标识和种类字段进行定界。 当转义点时,它以文字解释。 名称组件中仅允许一个非转义的点。 具有非空标识字段和空种类字段的名称组件表示为仅标识字段值,并且一定不能以非转义点结束。 空名称组件(空标识和空种类字段)表示为单个非转义点。 空字符串不是有效名称组件表示法。

    JNDI 名称语法是缺省语法,且适用于典型 JNDI 客户机。 此语法包含以下特殊字符: 正斜杠 (/) 和反斜杠 (\)。 名称中的组件由正斜杠定界。 反斜杠用作转义字符。 如果转义正斜杠,那么正斜杠解释为文字,即在反斜杠后。 同样,如果转义反斜杠,那么将它解释为文字。

    大多数 WebSphere 应用程序使用 JNDI 来查找 EJB 对象,而不需要查找 CORBA 应用程序绑定的对象。 因此,用于 JNDI 名称的缺省名称语法是最方便的。 如果您的应用程序需要查询由 CORBA 应用程序绑定的对象,那么您可能需要更改名称语法,以便表示所有 CORBA CosNaming 名称。

    JNDI 客户机可通过设置属性以设置名称语法。 当您实例化新的 java.naming.InitialContext 对象时,通过初始上下文工厂应用属性设置。 根据指定的名称语法,分析初始上下文上 JNDI 操作中指定的名称。

    您可设置属性:

    • 在命令行中输入实际字符串值。 例如:
      java -Dcom.ibm.websphere.naming.name.syntax=ins
    • 创建文件 jndi.properties 以作为具有期望属性设置的文本文件。 例如:
      ...
      com.ibm.websphere.naming.name.syntax=ins
      ...

      如果使用此技巧,请注意类路径中可能存在 jndi.properties 文件的其他实例,并且这些实例可能包含冲突属性设置。 属性设置按类装入器选择 jndi.properties 文件的顺序确定。 无法控制类装入器定位类路径中的文件时使用的顺序。 WebSphere Application Server 最初不包含或创建任何设置 com.ibm.websphere.naming.name.syntax 属性的 jndi.properties 文件。

    • 在 Java 程序中使用 com.ibm.websphere.naming.PROPS 文件中定义的 PROPS.NAME_SYNTAX* Java 常量。 常量定义如下所示:
      public static final String NAME_SYNTAX =
          "com.ibm.websphere.naming.name.syntax";
      public static final String NAME_SYNTAX_JNDI = "jndi";
      public static final String NAME_SYNTAX_INS  = "ins";

      要在 Java 程序中使用先前的属性,添加属性设置到散列表,并将它传递给 InitialContext 构造函数,如下所示:

      java.util.Hashtable env = new java.util.Hashtable();
      ...
      env.put(PROPS.NAME_SYNTAX, PROPS.NAME_SYNTAX_INS); // Set name syntax to INS
      ...
      javax.naming.Context initialContext = new javax.naming.InitialContext(env);

    示例:设置用于解析名称字符串的语法

    名称语法属性可以通过其在系统属性或 jndi.properties 文件中的参数传递到 InitialContext 构造函数。 初始上下文以及从该初始上下文中查找的任何上下文根据指定的语法解析名称字符串。

    下面的示例显示如何将名称语法设置为让初始上下文根据 INS 语法解析名称字符串。

    ...
    import java.util.Hashtable;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import com.ibm.websphere.naming.PROPS; // WebSphere naming constants
    ...
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
          "com.ibm.websphere.naming.WsnInitialContextFactory");
    env.put(Context.PROVIDER_URL, ...);
    env.put(PROPS.NAME_SYNTAX, PROPS.NAME_SYNTAX_INS);
    Context initialContext = new InitialContext(env);
    // The following name maps to a CORBA name component as follows:
    //    id = "a.name", kind = "in.INS.format"
    // The unescaped dot is used as the delimiter.
    // Escaped dots are interpreted literally.
    java.lang.Object o = initialContext.lookup("a\\.name.in\\.INS\\.format");
    ...

    INS 名称语法要求使用反斜杠字符 (\) 对名称 (例如 in.INS.format ) 中的嵌入式句点 (.) 进行转义。 在 Java 字符串字面值中,必须使用另一个反斜杠字符 (\\) 对反斜杠字符 (\) 进行转义。

  3. 可选: 禁用主机名规范化

    对提供程序 URL 中的主机名、IP 地址和 localhost 的引用通常会规范化。 规范化主机名的格式是主机名的标准格式。 主机名规范化可提高系统效率,因为它允许对给定引导主机使用同一 JNDI 高速缓存,不管该引用在提供程序 URL 中的格式如何都是如此。 例如,如果 myhostmyhost.mydomain.comlocalhost 引用全部引用同一主机,那么主机名规范化允许对这些引用使用同一 JNDI 高速缓存。

    因为规范化主机名已高速缓存,所以后续规范化执行的速度更快。 在某些网络环境中,域名查找数据会动态更改,导致高速缓存的主机名规范化数据变旧。 在这类环境中,您可能需要禁用主机名规范化。 如果禁用主机规范化,那么系统会按原样使用主机名和 IP 地址。 对 localhost 的引用通常解析为回送地址 127.0.0.1。

    JNDI 客户机可通过设置属性来禁用主机名规范化。 当您实例化新的 java.naming.InitialContext 对象时,通过初始上下文工厂应用属性设置。

    使用下列其中一个技巧来设置此属性:
    • 可从命令行输入实际字符串值。 例如:
      java -Dcom.ibm.websphere.naming.hostname.normalizer=...none...
    • 可创建文件 jndi.properties 作为带有期望属性设置的文本文件。 例如:
      ...
      com.ibm.websphere.naming.hostname.normalizer=...none...
      ...

      如果使用此技巧,请注意类路径中可能存在 jndi.properties 文件的其他实例,并且这些实例可能包含冲突属性设置。 属性设置按类装入器选择 jndi.properties 文件的顺序确定。 无法控制类装入器定位类路径中的文件时使用的顺序。 WebSphere Application Server 最初不包含或创建任何设置 com.ibm.websphere.naming.hostname.normalizer 属性的 jndi.properties 文件。

    • 可在 Java 程序中使用 PROPS.HOSTNAME_NORMALIZER* Java 常量。 这些 Java 常量是在 com.ibm.websphere.naming.PROPS 文件中定义的。 下面是使用此技巧时要指定的常量定义:
      public static final String HOSTNAME_NORMALIZER =
          "com.ibm.websphere.naming.hostname.normalizer";
      public static final String HOSTNAME_NORMALIZER_NONE = "...none...;

      要在 Java 程序中使用这些定义,请将属性设置添加至散列表并将其传递至 InitialContext 构造函数:

      java.util.Hashtable env = new java.util.Hashtable();
      ...
      env.put(PROPS.HOSTNAME_NORMALIZER, PROPS.HOSTNAME_NORMALIZER_NONE);
          // Disable hostname normalization
      ...
      javax.naming.Context initialContext = 
         new javax.naming.InitialContext(env);

    示例:禁用主机名规范化

    可通过系统属性文件或 jndi.properties 文件中的 InitialContext 构造函数参数将主机名规范器属性传递至 InitialContext 构造函数。 初始上下文及从该初始上下文查找到的任何将来上下文都将使用此属性设置。

    以下示例说明如何禁用主机名规范化。

    ...
    import java.util.Hashtable;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import com.ibm.websphere.naming.PROPS; // WebSphere naming constants
    ...
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
          "com.ibm.websphere.naming.WsnInitialContextFactory");
    env.put(Context.PROVIDER_URL, ...);
    env.put(PROPS.HOSTNAME_NORMALIZER, PROPS.HOSTNAME_NORMALIZER_NONE);
    Context initialContext = new InitialContext(env);
    java.lang.Object o = initialContext.lookup(...);
    ...