如何从 Java SE 中的 GlassFish 服务器获取初始上下文?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24843514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get initial context from GlassFish server in Java SE?
提问by pshemek
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:
我想从本地主机上运行的服务器(glassfish)中获取 InitialContext(),但出现以下错误:
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:
我知道我必须在 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);
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?
我不知道我应该如何配置 glassfish 服务器?
maven dependencies
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>
采纳答案by Tobb
In order to use JNDI you need to specify the java.naming.factory.initial
somehow, just like the error message says.
为了使用 JNDI,您需要以java.naming.factory.initial
某种方式指定,就像错误消息所说的那样。
There are multiple ways of doing this:
有多种方法可以做到这一点:
You could specify it as a system property in Glassfish, through server (Admin server)
-> Properties
您可以将其指定为 Glassfish 中的系统属性,通过server (Admin server)
->Properties
Alternatively, you could specify it in a HashTable and pass it to the constructor of InitialContext
:
或者,您可以在 HashTable 中指定它并将其传递给以下的构造函数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:
如果你使用 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>
See http://docs.oracle.com/javase/jndi/tutorial/beyond/env/context.htmlfor more information.
有关更多信息,请参阅http://docs.oracle.com/javase/jndi/tutorial/beyond/env/context.html。
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..
就实际值而言,上面的 Spring 配置是我们实际使用的Glassfish
. 我们不指定提供者 url 或凭据..
I don't think this is really connected to creating an ldap-realm, Glassfish might use JNDI to lookup the realm though.
我认为这与创建 ldap 领域并没有真正的联系,不过 Glassfish 可能会使用 JNDI 来查找领域。
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:
我想我可能明白问题是什么,您正在尝试从客户端访问远程类。有了这个假设,您可以使用 Spring 和 JndiTemplate 来做到这一点。假设服务器提供正确的 EJB 类,请在客户端执行此操作:
Create a bean for JndiTemplate:
为 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>
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 在服务器上查找内容。如果您想更进一步,并调用您自己的远程 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>
And then define beans as:
然后将bean定义为:
<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.
您可以像普通 bean 一样注入它,对它的任何调用都将发送到服务器。
回答by pshemek
In order to access glassfish (and too look up the EIB) running on localhost I had to use:
为了访问在本地主机上运行的 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");
}
}
When glassfish is running on localhost, Context can be initiated with default properties (without hashtable parameter)
当 glassfish 在 localhost 上运行时,可以使用默认属性启动 Context(不带 hashtable 参数)
Context ctx = new InitialContext();