Getting DataSource resource in a Java web app - java

I have the following resource tag in my context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/myApp">
<Resource name="jdbc/myDS" auth="Container"
type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="1000"
username="user" password="passwd"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myDB" />
</Context>
I am developing a Java web app using the Stripes framework in NetBeans.
How can I get this resource from within a Java class?

You need your bean to be instantiated by something (a dependecy injection framework) which knows how to handle the #Resrouce annotation. JSP itself doesn't know how.
In this case it would be simpler to locate the DataSource in the JNDI context:
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/myDS");

Thank you Bozho for the answer. I only had to change the lookup string to get it to work:
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/myDS");
Connection conn = ds.getConnection();

Related

Setting up JNDI with a Tomcat 7 environment using Liferay 6.1

I'm very confused why this isn't working. The environment is a Liferay 6.1 instance with Tomcat 7 and the database is NOT the default database from Liferay. It's a secondary server that is used for data. So I'm not sure if that matters with Liferay or not.
web.xml (located in webapps/conf in Tomcat)
<web-app>...
<resource-ref>
<description>My database</description>
<res-ref-name>jdbc/xxx</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
server.xml (located in webapps/conf in Tomcat)
<GlobalNamingResources>
<Resource name="jdbc/xxx" auth="Container" type="javax.sql.DataSource" username="a" password="y" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/xxx"
maxActive="200" maxIdle="25" />
</GlobalNamingResources>
context.xml (located in webapps/conf in Tomcat)
<context>
<ResourceLink global="jdbc/xxx" name="jdbc/xxx" type="javax.sql.DataSource" />
</context>
Code:
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/xxx");
Connection conn = ds.getConnection();
Error:
2016-12-21 19:13:04 FATAL asdasdsd:128 - Exception thrown in (removed):
javax.naming.NameNotFoundException: Name [java:comp/env/jdbc/xxx] is not bound in this Context. Unable to find [java:comp].
at org.apache.naming.NamingContext.lookup(NamingContext.java:820)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
What am I missing?
Edit:
Also confirmed the following:
mysql connector is in the path
same jar is in the classpath of the portlet
Second Edit:
I created a brand new, fresh dynamic web application project with the same configuration and DAO layer and it worked 100%. I have a feeling it's related to Liferay now. Unfortunately..
Third Edit:
Tried everything, including this article: http://www.journaldev.com/2513/tomcat-datasource-jndi-example-java
This didn't work either. Same exception. The lack of information about this issue on the Liferay website is amazing to me. Documentation appears to be very much lacking.
For anyone that this helps in the future, because boy was this a pain and not well documented.
I had to add this to the portlet-ext.properties of the Liferay application:
portal.security.manager.strategy=none
Once I found this link: Liferay/Tomcat "hot-deploy" closes JNDI connection, how can I keep it open?
It ended up solving my problem.
The other solution would be (It works for me), Remove the resource-ref from web.xml, remove the Resource from server. xml and remove ResourceLink from context.xml.
Add the resource alone to context.xml,
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="20" maxIdle="10" maxWait="-1" name="jdbc/xxx" password="" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/xxx" username=""/>
Code (java:comp/env/ is required in this case):
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/xxx");
Connection conn = ds.getConnection();

Tomcat 8.5.4 javax.naming.NameNotFoundException

I am developing a web application with Tomcat 8.5.4. I'm using a properties configured as Resource. So, my $TOMCAT_HOME/conf/server.xml contains
<GlobalNamingResources>
<Resource name="properties/global" auth="Container" type="java.util.Properties" />
</GlobalNamingResources>
The META-INF/context.xml of my webapp has
<Context antiResourceLocking="true" path="/mywebapp">
<ResourceLink global="properties/global" name="properties/global" type="java.util.Properties"/>
</Context>
I'm looking up the resource as follow
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
(Properties) envContext.lookup("properties/global");
However, I'm getting the exception
javax.naming.NameNotFoundException: Name [properties/global] is not bound in this Context. Unable to find [properties].
What's wrong? Thanks.

JNDI DataSource configuration in Tomcat 7

