如果要覆盖的类被调用com.example.FooServlet
并且此类在jar WEB-INF/lib/foo.jar
内,那么如何使用另一个jar中名为com.example.FooServlet
的类覆盖它,比如说{{1} }}?
或者有没有办法确保首先加载bar.jar
中的那个?
制作bar.jar
模块是不行的,因为bar.jar
会从FooServlet
中的许多广告系列中导入大量的类。
正如我上面所说,我试图在一个模块中包含WEB-INF/lib
,但是找不到类或没有类def错误(不能清楚地记得),因为bar.jar
扩展/实现了一些额外的类/ WEB在WEB-INF / lib中的第三方jar中的接口。
我不允许触摸FooServlet
或foo.jar
中已存在的任何广告。
答案 0 :(得分:2)
你说你无法触及现有的罐子,你似乎暗示你可以添加你的罐子到WEB-INF/lib
。
根据this:
WEB-INF/lib/*.jar
下的广告没有指定的优先顺序。bar.jar
,则无法知道它是否会在foo.jar
之前或之后加载。WEB-INF/classes
下的类必须在WEB-INF/lib/*.jar
下的任何内容之前加载假设您可以在WEB-INF/lib
下添加一个jar,您应该可以在WEB-INF/classes
下添加一个(或几个)类,而不会触及那些类。<登记/>
因此,如果您希望首先加载bar.jar
中的类,则可以在WEB-INF/classes
下解压缩该jar的内容(或者只是要优先加载的类 - 例如{ {1}})。
答案 1 :(得分:1)
查看JBoss模块以及如何通过jboss-deployment-structure.xml
部署描述符处理它们。
很简单......
对于2个不同的WAR文件,您可以拥有2个不同的模块,每个模块在不同的jar文件中都有不同的com.example.FooServlet。
您只需要将您的foo.jar和boo.jar文件从WAR文件中删除,然后将它们添加到相应的模块中。
WAR的ClassLoader从您在jboss-deployment-structure.xml
中定义的模块中选择所需的类,并且永远不会与其他版本冲突。
答案 2 :(得分:1)
假设您可以完全控制JBoss的启动方式,或者至少可以更改JBoss启动设置 - 您的帮助就是Java代理。
简而言之,Java代理是JVM的自定义“插件”jar,它可以拦截该JVM对每个类和任何类的加载。并且 - 正是您需要的 - 它可以执行任何截获的类的字节代码的替换。 Further reading about Java agent concept
你想要实现的目标不是全新的,似乎已经在某种程度上得到了解决。 查看此question以及answer - 看起来几乎有关于编写代理的完整指南,该代理根据提供的外部jar替换类替换。
-javaagent:/path/to/your/agent.jar
根据您的JBoss版本和部署模型,事情可能会变得有点复杂,但是有some guides用于流行的代理安装,可以很容易地适应我们的情况