javax.naming.NameNotFoundException: getting JNDI to work

J

jonck

Hi all,
I would like to set up a DBCP connection pool for my stand-alone
application (so not in Tomcat, for which documentation is abundant).
However, I keep getting an "javax.naming.NameNotFoundException: Name
jdbc is not bound in this Context" exception. I have tried everything I
could think of and I'm stumped.
First of all, I tried following the tutorial at
http://jakarta.apache.org/commons/dbcp/guide/jndi-howto.html

After replacing the driverClassName, url, username and password with
real values, this code gives me the NameNotFoundException when I try to
rebind however. So I tried adding the line

ref.add(new StringRefAddr("dataSourceName", "jdbc/sender")); (before
rebinding)

but this improved nothing. So I then tried creating a BasicDataSource
by hand as follows:

BasicDataSource ds = new BasicDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/mydb?autoReconnect=true&useUnicode=true");
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("xxxxxxxxxx");
ds.setPassword("xxxxxxxxxx");
Context ctx = new InitialContext();
ctx.bind("jdbc/test", ds);

It gives exactly the same error. Obviously I'm missing something
crucial here, but many hours of Googling have not turned up an answer
for me.

Could someone please point me in the right direction?
Thanks very much, Jonck
 
G

gimme_this_gimme_that

I use tyrex-1.0.1 from sourceforge.net to create a JNDI Context for my
database connections.

With tyrex you can create JNDIContexts for about anything - it doesn't
have to be a database.

I find it handy when executing junit tests which do database queries.
(For example, it works great with Hibernate if you are using a custom
connection
provider class.)

That is, with tyrex you can use the same connection classes in your web
applications as you do in junit or standalone applications.

To give you an idea ....

For tyrex, I'm using Oracle, so my (tyrex) domain.xml file looks like :
You use domain.xml file sort of like a tomcat/configure/server.xml
file.

<domain>
<name>BlahBlahDataSources</name>
<resources>
<dataSource>
<jar>C:\oracle\ora92\jdbc\lib\classes12.zip</jar>
<name>BlahBlahDataSource</name>
<class>oracle.jdbc.xa.client.OracleXADataSource</class>
<config>
<serverName>blah.blah.myoracle.db.server.com</serverName>
<portNumber>1521</portNumber>
<databaseName>blahblah</databaseName>
<user>blahblah</user>
<password>blahblah</password>
<driverType>thin</driverType>
</config>
<limits>
<maximum>50</maximum>
<minimum>5</minimum>
<initial>5</initial>
<maxRetain>300</maxRetain>
<timeout>10</timeout>
</limits>
</dataSource>
</resources>
</domain>

If you search around you can find a domain.xml compatible with MySQL.
A MySQL demo might even come with tyrex.


Then I have the following class which builds the JNDIContext for the
standalone (junit). It's abstract so I can connect to multiple
databases
in the same application.


package com.blah.blah.util.jndi;

import tyrex.resource.Resources;
import tyrex.resource.ResourceException;
import tyrex.tm.TransactionDomain;
import tyrex.tm.RuntimeContext;
import tyrex.tm.DomainConfigurationException;
import tyrex.tm.RecoveryException;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLExclseption;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


// This class is used to create a JNDI context for junit testing.

public abstract class JNDIContext {

public JNDIContext(){};

protected String DATASOURCE = null; // Assigned in subclass

protected RuntimeContext runCtx = null;

public void startUp(String DATASOURCE) {
try {
this.DATASOURCE=DATASOURCE;
TransactionDomain domain = TransactionDomain.createDomain(
"domain.xml" );
domain.recover();
DataSource dataSource = (DataSource) domain.getResources().
getResource(DATASOURCE);

runCtx = RuntimeContext.newRuntimeContext();
Context jndiCtx = runCtx.getEnvContext();

jndiCtx = jndiCtx.createSubcontext( "comp" );
jndiCtx = jndiCtx.createSubcontext( "env" );
jndiCtx = jndiCtx.createSubcontext( "jdbc" );
jndiCtx.bind( DATASOURCE , dataSource );

RuntimeContext.setRuntimeContext( runCtx );

} catch ( Exception ex) {
// DomainConfigurationException, RecoveryException, NamingException ,
ResourceException
throw new java.lang.RuntimeException(
"JNDI Context failed to initialize. : " + ex.getMessage() );
}
}

// ignore
public void cleanup() {
RuntimeContext.unsetRuntimeContext();
runCtx.cleanup();
}

//// getConnection() used for testing
public void getConnection() throws NamingException,SQLException {
InitialContext initCtx = new InitialContext();
String jndiName = "java:comp/env/jdbc/" + DATASOURCE ;
DataSource dataSource = (DataSource) initCtx.lookup( jndiName );
Connection con = dataSource.getConnection();
if ( null != con ) {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT SYSDATE FROM DUAL");
while(rs.next()) {
String c = rs.getString(1);
System.out.println("C : " + c);
}
rs.close();
stmt.close();
con.close();
}
}

//ignore
public void finalize() throws Throwable {
cleanup();
}

}


package com.blah.blah.util.jndi;

// This is the concrete class used to create a specific JNDI context .

public class BlahBlahContext extends JNDIContext {
public BlahBlahContext() {
super();
startUp("BlahBlahDataSource");
}
}

My Junit Test class has the following static block:

static {
try {
new BlahBlahContext();
} catch ( Exception ex ) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}

Then I connect to the database in the normal way in my code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top