Tomcat зависает при развертывании приложения SpringBoot

Я пытаюсь установить некоторые приложения (4 веб-приложения с весенней загрузкой) в Tomcat 9, я заметил, что 2 из них отображают журнал Tomcat:

17-Nov-2016 00:15:07.110 INFO [localhost-startStop-2] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /Users/viruskimera/apache-tomcat-9.0.0.M11/webapps/ftpoutbound990-0.0.1-SNAPSHOT.war

И он остается таким, просто при его развертывании не отображается DEPLOYMENT FINISHED. дело в том, что приложение РАБОТАЕТ, даже если оно не выглядит полностью РАЗВЕРНУТЫМ. (Я вижу, что мои записи log4j и файлы обрабатываются в отслеживаемой папке)

Эти приложения отслеживают 2 разные папки с помощью Java watchService со следующим кодом:

пакет com.ftpoutbound990.monitor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.ftpoutbound990.client.FtpoutboundApp;

@Component
public class MonitorDirectory {

    final static Logger logger = Logger.getLogger(MonitorDirectory.class);

    @Autowired
    private FtpoutboundApp ftpoutboundapp;

    @Value("${folder990}")
    private String folder990;

    public void startMonitoring() throws IOException, InterruptedException {
        logger.info("INICIO DE MONITOREO DE ARCHIVOS 990");
        try (WatchService watchService = FileSystems.getDefault().newWatchService()) {

            Path faxFolder = Paths.get(folder990);

            WatchService watchmyservice = FileSystems.getDefault().newWatchService();
            faxFolder.register(watchmyservice, StandardWatchEventKinds.ENTRY_CREATE);

            boolean valid = true;
            do {
                try {
                    WatchKey watchKey = watchmyservice.take();

                    for (WatchEvent event : watchKey.pollEvents()) {
                        WatchEvent.Kind kind = event.kind();
                        if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
                            String fileName = event.context().toString();
                            logger.info("ARCHIVO NUEVO:" + fileName);
                            boolean isGrowing = false;
                            Long initialWeight = new Long(0);
                            Long finalWeight = new Long(0);
                            Path child = faxFolder.resolve(folder990 + fileName);
                            do {
                                initialWeight = child.toFile().length();
                                Thread.sleep(1000);
                                finalWeight = child.toFile().length();
                                isGrowing = initialWeight < finalWeight;
                                logger.info("AUN COPIANDO ARCHIVO:" + fileName);
                            } while (isGrowing);
                            logger.info("LISTO ARCHIVO:" + fileName);
                            getFile(fileName);
                        }
                    }
                    valid = watchKey.reset();
                    // Thread.sleep(1000 * 10);
                } catch (InterruptedException | ClosedWatchServiceException e) {
                    //watchmyservice.close();
                    Thread.currentThread().interrupt();
                }

            } while (valid);
        }
    }

    public void getFile(String fileName) throws IOException {

        File file = new File(folder990 + fileName);
        ftpoutboundapp.createGateway(file);
    }

}

Если я удалю Do-While, приложения будут развернуты! Но почему? Это стандартный код службы наблюдения Java, может ли кто-нибудь помочь мне понять, что мне не хватает/в чем проблема? дело в том, что Tomcat не развертывает мое 4-е приложение, потому что продолжает развертывать 3-е. Заранее спасибо за помощь


РЕДАКТИРОВАТЬ 1: ДОБАВЛЕНИЕ ПОТОКА

28-Dec-2016 17:57:27.558 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
28-Dec-2016 17:57:27.559 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"]
28-Dec-2016 17:57:27.613 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"]
28-Dec-2016 17:57:27.664 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service Catalina
28-Dec-2016 17:57:27.664 SEVERE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.startup.HostConfig.deployWARs Error waiting for multi-thread deployment of WAR files to complete
 java.lang.InterruptedException
    at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:404)
    at java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:744)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:407)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1595)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:280)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:92)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1136)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1372)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1376)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1344)
    at java.lang.Thread.run(Thread.java:745)

