New user of Tomcat (8.5.9) on Linux CentOS 7 with Java SE 8. I must be making a simple mistake. This should be a textbook example how to configure a JDBC connection pool for tomcat.
I have this error:
javax.naming.NameNotFoundException: Name [jdbc/pool1] is not bound in this Context. Unable to find [jdbc]
Any idea what I could doing wrong? Tomcat states It is NOT recommended to place <Context> elements directly in the server.xml file. Thus, my setup:
$CATALINA_HOME/webapps/myapp/META-INF/context.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/pool1"
auth="Container"
type="javax.sql.DataSource"
username="xx"
password="xx"
driverClassName="oracle.jdbc.OracleDriver"
url="xx"
maxTotal="256"
maxIdle="8"
initialSize="4"
removeAbandonedTimeout="7200"
removeAbandonedOnBorrow="true"/>
<Resource name="jdbc/pool2"
auth="Container"
type="javax.sql.DataSource"
username="xx"
password="xx"
driverClassName="oracle.jdbc.OracleDriver"
url="xx"
maxTotal="256"
maxIdle="8"
initialSize="4"
removeAbandonedTimeout="7200"
removeAbandonedOnBorrow="true"/>
<ResourceLink name="jdbc/pool1"
global="jdbc/pool1"
type="javax.sql.DataSource"/>
<ResourceLink name="jdbc/pool2"
global="jdbc/pool2"
type="javax.sql.DataSource"/>
</Context>
$CATALINA_HOME/webapps/myapp/WEB-INF/web.xml is as follows:
...
<resource-ref>
<description>xxx</description>
<res-ref-name>jdbc/pool1</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<description>xxx</description>
<res-ref-name>jdbc/pool1</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
...
The code causing the exception:
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/pool1");
conn = ds.getConnection();
I have not modified $CATALINA_HOME/conf/server.xml at all. Did I configure something incorrectly, or am I missing setting another file up somewhere?
UPDATE 1
I tried adding the above ResourceLinks to the GlobalNamingResources tag in the $CATALINA_HOME/conf/server.xml file, then stopping/starting Tomcat, but I got the same error.
UPDATE 2
I then added the Resource tags from context.xml above also to the server.xml file (GlobalNamingResources tag), stopping/starting tomcat, and got same error.
UPDATE 3
I got everything working with Andreas' expert help (thanks!) by changing the way java calls the pool:
Context initCtx = new InitialContext();
Context context = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) context.lookup("jdbc/pool1");
conn = ds.getConnection();
Also, the ResourceLinks should not be in server.xml (they simply generate a warning in tomcat log).
Your $CATALINA_BASE/conf/server.xml file should contain the full <Resource> element. Remember to also add the JDBC driver jar file to Tomcat's $CATALINA_BASE/lib folder, since it is Tomcat, not your webapp, that needs it when the <Resource> is defined in server.xml.
Next, the META-INF/context.xml is a template that is used the first time your webapp is deployed. It gets copied to $CATALINA_BASE/conf/Catalina/localhost/myapp.xml, and is likely not updated/refreshed if you change META-INF/context.xml.
The .../Catalina/localhost/myapp.xml file should contain the <ResourceLink> element, mapping the name used by the webapp to the name used in server.xml. Keeping those two names the same is easiest, but not required.
Tomcat works fine without the <resource-ref> elements in WEB-INF/web.xml, but it's better if they are there, for compatibility with other Servlet containers.
Note: $CATALINA_BASE is usually the same as $CATALINA_HOME, i.e. the folder where Tomcat is installed, unless you explicitly configure it otherwise.
So, $CATALINA_BASE/conf/server.xml:
<?xml version='1.0' encoding='utf-8'?>
<Server ...>
...
<GlobalNamingResources>
...
<Resource name="jdbc/pool1" auth="Container" type="javax.sql.DataSource" ... />
<Resource name="jdbc/pool2" auth="Container" type="javax.sql.DataSource" ... />
...
</GlobalNamingResources>
...
</Server>
and $CATALINA_BASE/conf/Catalina/localhost/myapp.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<ResourceLink name="jdbc/pool1" global="jdbc/pool1" type="javax.sql.DataSource"/>
<ResourceLink name="jdbc/pool2" global="jdbc/pool2" type="javax.sql.DataSource"/>
</Context>
and place ojdbcXXX.jar in $CATALINA_BASE/lib.
Related
I did everything in this :
how to connect tomcat 7 and mysql
But it still isn't working..... why? What have I missed?
Enviroment
OS : Win7
Eclipse : J2EE Mars
Tomcat : tomcat 8.0
java : 1.8.0_73
db name : test
username: root
password: 123
controller:
writeDB testDB = new writeDB(tablename);
writeDB.java
....
Class.forName("com.mysql.jdbc.Driver");
try{
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
//-------error-------
dataSource = (DataSource) envContext.lookup("jdbc/test");
//-------error-------
}catch(NamingException ex)
{
throw new RuntimeException(ex);
}
web.xml (in my project)
<!-- MySQL JNDI -->
<resource-ref>
<description>MySQL DB</description>
<res-ref-name>jdbc/test</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
context.xml
(in TOMCAT_HOME/conf)
(Also in workspace\Servers\Tomcat v8.0 Server at localhost-config)
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/eatST">
<Resource
name="jdbc/test"
auth="Container"
type="javax.sql.DataSource"
maxActice="100"
maxIdle="30"
maxWait="10000"
username="root"
password="123"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test?
useUnicode=true&characterEncoding=UTF8"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
/>
</Context>
Logs
Servlet.service() for servlet [commentCtr] in context
with path [/eatST] threw exception
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
cannot be cast to javax.activation.DataSource
at com.joe.db.writeDB.<init>(writeDB.java:58)
at com.joe.servlet.CommentCtr.doPost(CommentCtr.java:38)
at ............
You've imported (and presumable programmed to) an incorrect DataSource. Your exception (java.lang.ClassCastException ... cannot be cast to javax.activation.DataSource) is telling you that you have usedjavax.activation.DataSource, but you wanted javax.sql.DataSource. Modify com.joe.db.writeDB and change
import javax.activation.DataSource;
to
import javax.sql.DataSource;
Also, you don't need Class.forName("com.mysql.jdbc.Driver"); (it doesn't hurt anything, but JDBC drivers register themselves now).
How do i connect to derby database (that comes with the netbeans) ? I am using Tomcat as the server. Earlier i used the following statements to connect to the derby database,but then i used glassfish as the server.
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/PollDatasource");
Connection connection = ds.getConnection();
But now using Tomcat as the server i am unaware how to do this.
Note : Tomcat and Derby are pre installed with netbeans IDE that i am using currently
In Tomcat find conf/context.xml, then edit and write something like this:
<Resource name="jdbc/PollDatasource" auth="Container" type="javax.sql.DataSource"
driverClassName="com.YourDriver"
url="jdbc:derby://localhost:1527/nameOfTheDatabase;create=true"
username="username" password="password" maxActive="20"
maxIdle="10" maxWait="-1" />
Note 1: With the above URL the driver will be org.apache.derby.jdbc.ClientDriver
Note 2 : You can also add the above information in META-INF/context.xml of your project. This becomes application specific.If you add the information in tomcat's context.xml that becomes global.
Note 3: Download the jar from this website.Download db-derby-10.9.1.0-bin.zip.It contains many files, including derby.jar and derbyclient.jar (along with much documentation).derbyclient.jar contains our friend org.apache.derby.jdbc.ClientDriver.class. derby.jar contains org.apache.derby.jdbc.EmbeddedDriver. Keep the downloaded jar in lib folder of Tomcat.
and in your application web.xml "resource-ref":
<resource-ref>
<description>my connection</description>
<res-ref-name>jdbc/PollDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
You may want to look at these questions :
Isn't it necessary to mention the name of archive in the Resource tag?
When is the tag I added in context.xml gets read?
What are steps followed in the look-up? what is looked first web.xml or context.xml?
You need to:
1) Copy your derbyclient-*.jar to ${TOMCAT_HOME}/lib.
2) Edit your server.xml and add the following lines to the section GlobalNamingResources:
<Resource auth="Container"
driverClassName="org.apache.derby.jdbc.EmbeddedDriver"
maxActive="8" maxIdle="4"
name="jdbc/my-ds" type="javax.sql.DataSource"
url="jdbc:derby:mydb;create=true"
username="myuser" password="mypassword" />
3) In your context definition, add:
<Context docBase="myapp"
path="/myapp"
reloadable="true"
...>
<ResourceLink name="jdbc/my-ds"
global="jdbc/my-ds"
type="javax.sql.DataSource" />
</Context>
4) Restart Tomcat.
The example you have requires JNDI. See the relevant tomcat versions docs on setting that up.
Or use a connection string, here's a page from derby docs http://db.apache.org/derby/integrate/plugin_help/derby_app.html
I have some Java-console-apps. which are using Hibernate to take care some database stuff (I use MySQL). Now, I want Hibernate to use datasource from Tomcat Context. Could anyone tell me how?
Tomcat wiki contains the needed configuration.
in context.xml:
<?xml version="1.0" encoding="UTF-8"?> <Context antiJARLocking="true" path="/DVDStore">
<Resource auth="Container"
driverClassName="com.mysql.jdbc.Driver" maxActive="30" maxIdle="10" maxWait="10000" name="jdbc/sakila" password="*****"
type="javax.sql.DataSource" url="jdbc:mysql://localhost/sakila" username="*****"/>
</Context>
In WEB-INF/web.xml .
<resource-ref>
<description>This is a MySQL database connection</description>
<res-ref-name>jdbc/sakila</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
In hibernate.cfg.xml:
<!-- using container-managed JNDI -->
<propertyname="hibernate.connection.datasource">
java:comp/env/jdbc/sakila
</property>
You can find more in The TomcatHibernate Wiki
Edit:
In case you want to access the context directly, this is the way to do it problematically
ServletContext sc = getServletContext();
String parameterValue = sc.getInitParameter("parameterName");
I have apache tomcat 5.5.28 on my windows box and I am trying to deploy a web application (WAR) which works fine on other servers.
However I am having trouble creating a datasource. I am not sure of the format. The db is oracle.
Here is what I have in server.xml.
<GlobalNamingResources>
<Environment
name="simpleValue"
type="java.lang.Integer"
value="30"/>
<Resource
name="tomdb11"
type="oracle.jdbc.pool.OracleDataSource"
maxActive="4"
maxIdle="2"
username="tomdb11"
maxWait="5000"
driverClassName="oracle.jdbc.driver.OracleDriver"
validationQuery="select * from dual"
password="remotedb11"
url="jdbc:oracle:thin:#dbserver:1521:orcl"/>
<Resource
auth="Container"
description="User database that can be updated and saved"
name="UserDatabase"
type="org.apache.catalina.UserDatabase"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>
How do I access this in the web.xml where usually what I have which works in other servers is
<context-param>
<param-name>databaseUser</param-name>
<param-value>tomdb11</param-value>
</context-param>
<context-param>
<param-name>databasePassword</param-name>
<param-value>tomdb11</param-value>
</context-param>
<context-param>
<param-name>databaseSchema</param-name>
<param-value>TOMDBADMINN11</param-value>
</context-param>
Also am I missing something?
Edit: I get the following exception:
javax.naming.NameNotFoundException: Name tomdb11 is not bound in this Context
at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)
at javax.naming.InitialContext.lookup(Unknown Source)
at com.taw.database.DatabaseService.<init>(DatabaseService.java:19)
at com.taw.database.DatabaseServices.init(DatabaseServices.java:40)
If exception tells that it cannot find jdbc in the JNDI context, then it roughly means that you tried to obtain the DataSource as follows
dataSource = new InitialContext().lookup("jdbc/tomdb11");
while your server.xml file tells the following:
<Resource
name="tomdb11"
>
Those names are not the same. In fact, you should have been used:
dataSource = new InitialContext().lookup("tomdb11");
In Tomcat, however, the InitialContext doesn't directly point to java:comp/env/, so you'll need to replace it by:
dataSource = new InitialContext().lookup("java:comp/env/tomdb11");
The normal practice, however, is that you specify JDBC datasources with the jdbc prefix. So I would rename the resource as
<Resource
name="jdbc/tomdb11"
>
and access it by
dataSource = new InitialContext().lookup("java:comp/env/jdbc/tomdb11");
In the webapp's web.xml you should however also have the following resource declaration:
<resource-env-ref>
<resource-env-ref-name>jdbc/tomdb11</resource-env-ref-name>
<resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>
For more details about Tomcat JNDI check this HOWTO: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html. Hope this helps.
First... Make sure you have an Oracle JDBC Jar in your $TOMCAT_HOME/common/lib.
Second... Make sure your web.xml also contains a block like this...
<resource-ref>
<description>Oracle Datasource</description>
<res-ref-name>tomdb11</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
As for your <context-param>, I'm not sure that is doing anything as you already have those things defined in your <Resource>.
I'm deploying an old app on a new box. When hitting the database for the first time I get
File input error: Cannot create PoolableConnectionFactory (Invalid handle)
I've set up my resource in context.xml, my dsn with unixODBC, and my resource-ref in web.xml. What else am I missing?
from content.xml -->
<Resource name="jdbc/MoleComp" auth="Container"
type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="-1"
removeAbandoned="false" removeAbandonedTimeout="60"
username="userName" password="passWord"
driverClassName="sun.jdbc.odbc.JdbcOdbcDriver"
url="jdbc:odbc:DSNName"/>
from app/WEB-INF/web.xml -->
<resource-ref>
<description>DB connection</description>
<res-ref-name>jdbc/MoleComp</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Thanks.
First, you should remove the <resource-def> from web.xml. This is just another way to define data source, which you've already done in context.xml.
That error is from ODBC-JDBC bridge driver. So either ODBC is not running or the url="jdbc:odbc:DSNName" is invalid.
After getting this problem on yet another server, I switched the application from using unixODBC and odbc.jdbc to java type 4 driver jTDS jtds.jdbc. Performance is a bit better too!