javax.naming.NameNotFoundException: Name [jdbc/rhwebDB] is not bound in this Context. Unable to find [jdbc]
Asked Answered
D

2

12

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.

Drifter answered 23/5, 2018 at 7:52 Comment(8)
Please post the full exception stack trace.Janiculum
that's was the only exception stack trace since the Exception was handled inside a "try catch". I can mofify the code in order to get the full stack trace, however, I'll have to do it after midnight since this is a production server.Drifter
After some changes I've made, now the exception I'm getting is this one: DBUtil.NamingException - javax.naming.NameNotFoundException: Name [rhwebDB] is not bound in this Context. Unable to find [rhwebDB]. Should I put this on a new question?? By the way, the exception I was getting last night was because I tried to use JDK 1.8 with Tomcat 7. Then I read they weren't compatible, so now I'm using JDK 1.7Drifter
Your question doesn't contain the full stacktrace, just the error message. In any case. Maybe change the name of the resource to jdbc/rhwebDB (I'm not sure if jdbc/ is required, but all examples contain it), and change the JDNI lookup accordingly. Also checkout tomcat.apache.org/tomcat-7.0-doc/…Janiculum
That's all the stacktrace I get when I catch the error. Code won't compile if I don't use try/catch. <code> } catch (NamingException e) { System.out.println("DBUtil.NamingException" + e); } catch(Throwable e) { System.out.println(e); System.out.println("Cause = " + e.getCause()); } </code> I've already tried adding the jdbc/rhwebDB in both places, with no luckDrifter
Sorry for the above code format, I tried to do it right but you only have 5 minutes for editing. } catch (NamingException e) { System.out.println("DBUtil.NamingException" + e); } catch(Throwable e) { System.out.println(e); System.out.println("Cause = " + e.getCause()); }Drifter
Comments are not really suitable for code, in any case, you need to use e.printStackTrace() to get the full stack trace (or an actual logging framework that does it for you). The toString() only shows the exception name + message.Janiculum
Any one? any idea?Drifter
D
4

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)

Drifter answered 7/6, 2018 at 6:40 Comment(0)
C
8

It looks like there is something wrong with the context.xml setup. Try server.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:

<GlobalNamingResources>
  <Resource
    name="jdbc/rhweb_rhwebDB"
    auth="Container"
    type="javax.sql.DataSource"
    ...
  />
</GlobalNamingResources>

link to global resource in the context.xml:

<Context>
  <ResourceLink
    global="jdbc/rhweb_rhwebDB"
    name="jdbc/rhwebDB"
    type="javax.sql.DataSource"
  />
</Context>

and then refer to it in /WEB-INF/web.xml like you already do:

<resource-ref>
  <res-ref-name>jdbc/rhwebDB</res-ref-name>
  <res-ref-type>javax.sql.DataSource</res-ref-type>
  <res-auth>Container</res-auth>
</resource-ref>

If this won't work you can check few other approaches discussed in this answer.

Cussedness answered 4/6, 2018 at 15:7 Comment(1)
Thanks a lot!!. Even if this approach works, it wouldn't be desirable for me to use the GlobalNamingResources since this is the first of 25 websites I need to update, and I would have to use 25 different resource names, which means, I would have to compile 25 different DBUtil java classes for each website, and I'd have to do the same every time I add a new website. All websites uses the same web app. In my Windows machine, everything works fine, so I just have to edit the context.xml file for each website. I'd like to make it work like that.Drifter
D
4

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)

Drifter answered 7/6, 2018 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.