2015-02-27 6 views
4

У меня есть приложение, которое использует встроенный причал и прекрасно работает.embedded jetty не очищает временный каталог полностью (сохраняет lib/*. Jar)

У меня возникли проблемы с временными каталогами, создаваемыми причалом. Когда приложение развернуто, он создает временную директорию с извлеченной войной (jetty-0.0.0.0-8888-app.war-_app-any-4643933123854766078.dir), все хорошо. Но когда я удаляю/заменяю эту войну другой версией (в том же контексте), она создает еще одну временную директорию, а другая не удаляется полностью. Я вижу, что jetty удаляет все css, html-файлы, но web-inf/lib/*. Jar не удаляется.

Значение webAppContext.setPersistTempDirectory установлено на false, я уже проверен.

Я уже пытался изменить временную директорию, используемую причалом.

Вот мой WebAppProvider:

WebAppProvider webAppProvider = new WebAppProvider(); 
webAppProvider.setMonitoredDirName("webapps"); 
webAppProvider.setScanInterval(1); 
webAppProvider.setExtractWars(true); 
webAppProvider.setDefaultsDescriptor("webdefault.xml"); 
webAppProvider.setTempDir(new File("work")); 

String webDefault = Thread.currentThread().getContextClassLoader().getResource("webdefault.xml").getPath(); 
if (webDefault != null) { 
    File f = new File(webDefault); 
    if (f.exists() && !f.isDirectory()) { 
     webAppProvider.setDefaultsDescriptor(webDefault); 
    } 
} 

Вот DeploymentManager:

DeploymentManager deploymentManager = new DeploymentManager(); 
deploymentManager.setContexts(contextHandlerCollection); 
deploymentManager.setContextAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", 
     ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\\.jar$"); 

deploymentManager.addAppProvider(webAppProvider); 

Настройка сервера:

server = new Server(8888); 
server.setStopAtShutdown(true); 
server.setStopTimeout(5000); 

handlerCollection.addHandler(contextHandlerCollection); 
handlerCollection.addHandler(new DefaultHandler()); 

server.setHandler(handlerCollection); 
server.addBean(deployManager); 

я заметил, что я только могу вручную удалить каталог, когда я остановить пристань. Я думаю, что это единственный способ освободить процесс, который использует банки, и позволить мне полностью удалить.

Обс: Я не хочу останавливать сервер, чтобы удалить папки.

Заранее спасибо.

+0

это простое приложение Java или не использует рамку. Как остановить приложение при развертывании новой версии? –

+0

Эй, да, я использую весну. Но я не останавливаю приложение для развертывания новой версии. Jetty наблюдает за изменением в каталоге webapps и делает для меня горячее развертывание, мне просто нужно заменить файл. – pecci

+0

ok; поэтому я думаю, что вы можете расширить 'org.eclipse.jetty.deploy.bindings.StandardStopper' или' oejdbStandarUndeployer' и передать его в 'DeploymentManager.addLifeCycleBinding (привязка к AppLifeCycle.Binding)' –

ответ

4

Ну, найдите решение. Просто отправляйте сюда, чтобы помочь любому, кто в этом нуждается.

Здесь идет мои файлы:

DeploymentManager:

DeploymentManager deploymentManager = new DeploymentManager(); 
deploymentManager.setContexts(contextHandlerCollection); 
deploymentManager.setContextAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", 
     ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/org.apache.taglibs.taglibs-standard-impl-.*\\.jar$"); 

deploymentManager.addLifeCycleBinding(new StandardStarter()); 
deploymentManager.addLifeCycleBinding(new StandardStopperCustom()); 
deploymentManager.addLifeCycleBinding(new StandardDeployer()); 
deploymentManager.addLifeCycleBinding(new StandardUndeployer()); 
deploymentManager.setUseStandardBindings(false); 

deploymentManager.addAppProvider(webAppProvider); 

WebAppProvider:

WebAppProviderCustom webAppProvider = new WebAppProviderCustom(); 
webAppProvider.setMonitoredDirName("webapps"); 
webAppProvider.setScanInterval(1); 
webAppProvider.setExtractWars(true); 
webAppProvider.setDefaultsDescriptor("webdefault.xml"); 
webAppProvider.setTempDir(new File("work")); 

String webDefault = Thread.currentThread().getContextClassLoader().getResource("webdefault.xml").getPath(); 
if (webDefault != null) { 
    File f = new File(webDefault); 
    if (f.exists() && !f.isDirectory()) { 
     webAppProvider.setDefaultsDescriptor(webDefault); 
    } 
} 

StopperCustom:

public class StandardStopperCustom extends StandardStopper { 
    @Override 
    public void processBinding(Node node, App app) throws Exception { 
     ContextHandler handler; 
     try { 
      handler = app.getContextHandler(); 

      if (handler instanceof WebAppContext) { 
       WebAppContext webapp = (WebAppContext) handler; 

       File tempDirectory = (File) webapp.getAttribute("javax.servlet.context.tempdir"); 
       String baseDirectory = tempDirectory.getName(); 

       if (webapp.getClassLoader() instanceof WebAppClassLoaderCustom && !baseDirectory.isEmpty()) { 
        WebAppClassLoaderCustom classLoader = (WebAppClassLoaderCustom) webapp.getClassLoader(); 

        super.processBinding(node, app); 

        classLoader.close(); 
        cleanUpTempDirectory(baseDirectory); 
       } 
      } else { 
       super.processBinding(node, app); 
      } 
     } catch (Exception e1) { 
      e1.printStackTrace(); 
     } 
    } 

    public void cleanUpTempDirectory(String tempDirectory) { 
     File work = new File(Constantes.workDirectory); 

     File[] jettyFolders = work.listFiles(new FilenameFilter() { 
      @Override 
      public boolean accept(File dir, String name) { 
       if (name.equalsIgnoreCase(tempDirectory)) { 
        return true; 
       } 

       return false; 
      } 
     }); 

     if (jettyFolders != null && jettyFolders.length > 0) { 
      for (File file : jettyFolders) { 
       IO.delete(file); 
      } 
     } 
    } 
} 

Установите специальный загрузчик классов в мы bappcontext: webAppContext.setClassLoader(new WebAppClassLoaderCustom(webAppContext));

WebAppClassLoaderCustom: (? то есть весной)

public class WebAppClassLoaderCustom extends WebAppClassLoader { 

    private HashSet<String> jarFileToClose = new HashSet<String>(); 

    public WebAppClassLoaderCustom(Context context) throws IOException { 
     super(context); 
    } 

    public WebAppClassLoaderCustom(ClassLoader parent, Context context) throws IOException { 
     super(parent, context); 
    } 

    @Override 
    public void close() { 
     System.out.println("Closing ClassLoader."); 

     jarFileToClose.clear(); 
     closeClassLoader(this); 
     // finalizeNativeLibs(this); 
     cleanupJarFileFactory(); 

     try { 
      super.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @SuppressWarnings("rawtypes") 
    private boolean closeClassLoader(ClassLoader cl) { 
     boolean res = false; 
     if (cl == null) { 
      return res; 
     } 
     Class classURLClassLoader = URLClassLoader.class; 
     Field f = null; 
     try { 
      f = classURLClassLoader.getDeclaredField("ucp"); 
     } catch (NoSuchFieldException e1) { 
      // ignore 
     } 
     if (f != null) { 
      f.setAccessible(true); 
      Object obj = null; 
      try { 
       obj = f.get(cl); 
      } catch (IllegalAccessException e1) { 
       // ignore 
      } 
      if (obj != null) { 
       final Object ucp = obj; 
       f = null; 
       try { 
        f = ucp.getClass().getDeclaredField("loaders"); 
       } catch (NoSuchFieldException e1) { 
        // ignore 
       } 
       if (f != null) { 
        f.setAccessible(true); 
        ArrayList loaders = null; 
        try { 
         loaders = (ArrayList) f.get(ucp); 
         res = true; 
        } catch (IllegalAccessException e1) { 
         // ignore 
        } 
        for (int i = 0; loaders != null && i < loaders.size(); i++) { 
         obj = loaders.get(i); 
         f = null; 
         try { 
          f = obj.getClass().getDeclaredField("jar"); 
         } catch (NoSuchFieldException e) { 
          // ignore 
         } 
         if (f != null) { 
          f.setAccessible(true); 
          try { 
           obj = f.get(obj); 
          } catch (IllegalAccessException e1) { 
           // ignore 
          } 
          if (obj instanceof JarFile) { 
           final JarFile jarFile = (JarFile) obj; 
           jarFileToClose.add(jarFile.getName()); 
           try { 
            jarFile.close(); 
           } catch (IOException e) { 
            // ignore 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
     return res; 
    } 

    @SuppressWarnings("rawtypes") 
    private boolean finalizeNativeLibs(ClassLoader cl) { 
     boolean res = false; 
     Class classClassLoader = ClassLoader.class; 
     java.lang.reflect.Field nativeLibraries = null; 
     try { 
      nativeLibraries = classClassLoader.getDeclaredField("nativeLibraries"); 
     } catch (NoSuchFieldException e1) { 
      // ignore 
     } 
     if (nativeLibraries == null) { 
      return res; 
     } 
     nativeLibraries.setAccessible(true); 
     Object obj = null; 
     try { 
      obj = nativeLibraries.get(cl); 
     } catch (IllegalAccessException e1) { 
      // ignore 
     } 
     if (!(obj instanceof Vector)) { 
      return res; 
     } 
     res = true; 
     Vector java_lang_ClassLoader_NativeLibrary = (Vector) obj; 
     for (Object lib : java_lang_ClassLoader_NativeLibrary) { 
      java.lang.reflect.Method finalize = null; 
      try { 
       finalize = lib.getClass().getDeclaredMethod("finalize", new Class[0]); 
      } catch (NoSuchMethodException e) { 
       // ignore 
      } 
      if (finalize != null) { 
       finalize.setAccessible(true); 
       try { 
        finalize.invoke(lib, new Object[0]); 
       } catch (IllegalAccessException e) { 
       } catch (InvocationTargetException e) { 
        // ignore 
       } 
      } 
     } 
     return res; 
    } 

    @SuppressWarnings("rawtypes") 
    private boolean cleanupJarFileFactory() { 
     boolean res = false; 
     Class classJarURLConnection = null; 
     try { 
      classJarURLConnection = Class.forName("sun.net.www.protocol.jar.JarURLConnection"); 
     } catch (ClassNotFoundException e) { 
      // ignore 
     } 
     if (classJarURLConnection == null) { 
      return res; 
     } 
     Field f = null; 
     try { 
      f = classJarURLConnection.getDeclaredField("factory"); 
     } catch (NoSuchFieldException e) { 
      // ignore 
     } 
     if (f == null) { 
      return res; 
     } 
     f.setAccessible(true); 
     Object obj = null; 
     try { 
      obj = f.get(null); 
     } catch (IllegalAccessException e) { 
      // ignore 
     } 
     if (obj == null) { 
      return res; 
     } 
     Class classJarFileFactory = obj.getClass(); 
     // 
     HashMap fileCache = null; 
     try { 
      f = classJarFileFactory.getDeclaredField("fileCache"); 
      f.setAccessible(true); 
      obj = f.get(null); 
      if (obj instanceof HashMap) { 
       fileCache = (HashMap) obj; 
      } 
     } catch (NoSuchFieldException e) { 
     } catch (IllegalAccessException e) { 
      // ignore 
     } 
     HashMap urlCache = null; 
     try { 
      f = classJarFileFactory.getDeclaredField("urlCache"); 
      f.setAccessible(true); 
      obj = f.get(null); 
      if (obj instanceof HashMap) { 
       urlCache = (HashMap) obj; 
      } 
     } catch (NoSuchFieldException e) { 
     } catch (IllegalAccessException e) { 
      // ignore 
     } 
     if (urlCache != null) { 
      HashMap urlCacheTmp = (HashMap) urlCache.clone(); 
      Iterator it = urlCacheTmp.keySet().iterator(); 
      while (it.hasNext()) { 
       obj = it.next(); 
       if (!(obj instanceof JarFile)) { 
        continue; 
       } 
       JarFile jarFile = (JarFile) obj; 
       if (jarFileToClose.contains(jarFile.getName())) { 
        try { 
         jarFile.close(); 
        } catch (IOException e) { 
         // ignore 
        } 
        if (fileCache != null) { 
         fileCache.remove(urlCache.get(jarFile)); 
        } 
        urlCache.remove(jarFile); 
       } 
      } 
      res = true; 
     } else if (fileCache != null) { 
      // urlCache := null 
      HashMap fileCacheTmp = (HashMap) fileCache.clone(); 
      Iterator it = fileCacheTmp.keySet().iterator(); 
      while (it.hasNext()) { 
       Object key = it.next(); 
       obj = fileCache.get(key); 
       if (!(obj instanceof JarFile)) { 
        continue; 
       } 
       JarFile jarFile = (JarFile) obj; 
       if (jarFileToClose.contains(jarFile.getName())) { 
        try { 
         jarFile.close(); 
        } catch (IOException e) { 
         // ignore 
        } 
        fileCache.remove(key); 
       } 
      } 
      res = true; 
     } 
     jarFileToClose.clear(); 

     return res; 
    } 

} 
Смежные вопросы