I know there’s many questions regarding this exception, however, I believe I’ve tried everything for many days, without any luck yet. As this is a production server, I can only work on this after midnight 🙁
I have a Tomcat app. Recently, I’ve updated the connection pool, in order to use Tomcat’s jdbc-connection pool. In my Windows developing machine, everything works fine, but now that I’m trying to implement this on my Linux Server, I get this exception (see title) when ever my app tries to connect to MySQL.
I’m using “Easy Tomcat 7” which is supposed to be the same as the regular version of Tomcat, only it comes with the CPanel software.
I just need this DB to be available for this app (not multiple app’s).
This is my java DB class:
public class DBUtil {
static DataSource ds;
static {
try {
Context context = new InitialContext();
ds = (DataSource)context.lookup("java:comp/env/jdbc/rhwebDB");
} catch (NamingException e) {
e.printStackTrace();
System.out.println("DBUtil.NamingException" + e);
} catch(Exception e) {
System.out.println(e);
}
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
This is my context.xml file, which is located on myAppDirectory/META-INF
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/rhwebDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="20"
minIdle="3"
maxIdle="15"
maxWait="10000"
initialSize="3"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
username="dbuser"
password="dbpwd"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/rhmexweb_rhweb"/>
</Context>
I don’t use WAR files. I just upload files to my server and re-start tomcat when needed, which normally works just fine.
In case this is relevant too, Tomcat’s server.xml file has this settings for this website. I’ve also tried adding parameter copyXML=”true”, with no luck so far:
<Host name="rhweb.net" appBase="webapps">
<Alias>www.rhweb.net</Alias>
<Context path="" reloadable="false" docBase="/home/rhweb/public_html" debug="1"/>
</Host>
Here’s the full stacktrace I get when my app tries to establish a connection with MySQL:
javax.naming.NameNotFoundException: Name [jdbc/rhwebDB] is not bound in this Context. Unable to find [jdbc].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(InitialContext.java:415)
at util.DBUtil.<clinit>(DBUtil.java:23)
at Solutio.AdminRH.Entity.ISeguridadAdminDB.verificaUsuario(ISeguridadAdminDB.java:142)
at org.apache.jsp.menu_jsp._jspService(menu_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
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)
I’ve also tried adding these lines in my app’s web.xml file (which I hadn’t had to include in my windows machine)
<resource-ref>
<description>MySQL RhWeb Datasource</description>
<res-ref-name>jdbc/rhwebDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
And when I include those lines, the exception I get is this one:
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
It seems that Tomcat can’t find my META-INF/context.xml file, or it doesn’t recognize this link:
ds = (DataSource)context.lookup(“java:comp/env/jdbc/rhwebDB”);
My linux, Tomcat and JDK versions are:
CentOS release 6.8 (Final)
Apache Tomcat/7.0.42
java version “1.7.0_131”
I don’t know what else can I try to fix this. Any help will be really appreciated
UPDATE
I still haven’t found a solution yet. I’ve realized some probable configuration issues that may be related to all this:
The app is located here:
/home/rhmexweb/public_html
However, on the Tomcat’s server.xml file the host definition for this website is:
<Host name="rhweb.mx" appBase="webapps">
<Context path="" reloadable="false" docBase="/home/rhmexweb/public_html" />
</Host>
The reason why is not located on the webapps directory, is because CPanel automatically creates every account in /home/account-name/public_html, so that’s why a context element is needed here (I guess). If I remove the whole Context tag, and instead I use appBase=”/home/rhmexweb/public_html”, then Tomcat won’t find all the jars and content from the WEB-INF folder (/home/rhmexweb/public_html/WEB-INF). I mentioned this because I added the parameter copyXML=”true” just to see where would tomcat tries to copy context.xml file, and if it changes it’s name, but it turns out that there are two different paths. First I got a writing permissions exception when I first include that parameter, and it was trying to create a folder here:
/var/lib/easy-tomcat7/webapps/
This path, only contains folders of the default tomcat app’s (manager, examples & host-manager)
The folder where all the websites are listed and all the compiled jsp files are is this one:
/usr/local/easy/etc/easy-tomcat7/Catalina/
however, in /usr/local/easy/etc/easy-tomcat7/Catalina/rhweb.mx/ there is no WEB-INF directory.
Anyway, what I’d like to know is if having a Context element in the host definition might be a problem for Tomcat in order to find the appPath/META-INF/context.xml file.
2
Answers
I finally solved it!!
Maybe it's a workaround but it works.
I copied the app-directory/META-INF/context.xml file to:
$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default (notice the "default" part of the filename)
As it's stated in the Tomcat's documentation
Now I don't need to add any entry in my app's web.xml file, neither a META-INF/context.xml file in my app directory (which is not located on the Tomcat's/webapps directory)
All I need is to put a context.xml.default file (containing it's DB information) in every folder listed in this path:
$CATALINA_BASE/conf/[enginename]/
which in my server is:
/usr/local/easy/etc/easy-tomcat7/Catalina/
so for this website, I copied it to:
/usr/local/easy/etc/easy-tomcat7/Catalina/myDomain.com/
You'll notice my path is different from the one specified in Tomcat's documentation, and that's because I'm using CPanel's easy-tomcat 7 which has a different structure than the regular Tomcat. That fact made everything more complicated when looking for a solution, even if it's called easy-tomcat.
About why Tomcat could never read the /META-INF/context.xml, that remains a mistery, but honestly, I don't care much since this method it's easier (one file instead of two)
It looks like there is something wrong with the
context.xml
setup. Tryserver.xml
or/META-INF/context.xml
to see if it behaves any different.You can try moving the configuration to the
server.xml
as per Tomcat 7 docs:link to global resource in the
context.xml
:and then refer to it in
/WEB-INF/web.xml
like you already do:If this won’t work you can check few other approaches discussed in this answer.