我正在将几个应用程序从JBoss 4迁移到GlassFish 3.1.x.这些应用程序中的每一个都使用相同的API,它提供每个应用程序使用的公共类和接口。我们称之为CoreAPI.jar
。
CoreAPI.jar
被放入GlassFish的<domain>/lib
目录中,并由公共类加载器加载。
现在让我们说每个应用程序从名为Version
的CoreAPI扩展一个类(而不是抽象):
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; }
}
当我将应用程序部署到GlassFish,捆绑在WAR或EAR中时,只要API从父类调用getVersion()
,我就会得到java.lang.NullPointerException
- 它似乎无法找到子类。
如果CoreAPI.jar
与WAR绑定并从<domain>/lib
目录中删除,则可以正确找到子类,但我不能这样做,因为许多应用程序需要它作为共享库。
有没有办法让共享库“看到”部署的应用程序中的子类?
谢谢!
澄清:我无权更改CoreAPI
答案 0 :(得分:1)
要在所有应用程序之间共享库,您应该使用$GLASSFISH_HOME/glassfish/lib
文件夹。当您通过更新工具向GlassFish安装加载项时,您甚至可能会注意到它将第三方jar复制到此文件夹,因此它可供所有应用程序使用。
要分享域名下的所有应用程序,您可以将其放在$GLASSFISH_HOME/glassfish/domains/your-domain/lib
文件夹中,就像您一样。
为了测试你描述的内容,我创建了2个maven项目:
java项目包含非抽象的CoreAPI类:
package com.acme.version;
public class Version
{
public String getVersion() { return null; }
}
在web-version项目中,我向version-1.0.jar
添加了一个提供的范围依赖项,因此它可以被编译,但是一旦它存在于Glassfish / lib文件夹中,它就不会被添加到项目中。< / p>
然后,web-version项目具有我用于测试的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转换的其他依赖关系有关,而不是你的子类或类加载方法。
答案 1 :(得分:1)
有没有办法让共享库“看到”一个子类 部署了应用程序?
没有。应用程序类加载器是公共类加载器的后代,类加载器只能看到它们的父级,而不能看到它们的属性。
当公共类试图在实际位于公共库中的代码中执行Class.forName("com.app.ImplementationClass")
之类的操作时,通常会发现这种情况。