英文:
javax.naming.NameNotFoundException in external library/jar
问题
我在部署在 Liberty 服务器上的应用程序中遇到了 javax.naming.NameNotFoundException 错误:
javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:app/ExternalEJB/EJBBean!com.example.server.ejb.SecurityEJB
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:355)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:428)
at com.example.connect.server.ServiceProvider.getLocal(ServiceProvider.java:153)
at com.example.connect.server.ServiceProvider.getLocal(ServiceProvider.java:122)
at com.example.connect.server.ServiceProvider.getService(ServiceProvider.java:73)
at com.example.connect.ConnectFactory.makeService(ConnectFactory.java:300)
at com.example.connect.ConnectFactory.getService(ConnectFactory.java:280)
at com.example.connect.ConnectFactory.getService(ConnectFactory.java:252)
at com.example.server.ejb.EJBWrapper.getService(EJBWrapper.java:91)
at com.example.server.ejb.EJBWrapper.find(EJBWrapper.java:1231)
at com.example.server.bo.PersonBO.find(PersonBO.java:233)
at de.example.framework.Wrapper.find(Wrapper.java:102)
应用程序结构如下:
Appl.ear
|
├──Module1.war (de.example.framework)
├──Module2.war
├──EJBModule.war
|
└───/lib
├───ExternalLib.jar (com.example.server)
| └── ExternalEJB (EJBBean 实现 SecurityEJB)
|
├───ExternalLib2.jar (com.example.connect)
|
└───MyOwnLib.jar (de.example.service)
现在我不知道为什么该库找不到 jdni 名称(在其他项目中,这两个库一起工作)。有什么建议吗?我做错了什么吗?
如果您需要更多信息,我会尽量为您提供。
谢谢!
编辑:
由于这些库是外部库,我没有源代码,不过我可以使用类似 JD 的工具向您展示它们的外观:
EJBBean 声明:
@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Local({SecurityEJB.class})
public class EJBBean extends BaseStatelessSessionBean implements SecurityEJB {
getLocal 方法:
protected static <T> T getLocal(Class<T> cls, String jndiName) throws GenException {
if (log.isDebugEnabled()) {
log.debug("class : " + cls);
log.debug("jndi : " + jndiName);
}
Context ctx = null;
Object local = null;
try {
ctx = getContext();
if (log.isDebugEnabled())
log.debug("context : " + ctx);
local = ctx.lookup(jndiName); <--- 第 153 行
if (log.isDebugEnabled()) {
log.debug("local : " + local);
log.debug(" class : " + local.getClass().getName());
log.debug(" class loader: " + local.getClass().getClassLoader());
}
return (T)local;
} catch (NamingException ex) {
throw new GenException(ex);
}
}
SecurityEJB 接口:
public interface SecurityEJB extends ICompressible {
public static final String JNDI_NAME = "java:app/ExternalEJB/EJBBean!" + SecurityEJB.class
.getName();
server.xml 中的特性:
<featureManager>
<feature>javaee-8.0</feature>
<feature>localConnector-1.0</feature>
<feature>ejbRemote-3.2</feature>
<feature>ldapRegistry-3.0</feature>
<feature>transportSecurity-1.0</feature>
</featureManager>
英文:
i get a javax.naming.NameNotFoundException in my application which is deployed on a liberty server:
javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:app/ExternalEJB/EJBBean!com.example.server.ejb.SecurityEJB
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:355)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:370)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:428)
at com.example.connect.server.ServiceProvider.getLocal(ServiceProvider.java:153)
at com.example.connect.server.ServiceProvider.getLocal(ServiceProvider.java:122)
at com.example.connect.server.ServiceProvider.getService(ServiceProvider.java:73)
at com.example.connect.ConnectFactory.makeService(ConnectFactory.java:300)
at com.example.connect.ConnectFactory.getService(ConnectFactory.java:280)
at com.example.connect.ConnectFactory.getService(ConnectFactory.java:252)
at com.example.server.ejb.EJBWrapper.getService(EJBWrapper.java:91)
at com.example.server.ejb.EJBWrapper.find(EJBWrapper.java:1231)
at com.example.server.bo.PersonBO.find(PersonBO.java:233)
at de.example.framework.Wrapper.find(Wrapper.java:102)
The application structure is as follows:
Appl.ear
|
├──Module1.war (de.example.framework)
├──Module2.war
├──EJBModule.war
|
└───/lib
├───ExternalLib.jar (com.example.server)
| └── ExternalEJB (EJBBean implements SecurityEJB)
|
├───ExternalLib2.jar (com.example.connect)
|
└───MyOwnLib.jar (de.example.service)
Now i dont know why the jdni name could not be found by the library (these two libraries work together in other projects). Any suggestions what i do wrong?
If you need more informations, i try to provide them to you.
Thanks!
Edit:
Since the libraries are external ones i do not have the source code, although with tool like JD i can show you how they look like:
EJBBean Declaration:
@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Local({SecurityEJB.class})
public class EJBBean extends BaseStatelessSessionBean implements SecurityEJB {
getLocal-method:
protected static <T> T getLocal(Class<T> cls, String jndiName) throws GenException {
if (log.isDebugEnabled()) {
log.debug("class : " + cls);
log.debug("jndi : " + jndiName);
}
Context ctx = null;
Object local = null;
try {
ctx = getContext();
if (log.isDebugEnabled())
log.debug("context : " + ctx);
local = ctx.lookup(jndiName); <--- line 153
if (log.isDebugEnabled()) {
log.debug("local : " + local);
log.debug(" class : " + local.getClass().getName());
log.debug(" class loader: " + local.getClass().getClassLoader());
}
return (T)local;
} catch (NamingException ex) {
throw new GenException(ex);
}
}
the SecurityEJB Interface:
public interface SecurityEJB extends ICompressible {
public static final String JNDI_NAME = "java:app/ExternalEJB/EJBBean!" + SecurityEJB.class
.getName();
features in server.xml:
<featureManager>
<feature>javaee-8.0</feature>
<feature>localConnector-1.0</feature>
<feature>ejbRemote-3.2</feature>
<feature>ldapRegistry-3.0</feature>
<feature>transportSecurity-1.0</feature>
</featureManager>
答案1
得分: 2
根据Java EE平台规范(部署Java EE应用程序),只有当模块不位于lib
目录中并且包含META-INF/ejb-jar.xml
文件或定义了EJB组件的注释(例如@Stateless
)时,该模块才被视为EJB模块。
在这个示例中,由于EJBBean
类位于lib/ExternalLib.jar
中,因此将忽略@Stateless
注释。ExternalLib.jar
JAR文件不被视为EJB模块,因为它位于lib
目录中。
ExternalLib.jar
需要移到lib
目录之外,或者其他EJB或WAR模块中的一个需要包含一个声明EJBBean
为EJB的ejb-jar.xml
文件。lib
目录中的所有类可以被EJB和WAR模块引用,因此在WAR或EJB模块的ejb-jar.xml
文件中将来自lib模块的类声明为EJB是可以接受的。请注意,java:
查找将使用包含ejb-jar.xml
文件的模块名称,而不会使用lib
目录中的JAR的名称。
英文:
Per the Java EE Platform Specification (Deploying a Java EE Application), a module is only considered an EJB module if it is not in the lib
directory and contains either an META-INF/ejb-jar.xml
file or an EJB component defining annotation, such as @Stateless
.
In this example, since the EJBBean
class is in lib/ExternalLib.jar
, the @Stateless
annotation will be ignored. The ExternalLib.jar
JAR file is not considered to be an EJB module since it is in the lib
directory.
ExternalLib.jar
either needs to be moved out of the lib
directory, or one of the other EJB or WAR modules needs to contain an ejb-jar.xml
file that declares EJBBean
to be an EJB. All classes in the lib
directory may be referenced by EJB and WAR modules, so it is acceptable to declare a class from a lib module as an EJB in the ejb-jar.xml
file of a WAR or EJB module. Note that the java:
lookup would use the module name where the ejb-jar.xml
file is located; never the name of a JAR in the lib
directory.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论