可以 Tomcat(没有热部署)忽略覆盖的 jar

Can Tomcat (without hot deploy) ignore overridden jar

我们正在使用 Tomcat 8.5 ,没有任何热部署

我假设 classes 已加载到内存中,例如,如果 class jar 中的更改将忽略(不是热部署)

但是如果我们在应用程序 运行 时覆盖一个 jar,它会覆盖 classes(或删除它)

例如,当我复制空 jar 时,它会为 jar 中的 classes 抛出 ZipException

java.lang.IllegalStateException: java.util.zip.ZipException: zip file is empty
        at org.apache.catalina.webresources.AbstractSingleArchiveResourceSet.getArchiveEntry(AbstractSingleArchiveResourceSet.java:97)
        at org.apache.catalina.webresources.AbstractArchiveResourceSet.getResource(AbstractArchiveResourceSet.java:260)
        at org.apache.catalina.webresources.StandardRoot.getResourcesInternal(StandardRoot.java:327)
        at org.apache.catalina.webresources.CachedResource.validateResources(CachedResource.java:127)
        at org.apache.catalina.webresources.Cache.getResources(Cache.java:147)
        at org.apache.catalina.webresources.StandardRoot.getResources(StandardRoot.java:315)
        at org.apache.catalina.webresources.StandardRoot.getClassLoaderResources(StandardRoot.java:231)
        at org.apache.catalina.loader.WebappClassLoaderBase.findResources(WebappClassLoaderBase.java:939)
        at java.lang.ClassLoader.getResources(ClassLoader.java:1142)
        at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:348)
        at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:393)
        at java.util.ServiceLoader.hasNext(ServiceLoader.java:474)
        at javax.xml.parsers.FactoryFinder.run(FactoryFinder.java:293)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.xml.parsers.FactoryFinder.findServiceProvider(FactoryFinder.java:289)
        at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:267)
        at javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:120)
        at com.MyHelper.createDoc(MyHelper.java:64)

可以 tomcat 忽略覆盖的 jar 并仅从内存中提取 classes 吗?

是否有某种我不知道的内置热部署?

编辑

这可能与 tomcat 打开空罐子的特定问题有关

我认为发生的事情是 classloader 或 JAR 文件 reader 正在读取和缓存 JAR 文件的索引。因此,如果您在 classloader 仍处于打开状态时替换 JAR 文件,然后尝试加载资源,则很可能会注意到该文件现在是空的。

It may be related to issue specific for tomcat with empty jar opening

没有。它更基本。标准 Java classloader 的设计无法应对 JAR 文件的变化。

Can Tomcat ignore overridden jar and pull classes from memory only ?

据我所知

但您也许可以实现自己的自定义 class 加载程序来执行类似的操作;例如

  • 将 JAR 文件读入字节数组,然后根据字节数组打开 JAR 文件reader。
  • 将 JAR 文件复制到另一个文件,用 JAR 文件打开第二个文件 reader,然后(可选)取消链接副本,这样就没有其他东西可以干扰它。 (最后一步不适用于 Windows ...)