28-Dec-2016 18:00:21.904 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/9.0.0.M11
28-Dec-2016 18:00:21.907 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Oct 6 2016 18:54:10 UTC
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         9.0.0.0
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Mac OS X
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            10.9.5
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          x86_64
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_73-b02
28-Dec-2016 18:00:21.908 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
28-Dec-2016 18:00:21.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /Users/viruskimera/apache-tomcat-9.0.0.M11
28-Dec-2016 18:00:21.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /Users/viruskimera/apache-tomcat-9.0.0.M11
28-Dec-2016 18:00:21.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/Users/viruskimera/apache-tomcat-9.0.0.M11/conf/logging.properties
28-Dec-2016 18:00:21.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
28-Dec-2016 18:00:21.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
28-Dec-2016 18:00:21.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
28-Dec-2016 18:00:21.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/Users/viruskimera/apache-tomcat-9.0.0.M11
28-Dec-2016 18:00:21.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/Users/viruskimera/apache-tomcat-9.0.0.M11
28-Dec-2016 18:00:21.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/Users/viruskimera/apache-tomcat-9.0.0.M11/temp
28-Dec-2016 18:00:21.910 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /Users/viruskimera/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
28-Dec-2016 18:00:22.063 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
28-Dec-2016 18:00:22.093 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
28-Dec-2016 18:00:22.096 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
28-Dec-2016 18:00:22.098 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
28-Dec-2016 18:00:22.100 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 604 ms
28-Dec-2016 18:00:22.145 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
28-Dec-2016 18:00:22.145 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/9.0.0.M11
28-Dec-2016 18:00:22.224 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /Users/viruskimera/apache-tomcat-9.0.0.M11/webapps/ftpoutbound990-0.0.1-SNAPSHOT.war
28-Dec-2016 18:00:26.346 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.6.RELEASE)

person viruskimera    schedule 17.11.2016    source источник


Ответы (3)


Выстрел в слепую..

Простой обзор вашего кода показывает, что если внутри try catch возникает исключение, логический флаг valid остается true, вызывая бесконечный цикл.

Следовательно, установите флаг false в теле блока catch!

person Amanuel Nega    schedule 27.12.2016
comment
Я проверяю это. - person viruskimera; 28.12.2016

Поток развертывания tomcat, похоже, вызывает метод startMonitoring. Как и предполагалось, этот метод никогда не возвращается назад, и, следовательно, развертывание не завершается.

Чтобы это исправить, нужно запустить метод мониторинга в отдельном (или фоновом) потоке.

Ниже приведен рефакторинг примера, который может быть полезен.

