Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 普通类加载器使用的GlassFish扩展罐_Java_Jakarta Ee_Glassfish_Classloader - Fatal编程技术网

Java 普通类加载器使用的GlassFish扩展罐

Java 普通类加载器使用的GlassFish扩展罐,java,jakarta-ee,glassfish,classloader,Java,Jakarta Ee,Glassfish,Classloader,我正在将几个应用程序从JBoss4迁移到GlassFish 3.1.x。每个应用程序都使用相同的API,该API提供每个应用程序使用的公共类和接口。让我们称之为CoreAPI.jar CoreAPI.jar被放入GlassFish的/lib目录中,并由公共类加载器加载 现在让我们假设每个应用程序都从CoreAPI扩展了一个名为Version的类(不是抽象类): public class Version { public String getVersion() { return null;

我正在将几个应用程序从JBoss4迁移到GlassFish 3.1.x。每个应用程序都使用相同的API,该API提供每个应用程序使用的公共类和接口。让我们称之为
CoreAPI.jar

CoreAPI.jar
被放入GlassFish的
/lib
目录中,并由公共类加载器加载

现在让我们假设每个应用程序都从CoreAPI扩展了一个名为
Version
的类(不是抽象类):

public class Version {
    public String getVersion() { return null; }
}
方法
getVersion()
从API本身的几个地方调用,每个使用API的应用程序负责扩展类并提供如下版本:

public class MyAppVersion extends Version {
    private static final String VERSION = "1.0";

    @Override
    public String getVersion() { return VERSION; }
}
当我将应用程序部署到捆绑在WAR或EAR中的GlassFish时,只要API从父类调用
getVersion()
,我就会得到一个
java.lang.NullPointerException
——它似乎找不到子类

如果
CoreAPI.jar
与WAR捆绑在一起并从
/lib
目录中删除,则可以正确地找到子类,但我不能这样做,因为许多应用程序都需要它作为共享库

有没有办法让共享库“看到”已部署应用程序中的子类

谢谢


澄清:我无权更改CoreAPI

为了在所有应用程序之间共享库,您应该使用
$GLASSFISH\u HOME/GLASSFISH/lib
文件夹。当您通过更新工具将附加组件安装到GlassFish时,您甚至可能会注意到它会将第三方JAR复制到此文件夹,以便所有应用程序都可以使用它

要在域下的所有应用程序中共享,您可以将其放入
$GLASSFISH\u HOME/GLASSFISH/domains/your domain/lib
文件夹,就像您所做的那样

为了测试您描述的内容,我创建了两个maven项目:

  • 一个名为version(CoreAPI的模拟)的java项目
  • 一个名为web版本的web项目(将扩展CoreAPI的人)
java项目包含非抽象CoreAPI类:

package com.acme.version;

public class Version
{
    public String getVersion() { return null; }
}
在web版本的项目中,我向
version-1.0.jar
添加了一个提供的范围依赖项,这样就可以对其进行编译,但一旦它出现在Glassfish/lib文件夹中,它就不会被添加到项目中

然后web版本项目具有我用于测试的
version
类的扩展版本:

package com.acme.web.controller;

import com.acme.version.Version;

public class ExtendedVersion extends Version
{
    private static final String VERSION = "1.0";

    @Override
    public String getVersion ()
    {
        return VERSION;
    }

    @Override
    public String toString()
    {
        return getVersion();
    }
}
然后我做了这个:

  • 构建版本项目并将结果jar复制到上面提到的
    $GLASSFISH_HOME/GLASSFISH/lib
    文件夹中

  • 创建了一个包含
    ExtendedVersion
    实例的控制器,并部署了应用程序。它在网页中输出
    1.0

有没有办法让共享库“看到”已部署应用程序中的子类

这有点奇怪,因为共享库正在加载。似乎出于某种原因,您的子类不是。(日志中是否有其他相关例外情况?)

我认为您已经描述了一点,这个问题甚至可能与JBoss x GlassFish transition的其他依赖性有关,而不是与您的子类化或类加载方法有关

有没有一种方法可以让共享库“看到”一个类中的子类 部署的应用程序

不可以。应用程序类加载器是普通类加载器的后代,类加载器只能看到它们的父类,而不能看到它们的从属类


这通常是在公共类尝试在公共库中的代码中执行类似于
class.forName(“com.app.ImplementationClass”)
的操作时发现的。

有什么方法可以解决这个问题吗?我有一个类似的WebSphere7服务器设置(使用共享库引用),我的案例运行正常。类加载器有什么不同?类加载器可能有很多不同。我对Websphere不太熟悉,无法发表评论。但是,例如,在Glassfish EAR中,默认情况下,所有模块(EJB、WAR等)的所有类和JAR都合并到一个单独的共享空间中。特别是,如果一个EAR包含两个WAR,WAR A将在WAR B中看到类和库。其他应用程序服务器的做法不同(隔离WAR),即使这两种方式都符合标准。所以可能会有很多不同。有关GF的详细信息,请参阅。谢谢!现在我已经阅读了好几次类装入器层次结构;我将
CoreAPI.jar
放在类加载器的几个不同位置。还是不走运。不幸的是,我想“不”是我问题的正确答案。我的猜测是API需要重写..您好,谢谢您的测试。我认为区别在于API本身正在从
Version
父级调用
getVersion()
,并期望它返回子类重写