2017-02-01 7 views
0

Я запускаю tomcat под/внутри затмения при разработке веб-приложения. Веб-приложение использует hsqldb во встроенном режиме, с помощью гибернации и guice. Кажется, что все работает нормально, за исключением случаев, когда я останавливаю tomcat. Eclipse имеет зеленую кнопку запуска и красную кнопку остановки для Tomcat. Когда я нажимаю кнопку «Стоп», она не сразу останавливается, как это было до того, как я добавил hibernate и hsqldb в микс. Теперь он ждет несколько секунд, а затем затмение дает мне диалоговое окно о невозможности остановить tomcat и нажать «ОК», чтобы принудительно завершить его.отмена регистрации драйвера JDBC?

Кто-нибудь знает, что мне нужно сделать, чтобы исправить это? Я нашел несколько других ответов, говорящих о том, чтобы поместить файл hsqldb jar в каталог lib tomcat, но мне было интересно, что я могу что-то сделать, это немного менее решительно.

Вот что на выходе ошибки из кота (в окне консоли Eclipse):

Jan 31, 2017 7:04:11 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc 
WARNING: The web application [basic] registered the JDBC driver [org.hsqldb.jdbc.JDBCDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 
Jan 31, 2017 7:04:11 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 
WARNING: The web application [basic] appears to have started a thread named [HSQLDB Timer @276f0355] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
java.lang.Object.wait(Native Method) 
org.hsqldb.lib.HsqlTimer$TaskQueue.park(Unknown Source) 
org.hsqldb.lib.HsqlTimer.nextTask(Unknown Source) 
org.hsqldb.lib.HsqlTimer$TaskRunner.run(Unknown Source) 
java.lang.Thread.run(Thread.java:745) 
Jan 31, 2017 7:04:11 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 
WARNING: The web application [basic] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java.lang.Thread.run(Thread.java:745) 
Jan 31, 2017 7:04:11 PM org.apache.catalina.loader.WebappClassLoaderBase checkThreadLocalMapForLeaks 
SEVERE: The web application [basic] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [[email protected]]) and a value of type [org.hibernate.internal.SessionImpl] (value [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 
+0

Вам необходимо ЗАМЕНЯТЬ базу данных, когда вы останавливаете Tomcat. – fredt

+0

lumpynose is rigth, у вас есть два решения: - запустите «SHUTDOWN;» как команда SQL где-то в конце вашего приложения ИЛИ используйте shutdown = true в вашей строке подключения следующим образом: _Connection = DriverManager.getConnection («jdbc: hsqldb: file: mydb; shutdown = true», «SA», ""); –

ответ

0

У меня есть глупый ответ, но я покажу вам, что я сделал.

@JulienR: У меня уже было shutdown = true в моем файле persistence.xml для значения javax.persistence.jdbc.url.

Я создал ServletContextListener и добавил его в свой файл web.xml; вот код. Первая часть, которая использует EntityManager для выдачи команды SHUTDOWN, - это мой код. Код для ClassLoader и драйвера eyeballing Я получил here. Таким образом, с этим он больше не жалуется на HSQLDB, но я все еще получаю ПРЕДУПРЕЖДЕНИЕ о двух потоках, которые не были остановлены (и я должен ждать, пока затмение перестанет ждать его). Я добавил соответствующие строки из журнала.

public class BasicServletContextListener implements ServletContextListener { 
    private final transient Logger log = 
     LoggerFactory.getLogger(BasicServletContextListener.class); 

    // private final Provider<EntityManager> entityManagerProvider; 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
     this.log.debug("contextEvent: {}", event.toString()); 

     final EntityManagerFactory entityManagerFactory = 
      Persistence.createEntityManagerFactory("ilmp"); 

     final EntityManager entityManager = 
      entityManagerFactory.createEntityManager(); 

     entityManager.getTransaction().begin(); 

     final Query query = 
      entityManager.createNativeQuery("SHUTDOWN COMPACT;"); 

     this.log.debug("query: {}", query.executeUpdate()); 

     entityManager.getTransaction().commit(); 

     entityManager.close(); 

     // Now deregister JDBC drivers in this context's ClassLoader: 
     // Get the webapp's ClassLoader 
     final ClassLoader cl = Thread.currentThread().getContextClassLoader(); 
     // Loop through all drivers 
     final Enumeration<Driver> drivers = DriverManager.getDrivers(); 
     while (drivers.hasMoreElements()) { 
      final Driver driver = drivers.nextElement(); 
      if (driver.getClass().getClassLoader() == cl) { 
       // This driver was registered by the webapp's 
       // ClassLoader, so deregister it: 
       try { 
        this.log.info("Deregistering JDBC driver {}", driver); 
        DriverManager.deregisterDriver(driver); 
       } 
       catch (final SQLException ex) { 
        this.log.error("Error deregistering JDBC driver {}", driver, 
            ex); 
       } 
      } 
      else { 
       // driver was not registered by the webapp's 
       // ClassLoader and may be in use elsewhere 
       this.log.trace(
           "Not deregistering JDBC driver {} as it does not belong to this webapp's ClassLoader", 
           driver); 
      } 
     } 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     this.log.debug("contextEvent: {}", event.toString()); 
    } 
} 

>

INFO: 2017-Feb-01 19:05:36.023 [localhost-startStop-2] org.hibernate.hql.internal.QueryTranslatorFactoryInitiator.initiateService.47: HHH000397: Using ASTQueryTranslatorFactory 
Hibernate: SHUTDOWN COMPACT; 
INFO: 2017-Feb-01 19:05:36.226 [localhost-startStop-2] sun.reflect.NativeMethodAccessorImpl.invoke0.-2: Database closed 
INFO: 2017-Feb-01 19:05:36.273 [localhost-startStop-2] sun.reflect.NativeMethodAccessorImpl.invoke0.-2: open start - state not modified 
INFO: 2017-Feb-01 19:05:36.351 [localhost-startStop-2] sun.reflect.NativeMethodAccessorImpl.invoke0.-2: Database closed 
DEBUG: 2017-Feb-01 19:05:36.460 [localhost-startStop-2] com.objecteffects.basic.persist.BasicServletContextListener.contextDestroyed.42: query: 0 
INFO: 2017-Feb-01 19:05:36.460 [localhost-startStop-2] com.objecteffects.basic.persist.BasicServletContextListener.contextDestroyed.59: Deregistering JDBC driver [email protected] 
Feb 01, 2017 7:05:36 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 
WARNING: The web application [basic] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java.lang.Thread.run(Thread.java:745) 
Feb 01, 2017 7:05:36 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 
WARNING: The web application [basic] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: 
sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java.lang.Thread.run(Thread.java:745) 
Feb 01, 2017 7:05:36 PM org.apache.catalina.loader.WebappClassLoaderBase checkThreadLocalMapForLeaks 
SEVERE: The web application [basic] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [[email protected]]) and a value of type [org.hibernate.internal.SessionImpl] (value [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.objecteffects.basic.persist.TumblrSecretsEntity#1], EntityKey[com.objecteffects.basic.persist.TumblrSecretsEntity#2]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 
Feb 01, 2017 7:05:36 PM org.apache.coyote.AbstractProtocol stop 
INFO: Stopping ProtocolHandler ["http-nio-8080"] 
Feb 01, 2017 7:05:36 PM org.apache.coyote.AbstractProtocol stop 
INFO: Stopping ProtocolHandler ["ajp-nio-8009"] 
Feb 01, 2017 7:05:36 PM org.apache.coyote.AbstractProtocol destroy 
INFO: Destroying ProtocolHandler ["http-nio-8080"] 
Feb 01, 2017 7:05:36 PM org.apache.coyote.AbstractProtocol destroy 
INFO: Destroying ProtocolHandler ["ajp-nio-8009"] 

Тупой ответ, что я смотрел на мою установку на то, что я написал несколько лет назад (я вышел в отставку и просто dinking вокруг, пытаясь написать что-то для себя) и добавления строки конфигурации c3p0, которые я использовал ранее для этого persistence.xml, заставляют его закрываться без задержки, хотя я все еще получаю кучу предупреждений о потоках зомби. Вот соответствующие строки (все еще прокомментированные).

<!--    <property --> 
<!--     name="hibernate.c3p0.min_size" --> 
<!--     value="5" /> --> 

<!--    <property --> 
<!--     name="hibernate.c3p0.max_size" --> 
<!--     value="20" /> --> 

<!--    <property --> 
<!--     name="hibernate.c3p0.timeout" --> 
<!--     value="1800" /> --> 

<!--    <property --> 
<!--     name="hibernate.c3p0.max_statements" --> 
<!--     value="50" /> -->