Tomcat(无需热部署)是否可以忽略覆盖的jar

时间:2019-07-17 10:33:15

标签: java tomcat classloader hotdeploy tomcat8.5

我们使用的是Tomcat 8.5 ,没有任何热部署

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

但是,如果我们在应用程序运行时覆盖jar,它将覆盖类(或将其删除)

例如,当我复制空jar时,它会向该jar中的类抛出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$1.hasNext(ServiceLoader.java:474)
        at javax.xml.parsers.FactoryFinder$1.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并仅从内存中提取类吗?

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

1 个答案:

答案 0 :(得分:1)

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

  

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

不。这是更根本的。标准的Java类加载器并不是为应对JAR文件更改而设计的。

  

Tomcat是否可以忽略重写的jar并仅从内存中提取类?

AFAIK号

但是您可以实现自己的自定义类加载器,该加载器可以执行类似的操作;例如

  • 将JAR文件读入字节数组,然后针对该字节数组打开JAR文件读取器。
  • 将JAR文件复制到另一个文件,使用JAR文件阅读器打开第二个文件,然后(可选)取消链接副本,以便其他任何操作都不会干扰它。 (最后一步在Windows上无法使用...)