Glassfish jdbc/database lookup failed - java

I hope I am not asking a duplicate question just because I was unable to find an answer.
I am getting this error:
javax.naming.NamingException: Lookup failed for 'jdbc/osclassDB' in SerialContext
This is what I did: I set up a JDBC Connection Pool and a JDBC Resource pointing to that pool (both in Glassfish).
Then I told my web.xml that there is a JDBC Resource:
<resource-ref>
<res-ref-name>jdbc/osclassDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
And then I tried using that resource in a Servlet:
Connection connection = null;
try {
InitialContext initialContext = new InitialContext();
//Context dbContext = (Context) initialContext.lookup("java:comp/env");
DataSource dataSource = (DataSource) initialContext.lookup("jdbc/osclassDB");
connection = dataSource.getConnection();
if (connection == null) {
throw new SQLException("Error establishing connection!");
}
// some queries here
}
// catch and finally close connection
But when I call the Servlet it throws me the NamingException and tells me that the Lookup failed for 'jdbc/osclassDB' in SerialContext
What am I doing wrong here? is it the web.xml? did I miss something?
Thank you for your help!

Solved the problem:
1st by adding a sun-web.xml that links the resource reference from the web.xml to an actual jndi-name (the one I setup on Glassfish). Normally, that shouldn't be necessary (says Oracle) but I did it anyways [Edit: as it turns out, it is really not necessary! ]
2nd I left out the "jdbc". In the servlet, the web.xml and the sun-web.xml it is now just called "osclassDB" (my resource name) instead of "jdbc/osclassDB"
now it looks like this:
web.xml
<resource-ref>
<res-ref-name>osclassDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
sun-web.xml
<resource-ref>
<res-ref-name>osclassDB</res-ref-name>
<jndi-name>osclassDB</jndi-name>
</resource-ref>
in the servlet
Context dbContext = (Context) initialContext.lookup("java:comp/env");
DataSource dataSource = (DataSource) dbContext.lookup("osclassDB");
connection = dataSource.getConnection();
[Edit:] the sun-web.xml is really not necessary

Related

simple string value by JNDI in Java

How can i set simple string value in configuration of tomcat and then read in java application?
context.xml
<ResourceLink name="global/test" global="testing" type="java.lang.String" />
server.xml
<Enviroment name="testing" value="myUser" type="java.lang.String"/>
web.xml in application
<resource-env-ref>
<resource-env-ref-name>global/test</resource-env-ref-name>
<resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>
in my java application
public String getValue(){
return new JndiDataSourceLookup().getDataSource("global/test").toString();
}
When i Run tomcat, i see these errors...
org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'global/test'; nested exception is javax.naming.NameNotFoundException: Name [global/test] is not bound in this Context. Unable to find [global].
javax.naming.NameNotFoundException: Name [global/test] is not bound in this Context. Unable to find [global].
In your web.xml use,
<env-entry>
<description>Sample env entry</description>
<env-entry-name>isConnected</env-entry-name>
<env-entry-type>java.lang.Boolean</env-entry-type><!--order matters -->
<env-entry-value>true</env-entry-value>
</env-entry>
In code,
try {
Context initCxt = new InitialContext();
Boolean isConn = (Boolean)initCxt.lookup("java:comp/env/isConnected");
System.out.println(isConn.toString());
// one could use relative names into the sub-context
Context envContext = (Context) initCxt.lookup("java:comp/env");
Boolean isConn2 = (Boolean)envContext.lookup("isConnected");
System.out.println(isConn2.toString());
} catch (NamingException e) {
e.printStackTrace();
}
Have a look here Naming service tutorial to get a good understanding of InitialContext and JNDI.
I don't know what's inside JndiDataSourceLookup().getDataSource("global/test") but by the name of it, it should return a DataSoruce not a string.
If your lookup is local, simply do
Context ctx = new InitialContext();
String s = (String) ctx.lookup("global/test");
or if you are in a javaee container,
#Resource(name="global/test")
String testString;
and finally in your ejb-jar.xml
<env-entry>
<description>The name was explicitly set in the annotation so the classname prefix isn't required</description>
<env-entry-name>global/test</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>StringValue</env-entry-value>
</env-entry>
Refer this link: http://tomee.apache.org/examples-trunk/injection-of-env-entry/README.html
Your configuration of context.xml, server.xml, and web.xml aren't gonna work.

Cannot find dataSource, even though the dataSource is defined in context.xml

I have the following bean declared for one particular dao method to use a different data source than the rest of the project.
#Bean(name="kingsDataSource")
public DataSource kingsDataSource(){
JndiDataSourceLookup jndi = new JndiDataSourceLookup();
jndi.setResourceRef(true);
return jndi.getDataSource("dataSource/kings");
Here's the use of that bean.
#Resource(name="kingsDataSource")
private DataSource ds;
Here's from the context.xml (omitting the user and password, which have been verified to be correct, and would have been throwing a different error if they were wrong anyway.) I have also played with putting this in the context.xml of the server, having it in one place and not the other, and having it in both places.
<Resource
name="dataSource/kings"
auth="Container"
type="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
factory="org.apache.naming.factory.BeanFactory"
URL="jdbc:mysql://kings/db_netlogs" />
The error is a name not found exception -
Caused by: javax.naming.NameNotFoundException: Name [dataSource/kings] is
not bound in this Context. Unable to find [dataSource].
My question, then, is - to what do I bind this and how?
try to add a resource-ref to your web.xml
<resource-ref>
<res-ref-name>dataSource/kings</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

Need to use jndi datasource defined in weblogic from a no context application

I need to get programmatic the weblogic datasource (JNDI) for my application, I have my own Spring placeholder and at this point there is no applicationcontext created I can't get the datasource from context.
How can I get the datasource from weblogic programmatic?
Try this in your Java code,
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,"t3://localhost:7004,localhost:7005"); //cluster URL, if datasource deployed on cluster
try{
envContext = new InitialContext(ht); // InitialContext();
DataSource ds = (DataSource)envContext.lookup("jdbc/MyDataSource"); //if using Weblogic 12c, then remove `jdbc/` and just give the name of DataSource
con = ds.getConnection();
//.. use connection
con.close();
}
catch(SQLException e)
{e.printStackTrace();}
and update your web.xml file with resource-ref
<resource-ref>
<description>DB Connection</description>
<res-ref-name>MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

