严重 [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
警告 [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [app] registered the JDBC driver [oracle.jdbc.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Artifact scjg-ms:war exploded: Error during artifact deployment. See server log for details.
信息 [Task-Thread-for-com.mchange.v2.async.ThreadPerTaskAsynchronousRunner@3fb603d0] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load [oracle/sql/converter_xcharset/lx20354.glb].
开发工具用的是 IntelliJ IDEA,运行的是web项目,数据库是oracle,昨天项目还能正常启动,突然今天就不能启动了。
当时首先看到的是第三条“信息”的内容:Illegal access: this web application instance has been stopped already. Could not load [oracle/sql/converter_xcharset/lx20354.glb],理解的意思是应用实例已经关闭,不能访问oracle/sql/converter_xcharset/lx20354.glb。很好,看不懂,应该不是错误源,因为不能直白地描述错误发生的原因,应该是前面的错误导致的连环异常从而产生这个描述。
往上看“警告”那条:The web application [app] registered the JDBC driver [oracle.jdbc.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.理解的意思是应用能注册JDBC driver但不能取消注册,为了防止内存泄漏,JDBC driver已强制取消注册。当时觉得这个是错误原因了,于是复制了这条错误信息去baidu、google,但转了一圈都没解决,而且大家的解决方案一看就感觉到跟自己的问题发生场景不匹配,有些是说自己写个监听器(在应用关闭的时候在手动取消注册驱动),但我用的是已经很成熟的Hibernate框架了,基本不会有这种低级问题的。
最后才看到第一行的“严重”信息,其实查找问题的顺序完全颠倒了,开始就应该从最前面排查,类比到平时抛出的错误堆栈也是要先看最初的源头,然后再分析问题。严重信息是:One or more listeners failed to start. Full details will be found in the appropriate container log file。于是也复制了去网络问前人,然后就发现别人的解决方案是先找详细日志,然后根据详细日志寻找最初的错误。这个思路很清晰,于是找到日志文件的位置(C:\Users\本机用户名\.IntelliJIdea2018.2\system\tomcat\Unnamed_项目名_2\logs\localhost.2018-10-18.log),打开日志文件直接翻到最后发现了详细错误原因:
Caused by: org.hibernate.exception.GenericJDBCException: Could not open connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:235)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
at org.hibernate.internal.SessionImpl.connection(SessionImpl.java:450)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:450)
... 98 more
Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228)
... 101 more
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
还是要看最下面的错误描述(A ResourcePool could not acquire a resource from its primary factory or source),把这个描述在网上搜索了一下,有篇文章列举了可能的原因https://blog.youkuaiyun.com/jdfkldjlkjdl/article/details/42170749,然后再思考了昨天跟今天的不同之处,突然想到了今天使用PL/SQL登录数据库的时候提示了用户密码还有6天就过期了,需要赶紧修改密码,当时因为嫌麻烦就没有改直接登录了,于是就尝试了一下数据库修改密码,再启动项目就没问题了。
解决方法①:直接再用PL/SQL登录一下(每次登录都会提示密码即将到期),修改密码为原来的密码(可以跟原密码相同),这种方法最方便。
解决方法②:以系统管理员登录sql命令行界面然后修改密码,以及修改密码为永不过期(适合开发人员),详细操作参照这篇文章https://blog.youkuaiyun.com/qin_zhimou/article/details/52448051
总结:定位问题的能力还有待加强