So I recently have started working in a new proyect. These guys have the Datasource connection declared this way:
Context init = new InitialContext();
Context context = (Context) init.lookup("java:comp/env");
ds = (DataSource)context.lookup("jdbc/WhateverDS");
I don't know why have they declared it this way. I've had always seen it like this:
DataSource ds = new InitialContext().lookup("java:comp/env/jdbc/WhateverDS");
First of all do you guys know why would they do it in two steps?
My second question is that sometimes we get the following error, and if it may have something to do with the code above:
Caused by: javax.naming.NameNotFoundException: The name comp/env is not bound in this context
at org.apache.naming.NamingContext.lookup(NamingContext.java:818)
at org.apache.naming.NamingContext.lookup(NamingContext.java:166)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:157)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
... 19 more
We are using MySQL over Tomcat using jdbc.
Edit:
They have nothing about the DB declared in web.xml.
The context.xml (among other parameters) looks like this:
Resource driverClassName="com.mysql.jdbc.Driver"
name="jdbc/WhateverDS"
type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/someDB"
To answer your first question: there is no effective difference between the two-step and the one-step lookup for the DataSource.
Your second question appears to be a duplicate of javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context
Related
I've got a WebApp with Tomcat 10, Java11 using Jersey3.
I defined a ConnectionPool in my context.xml for handling the connection to my OracleDB and now I'm trying to access the DataSource within my controller through a #Resource annotation. This should invoke a JNDI-lookup. Unfortunately, I always get a NPE as it seems not to find the resource while running... What am I doing wrong? Or what would the correct mappedName / lookup be?
#Path("/data")
public class DataController {
#Context
ServletContext context;
#Resource(lookup = "java:/jdbc/myDB") //also tried java:/comp/env/jdbc/myDB and mappedName="jdbc/myDB"
protected DataSource ds; //always null
<Context name="myapp">
<Resource type="javax.sql.DataSource"
name="jdbc/myDB"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#//localhost:1521/orcl"
username="xy"
password="xy"/>
According to the tutorials, a ref-link is optional when I define the resource directly in the context.xml.
Thanks for any input!
This link is about jboss, but would seem relevant to you too. It says that according to the specification, Resource annotation to do JNDI lookups would only work with EJBs, so it wouldn't work for your case.
A workaround is to do the programmatic way to see if your datasource is working:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource bean = (DataSource ) envCtx.lookup("jdbc/myDB");
If you can find your datasource you can then try to optimize to avoid "manual" lookup above.
According to this documentation:
https://www.playframework.com/documentation/2.5.x/JavaDatabase#exposing-the-datasource-through-jndi
I simply need another entry in my application.conf to expose a DataSource in JNDI:
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.jndiName=DefaultDS
I've added "tyrex" % "tyrex" % "1.0.1" to my libraryDepenencies in build.sbt.
From reading several other posts on this, it sound like I should be able to simply use
DataSource ds = (DataSource) play.api.libs.JNDI.initialContext().lookup("DefaultDS");
To fetch the DataSource from JNDI. However, when I try this it throws the following Exception:
javax.naming.NameNotFoundException: DefaultDS not found
at tyrex.naming.MemoryContext.internalLookup(Unknown Source)
at tyrex.naming.MemoryContext.lookup(Unknown Source)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
The main reason I'm trying to do this is so that Quartz can re-use the DataSource/ConnectionPool created by Play instead of defining another in quartz.properties. According to the docs:
http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigDataSources.html
I should need the following two lines in quartz.properties:
org.quartz.jobStore.dataSource = h2
org.quartz.dataSource.h2.jndiURL = DefaultDS
However, Quartz throws a bunch of exceptions:
java.sql.SQLException: Could not retrieve datasource via JNDI url 'DefaultDS' javax.naming.NameNotFoundException: DefaultDS not found [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'DefaultDS' javax.naming.NameNotFoundException: DefaultDS not found]
I'm not sure where to go next. Any help would be appreciated.
Thanks.
Found it.
I simply needed to add jdbc to my libraryDependencies in build.sbt. This created and exposed the DataSource in JNDI.
I am having a slight problem with using JDBC tomcat pool. I have properly defined the resource in context.xml, as well as referring to it in web.xml. Now in my Database access method, I would like to somehow get a data source for when a user get something from the database. However, when I type this in:
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/testDB");
I get the error message "InitialContext cannot be resolved to a type". What is the problem here?
Be sure to import InitialContext, it sounds like it is missing to the compiler.
I have a web application trying to access a JNDI declared in WebSphere Application Server.
The JNDI is declared under Object pool managers. However, I'm receiving an error when I access the pool. The error says that comp/env/pool is not found in context "java:".
My code is written as follows:
InitialContext initialContext = new InitialContext();
ObjectPoolManager opm = (ObjectPoolManager)initialContext.lookup("java:comp/env/pool");
Accessing the pool via the code below works:
ObjectPoolManager opm = (ObjectPoolManager)initialContext.lookup("pool");
I'm confused because according to what I've found on the internet, java:comp/env/ is a default prefix for JNDI. So why does it cause an error in my case?
Thank you!
you can only use java:comp/env if you have declared a reference to the Object Pool in your web.xml under the resource-ref section.
See What is resource-ref in web.xml used for? for further explanation.
This question already has answers here:
What does java:comp/env/ do?
(3 answers)
Closed 2 years ago.
what is meant by java:comp/env ?
What does the look up like :
Context envContext = (Context)initContext.lookup("java:comp/env");
do ?
I understand that a look-up like :
(DataSource)envContext.lookup("jdbc/MyDatasource")
looks up for the name MyDatasource in the context.xml or web.xml to get the URL of the database. Is it so ? !! But what does the former look up do ?
java:comp/env is the node in the JNDI tree where you can find properties for the current Java EE component (a webapp, or an EJB).
Context envContext = (Context)initContext.lookup("java:comp/env");
allows defining a variable pointing directly to this node. It allows doing
SomeBean s = (SomeBean) envContext.lookup("ejb/someBean");
DataSource ds = (DataSource) envContext.lookup("jdbc/dataSource");
rather than
SomeBean s = (SomeBean) initContext.lookup("java:comp/env/ejb/someBean");
DataSource ds = (DataSource) initContext.lookup("java:comp/env/jdbc/dataSource");
Relative paths instead of absolute paths. That's what it's used for.
It's an in-memory global hashtable where you can store global variables by name.
The "java:" url scheme causes JNDI to look for a javaURLContextFactory class, which is usually provided by your app container, e.g. here is Tomcat's implementation javadoc
See also NamingManager.getURLContext
I know I'm far late, but I was asking the same question, and I think I came some answer. So, if I may put my two cents.
java:comp/env/jdbc/myDataSource
java: is just like jdbc: from connection string. Acts as a protocol.
comp is the root for all JNDI contexts.
env is the subcontext for all resource related. There is another for user. Check this out.
jdbc is the subcontext for jdbc resources. There are types. Check the link from the previous bullet.
myDataSource is the name of your jdbc resource.