客户端对EJB错误的调用:javax.naming.NoInitialContextException [英] Client call to EJB error: javax.naming.NoInitialContextException
问题描述
从类Main调用我的EJB:
MyService myService =(MyService)ctx.lookup(MyService.class.getName( ));
出现错误:
javax.naming.NoInitialContextException:需要在环境或系统属性中或作为applet参数或在应用程序资源文件中指定类名称:javax.java中的java.naming.factory.initial
。 naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
在javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
在javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java: 350)javax.naming.InitialContext.lookup(InitialContext.java:417)
com.ejb.calculator.Main.main(Main.java:26)
如何调用我的EJB?
尝试了两个不同的JNDI调用:
JNDI_NAME = java:global / ejb / MyService;
MyService myService =(MyService)ctx.lookup(JNDI_NAME);
和
MyService myService =(MyService)ctx.lookup(MyService.class.getName());
代码:
注意:
我的测试用例适用于嵌入式容器,但是我可以不会调用我的外部运行容器。
使用的版本是Java8,EJB3.0,Glassfish5.0.1,Java EE8.0.1
Update1:
在deplyoment container-deploy-log.txt期间添加了日志。见git remote。
Update2:
将工作更改推送到git remote。
Update3:
将MDB示例推送到git remote。
首先,如果要从外部客户端访问EJB,则需要声明一个远程视图。
由于您的EJB仅具有 @Local
批注,它仅提供本地视图。您应该添加 @Remote
批注。
@Local
@Remote
@Stateless
公共类MyService实现IMyService {
public String getMessage(){
return Hello!;
}
}
全局JNDI名称由以下形式组成:
java:global / [EAR模块] / [EJB模块] / [EJB名称]
在您的情况下,因为没有EAR,将是:
java:global / ejb-1.0-SNAPSHOT / MyService
此测试应该有效:
Context ctx = new InitialContext();
IMyService myService =(IMyService)ctx.lookup( java:global / ejb-1.0-SNAPSHOT / MyService);
Assert.assertEquals(myService.getMessage(), Hello!);
更新
您还需要将glassfish客户端库添加到类路径中以运行Main类。
我最初使用JUnit测试对其进行了测试,因为项目已经声明对包含Glassfish客户端的 glassfish-embeded-all
的 test
依赖性。但是IntelliJ在运行Main类时不会添加 test
库。
您可以更改 glassfish-embededall
到 runtime
或添加新的依赖项:
< dependency>
< groupId> org.glassfish.main.appclient< / groupId>
< artifactId> gf-client< / artifactId>
< version> 5.1.0< / version>
< scope>运行时< / scope>
< / dependency>
Calling my EJB from class Main:
MyService myService = (MyService) ctx.lookup(MyService.class.getName());
Gives error:
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:313)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.ejb.calculator.Main.main(Main.java:26)
How can I call my EJB?
Tried two different JNDI calls:
JNDI_NAME = "java:global/ejb/MyService";
MyService myService = (MyService) ctx.lookup(JNDI_NAME);
and
MyService myService = (MyService) ctx.lookup(MyService.class.getName());
Code:
https://bitbucket.org/powder366/ejb/src/master/
Glassfish commands:
asadmin start-domain --verbose
asadmin stop-domain --verbose
http://localhost:8080/
http://localhost:4848/common/index.jsf
mvn package
asadmin deploy ejb-1.0-SNAPSHOT.jar
Screenshots:
Note:
My test cases works with the embedded container, but I can't call my external running container.
Used versions are Java8, EJB3.0, Glassfish5.0.1, Java EE8.0.1
Update1: Added log during deplyoment container-deploy-log.txt. See git remote.
Update2: Pushed the working changes to git remote.
Update3: Pushed MDB example to git remote.
First of all, if you want to access your EJB from an external client, you need to declare a remote view.
As your EJB only has the @Local
annotation, it only offers a local view. You should add the @Remote
annotation.
@Local
@Remote
@Stateless
public class MyService implements IMyService {
public String getMessage() {
return "Hello!";
}
}
The global JNDI name is formed by:
java:global/[EAR module]/[EJB module]/[EJB name]
in your case, as there is no EAR, would be:
java:global/ejb-1.0-SNAPSHOT/MyService
This test should work:
Context ctx = new InitialContext();
IMyService myService = (IMyService) ctx.lookup("java:global/ejb-1.0-SNAPSHOT/MyService");
Assert.assertEquals(myService.getMessage(), "Hello!");
UPDATE
You also need to add the glassfish client libraries to the classpath to run the Main class.
I originally tested it with a JUnit test, it worked for me because the project already declared a test
dependency on glassfish-embeded-all
that includes the glassfish client. But IntelliJ doesn't add test
libraries when running a Main class.
You could either change the scope of glassfish-embeded-all
to runtime
or add a new dependency:
<dependency>
<groupId>org.glassfish.main.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>5.1.0</version>
<scope>runtime</scope>
</dependency>
这篇关于客户端对EJB错误的调用:javax.naming.NoInitialContextException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!