I am new to JNDI and I am trying to get my db connection working. So far no luck.
I either get a message stating: "Name [java:comp/env] is not bound in this Context. Unable to find [java:comp]"
or I received a time out.
Here's information about my current configuration.
Tomcat: Apache Tomcat/7.0.29
JMV: 1.7.0_06-b24
OS: Win 10 Pro
Tomcat\conf\web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/myDatabaseName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Tomcat\conf\context.xml
<ResourceLink type="javax.sql.DataSource"
name="jdbc/localRemarket"
global="jdbc/remarket"
/>
I also tried to put the resource in context.xml to make sure it's findable:
<Resource
type="javax.sql.DataSource"
name="jdbc/myDatabaseName"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myDatabaseName"
username="myUsername"
password="myPassword"
maxActive="1500"
maxIdle="200"
maxwait="-1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
validationQuery="SELECT 1"
timeBetweenEvictionRunsMillis="2000"
minEvictableIdleTimeMillis="15000"
removeAbandoned="true"
removeAbandonedTimeout="5"
/>
Tomcat\conf\server.xml
<Resource
type="javax.sql.DataSource"
name="jdbc/myDatabaseName"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/myDatabaseName"
username="myUsername"
password="myPassword"
maxActive="1500"
maxIdle="200"
maxwait="-1"
testOnBorrow="true"
testOnReturn="true"
testWhileIdle="true"
validationQuery="SELECT 1"
timeBetweenEvictionRunsMillis="2000"
minEvictableIdleTimeMillis="15000"
removeAbandoned="true"
removeAbandonedTimeout="5"
/>
java code:
Connection conn;
public void openMyConnection() {
try {
Properties props = new Properties();
props.put("java.naming.factory.initial", "org.apache.naming.java.javaURLContextFactory");
InitialContext ctx = new InitialContext(props);
Context envCtx = (Context) ctx.lookup("java:comp/env"); // <<<<< PRB HERE
// error message : Name [java:comp/env] is not bound in this Context. Unable to find [java:comp]
org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) envCtx.lookup("jdbc/localDB");
conn = ds.getConnection();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if I change
props.put("java.naming.factory.initial", "org.apache.naming.java.javaURLContextFactory");
for
props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
I get :
Receive timed out
I have reviewed many posts related to JNDI including the following two that were the most helpful:
http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html
and
https://examples.javacodegeeks.com/enterprise-java/tomcat/tomcat-datasource-jndi-example/
Please note that I read the How to configure jndi DataSource in Tomcat 7 but it doesn't provide a solution for my problem.
Can anyone please help resolve this issue?
It worked for me, when I configured the datasource directly in the webapp (file META-INF/context.xml):
<Context >
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="scott"
password="tiger"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#127.0.0.1:1521:mysid"
maxActive="8"
maxIdle="4"/>
</Context>

Create JNDI Connection for Ingres Database

I have a Java project and I've been trying to create a JNDI connection for my Ingres database but have been unsuccessful. I'm not sure if there is something specific to ingres that needs to be included but after quite a bit of research I haven't been able to get things to work.
In my project I have my datasource info in the web.xml file and the context.xml
context.xml has the following info
<Context>
<Resource name="jdbc/myDB" auth="Container" type="javax.sql.Datasource"
username="myUser" password="password" driverClassName="com.ingres.jdbc.IngresDriver"
url="databaseURL" maxActive="8" maxIdle="4" maxWait="100" />
</Context>
My web.xml has the following info
<web-app>
<resource-ref>
<description>Project Descrip</description>
<res-ref-name>jdbc/myDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
In my java code I'm trying to get my connection using the following four lines
Context initContext = new InitialContext();
Context envContext = (Context) initContent.lookup("java:comp/env");
Datasource ds = (DataSource) envContext.lookup("jdbc/myDB");
return ds.getConnection();
After the third line is executed I get an exception that says: NamingException - Cannot create resource instance
I have found dozens of posts with this same exception and have tried the suggested solutions with no luck. I'm using a Tomcat 7 server and have made sure to include the necessary ingres jar (iijdbc.jar) to my WEB-INF/lib folder and to my tomcat lib folder.
Any help or suggestions would be greatly appreciated
I don't know much about Ingres, but if attempting to make a datasource is similar to JBOSS and DB2 or MySQL. I noticed that in your WEB.XML you define your resource-ref, but you don't mention the anything about the servlet parameters.
<servlet>
<description>Servlet Description</description>
<display-name>MyServlet</display-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>servlet.MyServlet</servlet-class>
<init-param>
<param-name>MyDB</param-name>
<param-value>java:comp/env/jdbc/MyDB</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Then you would need to code in your sevlet:
InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource)initialContext.lookup(this.getInitParameter("MyDB"));
Hope this helps.
Can you try adding global="jdbc/myDB" attribute as in your Resource tag as follows:
<Context>
<Resource name="jdbc/myDB" auth="Container" type="javax.sql.Datasource"
username="myUser" password="password" driverClassName="com.ingres.jdbc.IngresDriver"
url="databaseURL" maxActive="8" maxIdle="4" maxWait="100" global="jdbc/myDB"/>
</Context>

NoInitialContextException

I have a problem.
I want to connect to database using JDBC, I have Tomcat server. For this I use connection pool.
According to Internet tutorials I've written:
context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/Server" docBase="dbcp" debug="5"
reloadable="true" crossContext="true">
<Resource name="jdbc/TestDB" auth="Container"
type="javax.sql.DataSource" removeAbandoned="true"
removeAbandonedTimeout="30" maxActive="100"
maxIdle="30" maxWait="10000" username="root"
password="newpass"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/delta_server"/>
</Context>
web.xml :
<resource-ref>
<description>DB Connection Pooling</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and I try to connect...
Connection conn=null;
DataSource ds;
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
ds = (DataSource) envContext.lookup("jdbc/TestDB");
conn = ds.getConnection();
But I get a mistake:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
What to do???

Categories