如何从Java SE中的GlassFish服务器获取初始上下文? [英] How to get initial context from GlassFish server in Java SE?

查看:161
本文介绍了如何从Java SE中的GlassFish服务器获取初始上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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);
}
}
}

我想要InitialContext()构成在本地主机上运行的服务器(glassfish),但是我得到了下面的错误:

  SEVERE:null 
javax.naming.NoInitialContextException:需要在环境或系统属性或applet参数中或应用程序资源文件中指定类名称:
java.naming.factory.initial $ b $ javax.naming .spi.NamingManager.getInitialContext(NamingManager.java:662)$ javax.naming.InitialContext.getDefaultInitCtx中的b $ b(InitialContext.java:307)$ b $ javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344 )
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at poligon.Poligon.main(Poligon.java:29)

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

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

上下文ctx = new InitialContext(env);

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

  Context.INITIAL_CONTEXT_FACTORY 
Context.PROVIDER_URL(我想在本地主机上)
Context.SECURITY_PRINCIPAL
Context.SECURITY_CREDENTIALS

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





maven dependencies

 < dependency> 
< groupId> org.glassfish.main.extras< / groupId>
< artifactId> glassfish-embedded-all< / artifactId>
< version> 4.0< / version>
< scope>提供< / scope>
< /依赖关系>
< dependency>
< groupId> org.glassfish.main.appclient.client< / groupId>
< artifactId> gf-client< / artifactId>
< version> 3.1.2.2< / version>
< /依赖关系>


解决方案

为了使用JNDI,您需要指定 java.naming.factory.initial 就像错误消息说的那样。



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



您可以通过服务器(管理服务器) - > <$将其指定为Glassfish中的系统属性c $ c> Properties



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

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

上下文ctx = new InitialContext(env);

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

 < bean id =myJndiTemplateclass =org.springframework.jndi.JndiTemplate> 
< property name =environment>
<道具>
< 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>
< /道具>
< / property>
< / bean>

请参阅 http://docs.oracle.com/javase/jndi/tutorial/beyond/env/context.html 以获取更多信息。



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



我认为这不是真的与创建ldap领域相关,Glassfish可能会使用JNDI来查找领域。

编辑:

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



为JndiTemplate创建一个bean:

 < bean id =myJndiTemplateclass =org.springframework.jndi.JndiTemplate> 
< property name =environment>
<道具>
< 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>
< /道具>
< / property>
< / bean>

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

 << ; bean id =ejbProxy
class =org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean
abstract =true>
< property name =refreshHomeOnConnectFailurevalue =true/>
< property name =cacheHomevalue =true/>
< property name =lookupHomeOnStartupvalue =true/>
< property name =resourceRefvalue =false/>
< property name =jndiTemplateref =mySpringTemplate/>
< / bean>

然后将beans定义为:

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

您可以像普通bean一样注入它,任何对它的调用都将被发送到服务器。 / p>

I have a class like below:

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);
        }
    }
}

I would like to get the InitialContext() form the server (glassfish) running on localhost, but I get the below error:

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)

I know I have to create ldap realm on glassfish and add the below code (? - dont know the exact values) to my class:

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);

My problem is that I dont know what values should be at:

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

And I dont know how I should configure glassfish server?

maven dependencies

    <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>

解决方案

In order to use JNDI you need to specify the java.naming.factory.initial somehow, just like the error message says.

There are multiple ways of doing this:

You could specify it as a system property in Glassfish, through server (Admin server) -> Properties

Alternatively, you could specify it in a HashTable and pass it to the constructor of InitialContext:

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

Context ctx = new InitialContext(env);

If you use Spring you could also do this:

<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>

See http://docs.oracle.com/javase/jndi/tutorial/beyond/env/context.html for more information.

As far as the actual values go, the Spring config above is what we actually use with Glassfish. We do not specify provider url or credentials..

I don't think this is really connected to creating an ldap-realm, Glassfish might use JNDI to lookup the realm though.

Edit:

I think I might understand what the problem is, you are trying to access remote classes from a client. With this assumption, you can use Spring to do this, with JndiTemplate. Assuming that the server makes available the correct EJB-classes, do this on the client side:

Create a bean for JndiTemplate:

  <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>

You can then use this bean to lookup stuff on the server. If you want to take it a step further, and call your own remote EJB-classes, you could also do this:

  <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>

And then define beans as:

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

You can inject this like a regular bean, any calls to it will be made to the server.

这篇关于如何从Java SE中的GlassFish服务器获取初始上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