I have a web java project that when running some pages give me the following error:
Caused by: org.apache.ibatis.exceptions.PersistenceException:
Error building SqlSession.
The error may exist in SQL Mapper Configuration
Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.datasource.DataSourceException: There was an error configuring JndiDataSourceTransactionPool. Cause: javax.naming.NameNotFoundException: Intermediate context does not exist: jdbc/DashDBtest
I have the credentials of the database, but I do not know how to configure it to work
This error may related to DataSource configuration. if you use Apache Tomcat AS, it provide three ways to configure DataSource in JNDI.
1- in your application: context.xml under META-INF directory.
2- in your server context.xml under Tomcat/conf directory.
3- define it at global level by setting both server.xml and context.xml
I prefer the third way, so for Oracle Database declare the JNDI resource in your in your Tomcat/conf/server.xml like:
<GlobalNamingResources>
<Resource name="jdbc/DATABASE_NAME"
auth=Container
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
username="db_username"
password="db_password"
url="jdbc:oracle:thin:#//localhost:1521:XE"
/>
....
and for MySQL Database do:
<GlobalNamingResources>
<Resource name="jdbc/DATABASE_NAME"
auth=Container
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
username="db_username"
password="db_password"
url="jdbc:mysql://localhost:3306/DATABASE_NAME"
/>
....
And reference the JNDI resource link in your Tomcat/conf/context.xml :
<Context>
<ResourceLink name="jdbc/MY_DATABASE_NAME" global="jdbc/DATABASE_NAME" type="javax.sql.DataSource"/>
</Context>
and finally use the ResourceLink's name in your project to get the DataSource.
hope it help.
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).
I am trying to connect a Spring MVC 4 application to MY Sql local BBDD.
This is the files:
Spring MVCConfiguration File:
#Bean
public DataSource dataSource() throws Exception {
Context cts = new InitialContext();
DataSource dts = (DataSource) cts.lookup("java:/comp/env/jdbc/etielaBBDD");
return dts;
}
Tomcat Context.xml:
<ResourceLink name="jdbc/etielaBBDD"
global="jdbc/BBDD"
auth="Container"
type="javax.sql.DataSource" />
Tomcat Server XML:
<Resource name="jdbc/BBDD" global="jdbc/BBDD" auth="Container" type="javax.sql.DataSource"
username="XXXXXX"
password="XXXXXX"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/confluenceuseUnicode=true&characterEncoding=utf8"
maxActive="15"
maxIdle="7"
defaultTransactionIsolation="READ_COMMITTED"
validationQuery="Select 1" />
And, when I Start Tomcat, this error appears:
javax.naming.NameNotFoundException: Name jdbc/BBDD is not bound in this context
I am two days trying to solve this error with no solution. Any idea? Thanks.
I've setup a mail Resource definition in my context.xml
<Resource
name="MyMailSession"
auth="Container"
type="javax.mail.Session"
mail.smtp.sendpartial="true"
mail.debug="true"
mail.smtp.host="myhost.hosting.com"
/>
And a mail utility which looks up the mail session's JNDI:
public int send() throws Exception {
int msgCount = 0; //number of recipients
Context ctx = new InitialContext();
Session session = (Session) ctx.lookup("java:comp/env/mail/MyMailSession");
MimeMessage message = new MimeMessage(session);
But am getting the following exception:
javax.naming.NameNotFoundException: Name [mail/MyMailSession] is not bound in this Context. Unable to find [mail].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
...
Is the mail tag necessary as a prefix to the Resource name when it comes to mail or is it more of a convention? (i.e., looking up a User Transaction would be set as java:comp/UserTransaction)
Try with
<Resource
name="mail/MyMailSession"
auth="Container"
type="javax.mail.Session"
mail.smtp.sendpartial="true"
mail.debug="true"
mail.smtp.host="myhost.hosting.com"
/>
instead of
<Resource
name="MyMailSession"
auth="Container"
type="javax.mail.Session"
mail.smtp.sendpartial="true"
mail.debug="true"
mail.smtp.host="myhost.hosting.com"
/>
Edit : In that case it is necessary because your refer to the context as mail/MyMailSession in this line :
Session session = (Session) ctx.lookup("java:comp/env/mail/MyMailSession");
What follow java:comp/env/ must be your Resource name.
It is said that in the Spring javadoc article about DriverManagerDataSource class, that this class is very simple and that it is recommended
to use a JNDI DataSource provided by the container. Such a DataSource can be exposed as a DataSource bean in a Spring ApplicationContext via JndiObjectFactoryBean
The question is: how do I accomplish this?
For example, if I wish to have DataSource bean to access my custom MySQL database, what would I require then? What should I write in the context configuration, etc?
If using Spring's XML schema based configuration, setup in the Spring context like this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
...
<jee:jndi-lookup id="dbDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
Alternatively, setup using simple bean configuration like this:
<bean id="DatabaseName" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
</bean>
You can declare the JNDI resource in tomcat's server.xml using something like this:
<GlobalNamingResources>
<Resource name="jdbc/DatabaseName"
auth="Container"
type="javax.sql.DataSource"
username="dbUser"
password="dbPassword"
url="jdbc:postgresql://localhost/dbname"
driverClassName="org.postgresql.Driver"
initialSize="20"
maxWaitMillis="15000"
maxTotal="75"
maxIdle="20"
maxAge="7200000"
testOnBorrow="true"
validationQuery="select 1"
/>
</GlobalNamingResources>
And reference the JNDI resource from Tomcat's web context.xml like this:
<ResourceLink name="jdbc/DatabaseName"
global="jdbc/DatabaseName"
type="javax.sql.DataSource"/>
Reference documentation:
Tomcat 8 JNDI Datasource HOW-TO
Tomcat 8 Context Resource Links Reference
Spring 4 JEE JNDI Lookup XML Schema Reference
Spring 4 JndiObjectFactoryBean Javadoc
Edit: This answer has been updated for Tomcat 8 and Spring 4. There have been a few property name changes for Tomcat's default datasource resource pool setup.
With Spring's JavaConfig mechanism, you can do it like so:
#Configuration
public class MainConfig {
...
#Bean
DataSource dataSource() {
DataSource dataSource = null;
JndiTemplate jndi = new JndiTemplate();
try {
dataSource = jndi.lookup("java:comp/env/jdbc/yourname", DataSource.class);
} catch (NamingException e) {
logger.error("NamingException for java:comp/env/jdbc/yourname", e);
}
return dataSource;
}
}
Assuming you have a "sampleDS" datasource definition inside your tomcat configuration, you can add following lines to your applicationContext.xml to access the datasource using JNDI.
<jee:jndi-lookup expected-type="javax.sql.DataSource" id="springBeanIdForSampleDS" jndi-name="sampleDS"/>
You have to define the namespace and schema location for jee prefix using:
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"
Documentation: C.2.3.1 <jee:jndi-lookup/> (simple)
Example:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>
You just need to find out what JNDI name your appserver has bound the datasource to. This is entirely server-specific, consult the docs on your server to find out how.
Remember to declare the jee namespace at the top of your beans file, as described in C.2.3 The jee schema.
Another feature:
instead of of server.xml, you can add "Resource" tag in
your_application/META-INF/Context.xml
(according to tomcat docs)
like this:
<Context>
<Resource name="jdbc/DatabaseName" auth="Container" type="javax.sql.DataSource"
username="dbUsername" password="dbPasswd"
url="jdbc:postgresql://localhost/dbname"
driverClassName="org.postgresql.Driver"
initialSize="5" maxWait="5000"
maxActive="120" maxIdle="5"
validationQuery="select 1"
poolPreparedStatements="true"/>
</Context>
According to Apache Tomcat 7 JNDI Datasource HOW-TO page there must be a resource configuration in web.xml:
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
That works for me
In your spring class, You can inject a bean annotated like as
#Autowired
#Qualifier("dbDataSource")
private DataSource dataSource;
and You add this in your context.xml
<beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/>
</beans:bean>
You can declare the JNDI resource in tomcat's server.xml using
<Resource name="jdbc/TestDB"
global="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/TestDB"
username="pankaj"
password="pankaj123"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
back to context.xml de spring add this
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource" />
if, like this exmple you are injecting connection to database, make sure that MySQL jar is present in the tomcat lib directory, otherwise tomcat will not be able to create the MySQL database connection pool.
I found this solution very helpful in a clean way to remove xml configuration entirely.
Please check this db configuration using JNDI and spring framework.
http://www.unotions.com/design/how-to-create-oracleothersql-db-configuration-using-spring-and-maven/
By this article, it explain how easy to create a db confguration based on database jndi(db/test) configuration. once you are done with configuration then all the db repositories are loaded using this jndi. I did find useful. If #Pierre has issue with this then let me know. It's complete solution to write db configuration.