客户端对EJB错误的调用:javax.naming.NoInitialContextException [英] Client call to EJB error: javax.naming.NoInitialContextException

查看:61
本文介绍了客户端对EJB错误的调用: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:

Source link

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

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