web services.Error: com.mysql.jdbc.CommunicationsException: Communications link failure java.io.EOFException [duplicate] - mysql

My webapp is running on Tomcat 5.5, I declared the datasource in web.xml:
<resource-ref>
<res-ref-name>jdbc/OrdiniWebDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
In context.xml (tomcat conf):
<Resource
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
maxActive="100"
maxIdle="30"
maxWait="10000"
name="jdbc/OrdiniWebDS"
password="[mypassword]"
type="javax.sql.DataSource"
url="jdbc:mysql://[myHost:port]/ordiniweb"
username="[myusername]"
/>
The database is a MySql 5.0.
Everything works well except that sometimes, after several hours of "unuse", at first access I got this Exception:
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1956)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2368)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2867)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1616)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1708)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3255)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1293)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1428)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93)
at com.blasetti.ordiniweb.dao.OrdiniDAO.caricaOrdine(OrdiniDAO.java:263)
...
** END NESTED EXCEPTION **
Last packet sent to the server was 0 ms ago.
com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2579)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2867)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1616)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1708)
com.mysql.jdbc.Connection.execSQL(Connection.java:3255)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1293)
com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1428)
org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93)
com.blasetti.ordiniweb.dao.OrdiniDAO.caricaOrdine(OrdiniDAO.java:263)
...
I need to refresh and it works well again. Any idea? Thanks.

MySQL drops unused connections after a while because it assumes that the other side forgot to close it.
What you need to do is to configure a check that Tomcat should apply before it reuses a pooled connection. To do this, add ?autoReconnect=true&useUnicode=true&characterEncoding=utf8 to the end of the URL and add validationQuery="Select 1" to the Resource element:
<Resource
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
maxActive="100"
maxIdle="30"
maxWait="10000"
name="jdbc/OrdiniWebDS"
password="[mypassword]"
type="javax.sql.DataSource"
url="jdbc:mysql://[myHost:port]/ordiniweb?autoReconnect=true&useUnicode=true&characterEncoding=utf8"
username="[myusername]"
validationQuery="Select 1"
/>
[EDIT] This page gives more details: Configuring a MySQL Datasource in Apache Tomcat

Related

Trying to install HikariCP on tomcat 7 and getting javax.naming.NamingException on startup

I am trying to configure HikariCP as my datasource connection pool on tomcat 7 with mysql. Here is my context file...
<?xml version="1.0" encoding="UTF-8"?>
<Context allowCasualMultipartParsing="true">
<Resource name="jdbc/application" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSource.implicitCachingEnabled="true"
dataSource.user="root"
dataSource.password="pass"
dataSource.url="jdbc:mysql://localhost:3306/Database"/>
</Context>
But on startup I get this error...
WARNING: Failed to retrieve JNDI naming context for container
javax.naming.NamingException: No naming context bound to this class loader
How can I configure HikariCP-2.3.0 on tomcat?
may be this could help you
Configuring the Tomcat Definitions
Location of your JNDI datasource definitions depends upon the scope for the connections. You can define them globally by specifying them in Tomcat's conf/server.xml and conf/context.xml, or you can scope them to individual applications by defining them in conf/Catalina/localhost/WebAppContext.xml (where WebAppContext is the web application context for the app, basically the directory name from Tomcat's webapps directory).
<Resource name="jdbc/LiferayPool" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="org.postgresql.ds.PGSimpleDataSource"
dataSource.url="jdbc:postgresql://localhost:5432/lportal"
dataSource.implicitCachingEnabled="true"
dataSource.user="user"
dataSource.password="pwd" />
https://community.liferay.com/blogs/-/blogs/tomcat-hikaricp

Connection pool issue: Connection has already been closed

I am using Grails 2.4.2, Tomcat 7 and MySQL 5.6.17 and I am having problem with the connection pool. After a while my application randomly reports the following errors.
2014-07-24 08:24:35,012 [http-bio-127.0.0.1-50000-exec-9] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Connection has already been closed.
and
2014-07-25 10:55:12,018 [http-bio-127.0.0.1-50000-exec-6] ERROR org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver - SQLException occurred when processing request: [GET] /controller/index
Connection has already been closed.. Stacktrace follows:
java.sql.SQLException: Connection has already been closed.
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:189)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Here is the JNDI datasource resource defined in $TOMCAT_HOME/conf/context.xml
<Resource name="jdbc/xxx" auth="Container" type="javax.sql.DataSource"
username="user" password="password"
driverClassName="com.mysql.jdbc.Driver"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
url="jdbc:mysql://localhost:3306/db?generateSimpleParameterMetadata=true"
validationQuery="SELECT 1"
validationInterval="30000"
initialSize="5"
maxActive="50"
minIdle="5"
maxIdle="30"
maxWait="10000"
timeBetweenEvictionRunsMillis="5000"
minEvictableIdleTimeMillis="55000"
testOnBorrow="true"
removeAbandoned="true"
removeAbandonedTimeout="55"/>
Does anyone of you have any experience on this topic and can help me on this?
Switching to C3P0 connection pool did the job.
<Resource auth="Container"
description="DB Connection"
driverClass="com.mysql.jdbc.Driver"
maxPoolSize="10"
minPoolSize="2"
acquireIncrement="1"
name="jdbc/xxx"
user="user"
password="password"
factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="jdbc:mysql://localhost:3306/db?generateSimpleParameterMetadata=true" />

