Java 普通类加载器使用的GlassFish扩展罐
我正在将几个应用程序从JBoss4迁移到GlassFish 3.1.x。每个应用程序都使用相同的API,该API提供每个应用程序使用的公共类和接口。让我们称之为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;
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的人)
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
这通常是在公共类尝试在公共库中的代码中执行类似于
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()
,并期望它返回子类重写