Кроме того, один экземпляр экземпляра WatcherService может использоваться для просмотра нескольких каталогов.

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MonitorDirectory {

    final static Logger logger = Logger.getLogger(MonitorDirectory.class);

    @Autowired
    private FtpoutboundApp ftpoutboundapp;

    @Value("${folder990}")
    private String folder990;

    private WatchService watchService;

    private ExecutorService eventLoop = Executors.newFixedThreadPool(1);

    @PostConstruct
    public void init() throws IOException, InterruptedException {
        watchService = FileSystems.getDefault().newWatchService();
        eventLoop.submit((Runnable) () -> {
            try {
                startMonitoring();
            } catch (Exception e) {
                logger.error("ERROR...", e);
            }
        });
    }

    @PreDestroy
    public void destroy() throws IOException {
        eventLoop.shutdownNow();
        if (watchService != null) {
            watchService.close();
        }
    }

    public void startMonitoring() throws IOException, InterruptedException {
        logger.info("INICIO DE MONITOREO DE ARCHIVOS 990");
        Path faxFolder = Paths.get(folder990);
        WatchKey watchKey = faxFolder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
        boolean valid = true;
        do {
            for (WatchEvent<?> event : watchKey.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();
                if (StandardWatchEventKinds.ENTRY_CREATE.equals(kind)) {
                    String fileName = event.context().toString();
                    logger.info("ARCHIVO NUEVO:" + fileName);
                    boolean isGrowing = false;
                    Long initialWeight = new Long(0);
                    Long finalWeight = new Long(0);
                    Path child = faxFolder.resolve(folder990 + fileName);
                    do {
                        initialWeight = child.toFile().length();
                        Thread.sleep(1000);
                        finalWeight = child.toFile().length();
                        isGrowing = initialWeight < finalWeight;
                        logger.info("AUN COPIANDO ARCHIVO:" + fileName);
                    } while (isGrowing);
                    logger.info("LISTO ARCHIVO:" + fileName);

                    getFile(fileName);
                }
                valid = watchKey.reset();
            }
        } while (valid);
    }

    public void getFile(String fileName) throws IOException {
        File file = new File(folder990 + fileName);
        ftpoutboundapp.createGateway(file);
    }

}
person skadya    schedule 28.12.2016
comment
я пытаюсь это - person viruskimera; 28.12.2016
comment
посмотри мой EDIT 1, это локальный прогон, но боюсь на сервере будет то же самое. Я применил ваш код и зависает так же, затем я закрываю tomcat и отображает: посмотрите на строку СЕРЬЕЗНАЯ ОШИБКА: 28 декабря 2016 г. 17: 57: 27.664, в ней говорится об ошибке, ожидающей завершения развертывания. Я даже пытался изменить весеннюю версию с v1.4.1.RELEASE на v1.3.6.RELEASE, поскольку 1 приложение, использующее v1.4.1.RELEASE, развертывается правильно, но происходит то же самое. - person viruskimera; 29.12.2016
comment
Кстати, я заметил, что потребление памяти процессом Java увеличивается. - person viruskimera; 29.12.2016
comment
Я предполагаю, что startMonitoring вызывается только из фонового потока. Также выглядит немного странно, что исключение тайм-аута возникает при остановке сервера tomcat (можете ли вы попробовать после добавления условия Thread.interrupted() в условие while. Например, while(valid && !Thread.interrupted()). - person skadya; 29.12.2016
comment
выглядит одинаково, обратите внимание, что приложение всегда запускается, даже если развертывание не завершено, потому что приложения показывают сообщение о запуске мониторинга в файле log4j, но после этого tomcat зависает (он не развертывает больше приложений) - person viruskimera; 29.12.2016
comment
это работает только на 1 ПК, мы скопировали tomcat, jdk, все... Но пока не уверены, почему не работает на сервере... - person viruskimera; 30.12.2016
comment
похоже на проблему с конфигурацией, но все еще не уверен, что... если это не решено, я буду использовать задачу SCHEduled для мониторинга папки (последний вариант...) - person viruskimera; 30.12.2016

Можете ли вы проверить несколько вещей ниже.

Вызывается ли Component MonitorDirectory только один раз в ваших приложениях. Если нет, вам может потребоваться объявить 'eventLoop' как статический и проверить инициализацию в PostConstruct, чтобы избежать многократной инициализации и вызова.

Кроме того, executorservice инициализируется с пулом потоков, равным 1, и если в вашем приложении инициализируется объект Multiple MonitorDirectory, это может привести к зависанию развертывания.

Есть ли шанс, что размер файла может уменьшаться в среде сервера. Это может привести к бесконечному зацикливанию проверки isGrowing.

person srivelayutha raja    schedule 02.01.2017
comment
Часть этого кода была предложена пользователем Skadya выше, но я бы сказал, что MOnitor вызывается только 1 раз, как можно было вызывать monitor более одного раза? Обратите внимание, что это работает на 1 ПК, но мы скопировали все с этого ПК (jdk, tomcat и т. д.). Я пытался использовать аннотацию @scheduled, кажется, работает, но все еще имеет дело с некоторыми проблемами. - person viruskimera; 03.01.2017
comment
В Spring всякий раз, когда объект инициализируется, будет вызываться метод postConstruct. Если приложение может создавать несколько объектов для одного и того же объекта (типичное веб-приложение с параллелизмом), это может произойти. - person srivelayutha raja; 03.01.2017