This commit is contained in:
Clebert Suconic 2019-01-22 17:37:13 -05:00
commit 261b05e5c4
2 changed files with 90 additions and 15 deletions

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.artemis.boot;
import java.io.File;
/**
* This class is used to remove the jar files
* in temp web dir on Windows platform where
* handles of the jar files are never released
* by URLClassLoader until the whole VM exits.
*/
public class WebTmpCleaner {
public static void main(String[] args) throws Exception {
String[] filesToClean = args[0].split(",");
//It needs to retry a bit as we are not sure
//when the main VM exists.
boolean allCleaned = false;
int maxRetries = 100;
while (!allCleaned && maxRetries-- > 0) {
allCleaned = true;
for (String f : filesToClean) {
if (!f.trim().isEmpty()) {
File file = new File(f);
if (file.exists()) {
deleteFile(file);
allCleaned = false;
}
}
}
Thread.sleep(200);
}
}
public static final void deleteFile(final File file) {
if (file.isDirectory()) {
String[] files = file.list();
for (String path : files) {
File f = new File(file, path);
deleteFile(f);
}
}
file.delete();
}
}

View File

@ -31,7 +31,6 @@ import org.apache.activemq.artemis.dto.AppDTO;
import org.apache.activemq.artemis.dto.ComponentDTO;
import org.apache.activemq.artemis.dto.WebServerDTO;
import org.apache.activemq.artemis.utils.FileUtil;
import org.apache.activemq.artemis.utils.TimeUtils;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
@ -61,10 +60,12 @@ public class WebServerComponent implements ExternalComponent {
private String consoleUrl;
private List<WebAppContext> webContexts;
private ServerConnector connector;
private String artemisHome;
@Override
public void configure(ComponentDTO config, String artemisInstance, String artemisHome) throws Exception {
webServerConfig = (WebServerDTO) config;
this.artemisHome = artemisHome;
uri = new URI(webServerConfig.bind);
server = new Server();
String scheme = uri.getScheme();
@ -237,28 +238,38 @@ public class WebServerComponent implements ExternalComponent {
public void internalStop() throws Exception {
server.stop();
if (webContexts != null) {
File tmpdir = null;
StringBuilder strBuilder = new StringBuilder();
boolean found = false;
for (WebAppContext context : webContexts) {
tmpdir = context.getTempDirectory();
if (tmpdir != null && !context.isPersistTempDirectory()) {
if (tmpdir != null && tmpdir.exists() && !context.isPersistTempDirectory()) {
//tmpdir will be removed by deleteOnExit()
//somehow when broker is stopped and restarted quickly
//this tmpdir won't get deleted sometimes
boolean fileDeleted = TimeUtils.waitOnBoolean(false, 5000, tmpdir::exists);
if (!fileDeleted) {
//because the execution order of shutdown hooks are
//not determined, so it's possible that the deleteOnExit
//is executed after this hook, in that case we force a delete.
FileUtil.deleteDirectory(tmpdir);
logger.debug("Force to delete temporary file on shutdown: " + tmpdir.getAbsolutePath());
if (tmpdir.exists()) {
ActiveMQWebLogger.LOGGER.tmpFileNotDeleted(tmpdir);
}
//However because the URLClassLoader never release/close its opened
//jars the jar file won't be able to get deleted on Windows platform
//until after the process fully terminated. To fix this here arranges
//a separate process to try clean up the temp dir
FileUtil.deleteDirectory(tmpdir);
if (tmpdir.exists()) {
ActiveMQWebLogger.LOGGER.tmpFileNotDeleted(tmpdir);
strBuilder.append(tmpdir);
strBuilder.append(",");
found = true;
}
}
}
if (found) {
String bootJar = artemisHome + File.separator + "lib" + File.separator + "artemis-boot.jar";
String[] command = {"java", "-cp", bootJar, "org.apache.activemq.artemis.boot.WebTmpCleaner", strBuilder.toString()};
ProcessBuilder pb = new ProcessBuilder(command);
pb.start();
}
webContexts.clear();
}
}