how to do connection pooling in java?

I am trying to understand connection pooling in java, i am using jsp, servlet and tomcat 6 server in my application. I have written the following code in a java class dbconnection.java:
I am using type 4 jdbc connection with oracle 10g EE in windows Xp OS
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class dbconnection {
public Connection con = null;
public Connection getConnection() throws Exception, SQLException
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:abc","abc", "abc");
}
catch(Exception e)
{
}
return con;
}
public void removeConnection() throws SQLException
{
con.close();
}
}
Then i am retriving connection in servlet as follows:
try{
dbconnection db= new dbconnection();
Connection con=db.getConnection();
}
catch(Exception e){
}
finally{
db.removeConnection();//removes connection
}
Is it connection pooling or some configuration is required in tomcat server or something else?
A connection pool operates by performing the work of creating connections ahead of time.
In the case of a JDBC connection pool, a pool of Connection objects is created at the time the application server starts. The client can access the connection object in connection pool and return the object to pool once the db work is completed.
Context.xml
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" username="root" password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/cdcol"/>
//This should be added in the servers context,xml file. For example if you are using apache server then the context.xml will be found in C:\apache-tomcat-6.0.26\conf\Context.xml
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>
</resource-ref>
//This should be added in the web.xml of the local project. (Not in server's web.xml).
Context ctx=new InitialContext();
Context envContext = (Context)ctx.lookup("java:comp/env");
DataSource ds=(DataSource)envContext.lookup("jdbc/TestDB");//TestDB is the Database Name
con=ds.getConnection();
stmt = con.createStatement();
You can get a third-party library, or you can use the connection pooling your Java EE container (for example, JBoss or WebSphere) provides for you.
To do this, you configure and use a JNDI datasource.
Here are details for Tomcat:
http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html
http://www.tomcatexpert.com/blog/2012/01/24/using-tomcat-7-jdbc-connection-pool-production
Connection pooling is the feature available in all major web and application servers. You can find the simple example on configuring with Tomcat. Tomcat Connection Pooling
But if you would like to write your own connection pooling then there are libraries available to write. Apache DBCP

JNDI path Tomcat vs. Jboss

I have DataSource which is configured on Tomcat 6 in context.xml as MyDataSource.
And I'm fetching it the following way:
DataSource dataSource;
try {
dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource");
} catch (NamingException e) {
throw new DaoConfigurationException(
"DataSource '" + url + "' is missing in JNDI.", e);
}
Everything works fine. Now I'm exporting this code to Jboss AP 6. and I configured my dataSource and its connection pool as local-tx dataSource under the same name.
When I'm executing the code above, I'm getting NamingException exception. after some investigation I've found that correct way to call my DataSource under Jboss is
dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");
Can anybody explain me why should I omit "comp/env" in my JNDI path under Jboss?
The portable approach for defining data sources is to use a resource reference. Resource references enable you to define the JNDI name for your data source, relative to your application naming context (java:comp/env), and then map that logical reference to the physical resource defined in the application server, whose JNDI name is proprietary to the application server vendor. This approach enables your code and assembly to be portable to any compliant application server.
Step 1: Declare and Lookup Resource Reference
Option 1
This can be done by declaring a resource-ref in your web deployment descriptor (WEB-INF/web.xml):
<resource-ref>
<description>My Data Source.</description>
<res-ref-name>jdbc/MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Within your code, you can then lookup this resource using the JNDI name java:comp/env/jdbc/MyDataSource:
dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");
This JNDI name will not change regardless of the server where the application is deployed.
Option 2
Alternatively, starting in Java EE 5 (Servlet 2.5), this can be done even easier within your code using the #Resource annotation. This eliminates the need for configuring the resource-ref in your web deployment descriptor (web.xml) and prevents the need to perform an explicit JNDI lookup:
public class MyServlet extends HttpServlet {
#Resource(name = "jdbc/MyDataSource")
private DataSource dataSource;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// dataSource may be accessed directly here since the container will automatically
// inject an instance of the data source when the servlet is initialized
}
This approach has the same results as the previous option, but cuts down on the boilerplate code and configuration in your assembly.
Step 2: Map Resource Reference to Data Source
Then, you will need to use your application server's proprietary approach for mapping the resource reference to the physical data source that you created on the server, for example, using JBoss's custom deployment descriptors (WEB-INF/jboss-web.xml):
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:/MyDataSource</jndi-name>
</resource-ref>
</jboss-web>
Or, for example, using Tomcat's context.xml:
<Resource name="jdbc/MyDataSource" . . . />
You can add to your data source definition the 'jndi-name' tag:
jndi-name - the JNDI name under which the DataSource should be bound.
You can find data source documentation on JBoss wiki: ConfigDataSources

Categories