context.xml in Tomcat without DB password

I have a servlet application running on Tomcat 7 and wish to connect to MySQL locally.
My local MySQL user does not have a password, and I wish to keep it that way for convenience.
However, if I do not use the password attribute under Resource in context.xml, it tries to connect to the DB without the username even though I have set it.
How can I connect without a password?
Below is my context.xml file, if it matters.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="whirlwin"
password="removeMe"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/theDB?autoReconnect=true"/>
</Context>
Have you tried leaving empty string for the password?
If this doesn't help, post what you get running mysql -uwhirlwin -hlocalhost from the command line.

Cannot create resource instance in Tomcat7

I'm trying to configure connection pool in Tomcat 7. Here is code:
part of server.xml:
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource
name="jdbc/testDataSource"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/delta_server"
username="test" password="test"
validationQuery="select count (*) from session_contexts"
/>
web.xml configuration:
<resource-ref>
<description>
Sample JNDI DataSource resource reference
</description>
<res-ref-name>jdbc/testDataSource</res-ref-name>
<res-type>java.sql.DatSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and access from jsp page:
Context initialContext = new InitialContext();
Context envContext = (Context) initialContext.lookup("java:/comp/env");
conn = (Connection) envContext.lookup("jdbc/testDataSource");
But unfortunately I get exception:
javax.naming.NamingException: Cannot create resource instance
org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:146)
javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
org.apache.naming.NamingContext.lookup(NamingContext.java:826)
org.apache.naming.NamingContext.lookup(NamingContext.java:145)
org.apache.naming.NamingContext.lookup(NamingContext.java:814)
org.apache.naming.NamingContext.lookup(NamingContext.java:159)
org.apache.jsp.index_jsp._jspService(index_jsp.java:91)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:389)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
How can I fix it?
Thank you.
Your configuration looks pretty much OK (except for some typos in your web.xml file; the <res-type>java.sql.DatSource</res-type> should be <res-type>javax.sql.DataSource</res-type>).
But the problem I think is the fact that you are declaring the database resource inside the server.xml file.
Normally the application resources should be declared in the context.xml file of the application and only be declared in server.xml if they are shared between applications. So my suggestion is to declare the jdbc/testDataSource resource in your context.xml file. That should be one way to make it work.
If you must absolutely have a global resource then in your context.xml file you must add a resource link to it or it won't be visible by default.
This context is distinct from the per-web-application JNDI contexts described in the JNDI Resources HOW-TO. The resources defined in this element are not visible in the per-web-application contexts unless you explicitly link them with <ResourceLink> elements.
So the second way to make it work is to leave the resource declared in server.xml but then add something like this in your context.xml file:
<ResourceLink global="jdbc/testDataSource"
name="jdbc/testDataSource"
type="javax.sql.DataSource" />

Keep JDBC references outside web.xml to deploy in Jetty, like in tomcat

I try to move some services from my Tomcat Server to Jetty, just to make some comparisons. Obviously I don't want to change my services, but I experiment some issues to deploy them with JDBC.
My services all use the same database to access datas, so I wrote my own library to make my requests. The services don't have any informations about the database, they just know they have to use the library. In this library I make connections with the database using this kind of code:
InitialContext ictx = new InitialContext();
Context envCtx = (Context) ictx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/mysql");
In Tomcat my services work well just adding a line in context.xml:
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/mysql" username="login" password="password" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/mysql" />
So I just want to do the same in Jetty. I added the following block in my jetty.xml:
<New id="mysql" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/mysql</Arg>
<Arg>
<New class="org.apache.commons.dbcp.BasicDataSource">
<Set name="driverClassName">com.mysql.jdbc.Driver</Set>
<Set name="url">jdbc:mysql://localhost:3306/mysql</Set>
<Set name="username">login</Set>
<Set name="password">password</Set>
</New>
</Arg>
</New>
The server starts well and seem to work, but I get an error when I try to access to my services. In jetty's manual I found it's explictly written that I have to add some informations in web.xml like:
<resource-ref>
<description>My DataSource Reference</description>
<res-ref-name>jdbc/DSTest</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
So I wonder if there is any other solution, than write the same lines in all my web.xml services' files? Like adding a common xml file for all my server with the same informations ?
You can add it to the webdefault.xml that is used as the foundation for processing web.xml.
This file is typically located in etc/webdefault.xml of the distribution.
cheers