外部库/ jar中的javax.naming.NameNotFoundException

问题描述

我在部署在自由服务器上的应用程序中得到了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 implements 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); <--- 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);
    } 
  }

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>

解决方法

根据Java EE平台规范(部署Java EE应用程序),仅当模块不在lib目录中并且包含META-INF/ejb-jar.xml文件或EJB时,才将其视为EJB模块。定义注释的组件,例如@Stateless

在此示例中,由于EJBBean类位于lib/ExternalLib.jar中,因此@Stateless注释将被忽略。 ExternalLib.jar JAR文件不属于EJB模块,因为它位于lib目录中。

ExternalLib.jar要么需要移出lib目录,要么其他EJB或WAR模块之一需要包含一个声明ejb-jar.xml的{​​{1}}文件是一个EJB。 EJBBean目录中的所有类都可以由EJB和WAR模块引用,因此可以将来自lib模块的类声明为WAR或EJB模块的lib文件中的EJB。请注意,ejb-jar.xml查找将使用java:文件所在的模块名称。 ejb-jar.xml目录中永远不要是JAR的名称。