繁体   English   中英

自定义Tomcat Webapp ClassLoader

[英]Custom Tomcat Webapp ClassLoader

我正在尝试为tomcat实现自定义类加载器。 我的第一次尝试产生了类强制转换异常(显然,tomcat尝试将我的加载器强制转换为org.apache.catalina.loader.WebappLoader)。 好吧,我扩展了WebappLoader并将catalina.jar添加到我的构建路径中。

现在我准备好部署(我想)。 我收到这个错误:

严重:Catalina.start:LifecycleException:start :: java.lang.NoClassDefFoundError:org / apache / catalina / loader / WebappLoader

Tomcat附带catalina.jar来运行,所以我99.9%肯定它已经加载到tomcat中。 我通过检查/server/lib/catalina.jar验证了这一点,它包含了apache WebappLoader。 此外,正如预期的那样,手动链接另一个catalina.jar会产生一大堆问题。

我糊涂了。 任何提示都会很热。

谢谢!

更新:有趣的是,tomcat6上的相同内容(扩展WebappLoader;在tomcat5.5上运行)仍会导致ClassCastException。 听起来像执行演员表的类是使用与加载我的类的装载器不同的加载器加载的。 我不知道我怎么能控制它,除非在某处可能有另一个丢失的tomcat配置? 对tomcat6有什么想法吗?

也许我是密集的,但我认为应该是WebappClassLoader,而不是WebappLoader。 导入看起来不错。

如果不知道你的代码和设置的具体细节,就无法确定,但这让我想起了在自定义类加载器上尝试时遇到的问题。

场景是这样的:

  1. 引导加载程序(JVM本地/ Tomcat /取其中)加载您的代码
  2. 您的类加载器会加载上面类路径中不可用的附加内容。
  3. 您的代码引用了这些添加内容。
  4. 这些添加在与引导加载程序加载的代码相同的命名空间中不可用。
  5. 您的引导加载程序命名空间中的代码运行,尝试引用自定义命名空间中的代码,这在引导加载程序的命名空间中是不可见的。 所以在那时JVM就会出现NoClassDefFound错误。

这样做的原因是类加载器层次结构仅在单一方向上工作:即子命名空间(子类加载器)中的代码在更宽的父命名空间(父类加载器)中不可用(可见); 并没有很好的方法来入侵这个系统。

幸运的是,您可以定义父命名空间中可用的接口,然后在仅在子命名空间中可见的代码中实现这些接口。 然后,只存在于父命名空间内的代码能够使用此接口名称进行转换和方法调用,从而无论如何都可以访问您的子命名空间组件。

为了使其工作,您必须确保您的自定义类加载器不仅加载父加载器无法访问的组件(即在其类路径之外),而且还加载直接与这些组件接口的代码的那些位。明确地引用这些符号(类型名称/方法等)。 否则对这些组件的引用最终会出现在父命名空间中(请记住,默认情况下,引导类加载器会加载所有您自己的代码)并且您将回到原始问题。

您可以通过破坏预期的类加载委派模型来完成此操作。 通常,在尝试自己加载类之前,您会遵从父加载程序。 但是,现在您必须提前检查您的代码是否未触及任何这些组件,这些组件对父加载器无效。 最简单的方法可能是设置代码路径,使类加载器维护一组类加载自己的类名,而不是允许父加载器加载它们。

你必须找到一种方法以某种方式告诉你的自定义类加载器,类声明的类型注释可以用于此。 这里的想法是你的类加载器内省了父类加载的类,如果它在类型名称上找到一个特定的自定义注释,它将调用注释上的方法来获取它必须不允许其父加载器的类符号的名称。加载。

例:

@MyCustomAnnotation(implementation="my.custom.package.MyImpl")
public class MyFeatureProvider {
  public MyFeature getFeature() { // return an instance of MyImpl here }
}

请注意,因为MyFeatureProvider类将 MyImpl 之前加载,所以您的类加载器将事先知道MyFeatureProvider的注释,因此它将能够覆盖MyImpl的默认委托模型。 因为你的代码的其余部分只与MyImpl作为MyFeature的一个实例进行MyFeature所以父加载器永远不需要在看到未定义的符号时发生错误 - 并且解决了ClassNoDefFound错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM