如何从Java SE中的GlassFish服务器获取初始上下文?

时间:2014-07-19 18:15:04

标签: java glassfish initial-context

我有一个如下课程:

public class Poligon {

    public static void main(String[] args) {

        try {
            Context ctx = new InitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("jms/javaee7/ConnectionFactory");
            Destination destination = (Destination) ctx.lookup("jms/javaee7/Topic");
            JMSContext context = connectionFactory.createContext();
            OrderDTO order = context.createConsumer(destination).receiveBody(OrderDTO.class);
            System.out.println("Order received: " + order);
        } catch (NamingException ex) {
            Logger.getLogger(Poligon.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

我想将localContext()表单运行在localhost上运行的服务器(glassfish),但是我收到以下错误:

SEVERE: null
javax.naming.NoInitialContextException: Need to specify class name in environment or  system property, or as an applet parameter, or in an application resource file:  
    java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
    at javax.naming.InitialContext.lookup(InitialContext.java:411)
    at poligon.Poligon.main(Poligon.java:29)

我知道我必须在glassfish上创建ldap领域并将以下代码(? - 不知道确切的值)添加到我的班级:

Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
            "?");
    env.put(Context.PROVIDER_URL, "?");
    env.put(Context.SECURITY_PRINCIPAL, "?");
    env.put(Context.SECURITY_CREDENTIALS, "?");

Context ctx = new InitialContext(env);

我的问题是我不知道应该在什么值:

Context.INITIAL_CONTEXT_FACTORY
Context.PROVIDER_URL (I want it on localhost)
Context.SECURITY_PRINCIPAL
Context.SECURITY_CREDENTIALS

我不知道应该如何配置glassfish服务器?

enter image description here

maven依赖

    <dependency>
        <groupId>org.glassfish.main.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>4.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.main.appclient.client</groupId>
        <artifactId>gf-client</artifactId>
        <version>3.1.2.2</version>
    </dependency>

2 个答案:

答案 0 :(得分:1)

为了使用JNDI,您需要以某种方式指定java.naming.factory.initial,就像错误消息所示。

有多种方法可以做到这一点:

您可以在Glassfish中将其指定为系统属性,通过server (Admin server) - &gt; Properties

或者,您可以在HashTable中指定它并将其传递给InitialContext的构造函数:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,  
    "com.sun.enterprise.naming.SerialInitContextFactory");

Context ctx = new InitialContext(env);

如果你使用Spring,你也可以这样做:

<bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.enterprise.naming.SerialInitContextFactory</prop>
            <prop key="java.naming.factory.url.pkgs">com.sun.enterprise.naming</prop>
            <prop key="java.naming.factory.state">com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl</prop>
        </props>
    </property>
</bean>

有关详细信息,请参阅http://docs.oracle.com/javase/jndi/tutorial/beyond/env/context.html

就实际值而言,上面的Spring配置是我们实际使用的Glassfish。我们不指定提供者URL或凭证..

我认为这与创建ldap-realm无关,Glassfish可能会使用JNDI来查找域。

编辑:

我想我可能会理解问题所在,您正试图从客户端访问远程类。有了这个假设,你可以使用Spring来使用JndiTemplate。假设服务器提供了正确的EJB类,请在客户端执行此操作:

为JndiTemplate创建一个bean:

  <bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
      <props>
        <prop key="java.naming.factory.initial">com.sun.enterprise.naming.SerialInitContextFactory</prop>
        <prop key="org.omg.CORBA.ORBInitialHost">${servername}</prop>
        <prop key="org.omg.CORBA.ORBInitialPort">${jndiport}</prop>
      </props>
    </property>
  </bean>

然后,您可以使用此bean在服务器上查找内容。如果你想更进一步,并调用你自己的远程EJB类,你也可以这样做:

  <bean id="ejbProxy"
        class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"
        abstract="true">
    <property name="refreshHomeOnConnectFailure" value="true"/>
    <property name="cacheHome" value="true"/>
    <property name="lookupHomeOnStartup" value="true"/>
    <property name="resourceRef" value="false"/>
    <property name="jndiTemplate" ref="mySpringTemplate"/>
  </bean>

然后将bean定义为:

  <bean id="someRemoteService" parent="ejbProxy">
    <property name="jndiName"
              value="com.company.service.MyRemoteService"/>
    <property name="businessInterface"
              value="com.company.service.MyRemoteService"/>
  </bean>

你可以像普通bean一样注入它,任何对它的调用都将发送给服务器。

答案 1 :(得分:0)

为了访问在localhost上运行的glassfish(以及查找EIB)我必须使用:

public class Main {

    public static void main(String[] args) throws NamingException {

        java.util.Hashtable<String, String> hashTable = new Hashtable<String, String>();
        hashTable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.impl.SerialInitContextFactory");
        hashTable.put(Context.STATE_FACTORIES, "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
        hashTable.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
        Context ctx = new InitialContext(hashTable);

    // Looks up the EJB with JNDI
        BookEJBRemote bookEJB = (BookEJBRemote) ctx.lookup("java:global/chapter08-service-1.0/BookEJB!org.agoncal.book.javaee7.chapter08.BookEJBRemote");
    }
}

当glassfish在localhost上运行时,可以使用默认属性(没有哈希表参数)启动Context

Context ctx = new InitialContext();