Tomcat servlet configure JNDI - oracle

Good day, respective all!
My environment:
Tomcat 8.5 under windows 64-bit
All needed jars are placed into $CATALINA_HOME/lib
It is my first attempt to write servlet using ConnectionPool.
After "googling"I made an entry inside $CATALINA_HOME/conf/server.xml:
<context docbase="msgsend" path="/msgsend" reloadable="true">
<context docbase="ssr" path="/ssr" reloadable="true">
<Resource
name="jdbc/OrServlet"
auth="Container"
type="javax.sql.DataSource"
user="STERN"
username="STERN"
password="pwdxxx"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:STERN/pwdxxx#XEPDB1"
/>
</context>
I included following into WEb-INF/web.xml:
<resource-ref>
<description>just a test</description>
<res-ref-name>jdbc/OrServlet</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
When I try to connect to Oracle in traditional way:
try {
cn = DriverManager.getConnection(
"jdbc:oracle:thin:#XEPDB1", "STERN", "pwdxx");
}
catch (Exception e) { }
everything works fine.
But when I try to connect through context:
Connection cn = null;
DataSource ds = null;
try
{
Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
ds = (DataSource)envCtx.lookup("jdbc/OrServlet");
cn = ds.getConnection();
}
catch(NamingException n) {}
catch(SQLException s) {out.println(ds.getClass().getName()+" exception "+s);
;}
I get :
**exception java.sql.SQLException: Cannot create JDBC driver of class '' for connect URL 'null'**
and ds.getClass().getName() in exception handler returns:
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
which is distinct from javax.sql.DataSource as declared in
and .
And it seems to me that ds = (DataSource)envCtx.lookup("jdbc/OrServlet")
doesn't wvwn try to look inside Resource section.
What I missed?
Any help will be very appreciated.
Regards,
Andrew.

Related

Cannot connect to Oracle DB through Java Context method. \Error: Name [comp/env] is not bound in this Context. Unable to find [comp]

I am learning Apache 9.0 web server and Oracle 11g DB within Eclipse EE environment.
When I simply connect using
conn = DriverManager.getConnection(url, "name", "pw");
I can connect to Oracle DB and send SQL and receive result. (everything works.)
But when I try to connect with this method below, I get error.
public class JdbcUtil {
public static Connection getConnection() {
Connection con = null;
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/OracleDB");
System.out.println("ds = " + ds);
con = ds.getConnection();
System.out.println("con = " + con);
con.setAutoCommit(false);
System.out.println("DB connect success! Util");
} catch (Exception e) {
System.out.println("DB connect failure! Util");
e.printStackTrace();
}
return con;
}
Error message is
javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context. Unable to find [comp].
at org.apache.naming.NamingContext.lookup(NamingContext.java:833)
at org.apache.naming.NamingContext.lookup(NamingContext.java:174)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at db.JdbcUtil.getConnection(JdbcUtil.java:14)
at service.mListService.memberList(mListService.java:15)
at controller.mListController.doProcess(mListController.java:45)
So the error is at Context envCtx = (Context) initCtx.lookup("java:comp/env");
But sometimes error is at DataSource ds = (DataSource) envCtx.lookup("jdbc/OracleDB");
This is my context.xml in META-INF (of my current project)
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name = "jdbc/OracleDB"
auth = "Container"
type = "javax.sql.DataSource"
username = "NAME"
password = "PW"
driverClassName = "oracle.jdbc.driver.OracleDriver"
factory = "org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"
url = "jdbc:oracle:thin:#127.0.0.1:1521:xe"
maxActive ="500"
maxIdle = "100"
/>
</Context>
This is my web.xml in WEB-INF/lib (of my current project)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<display-name>MemberBoard</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<description>Connection</description>
<res-ref-name>jdbc/OracleDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
I didn't touch xml files in my tomcat 9.0 server.

Configuring JNDI JDBC for Web App in Tomcat

I'm unable to figure out why JNDI JDBC data source is failing
context.xml in META-INF
<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
<Resource auth="Container"
name="jdbc/BigByte"
type="javax.sql.DataSource"
driverClassName="com.ibm.as400.access.AS400JDBCDriver"
url="jdbc:as400://****.****/****;prompt=false;sort=language;sort language=ENU;sort weight=shared"
username="****"
password="****"
maxIdle="10"
maxActive="200"
maxWait="5"
removeAbandoned="true"
removeAbandonedTimeout="1200" />
</Context>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
*
*
*
<resource-ref>
<description>Big Byte DB Connection</description>
<res-ref-name>jdbc/BigByte</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
my test
DataSource ds = null;
try {
Context initCtx = new InitialContext();
NamingEnumeration<NameClassPair> list = initCtx.list("");
while (list.hasMore()) {
System.out.println(list.next().getName());
}
Context envCtx = (Context)initCtx.lookup("java:comp/env");
ds = (DataSource)envCtx.lookup("jdbc/BigByte");
Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(
"select * from XAAQREV1 where AQABVN = ?");
ps.setString(1, "*****");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String uid = rs.getString("AQABVN");
System.out.println(uid);
}
} catch (NamingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
My console output
2017-09-28 10:13:26,482/: [http-nio-8080-exec-10/:ERROR] - Cannot find the class org/apache/naming/LocalStrings.class
2017-09-28 10:13:26,619/: [http-nio-8080-exec-10/:ERROR] - Cannot find the class org/apache/naming/LocalStrings_en.class
2017-09-28 10:13:26,775/: [http-nio-8080-exec-10/:ERROR] - Cannot find the class org/apache/naming/LocalStrings_en_US.class
2017-09-28 10:13:28,091/: [http-nio-8080-exec-10/:ERROR] - Cannot find the class org/apache/juli/JdkLoggerConfig.class
javax.naming.NameNotFoundException: Name [java:comp/env] is not bound in this Context. Unable to find [java:comp].
at org.apache.naming.NamingContext.lookup(NamingContext.java:824)
at org.apache.naming.NamingContext.lookup(NamingContext.java:172)
at javax.naming.InitialContext.lookup(Unknown Source)
at webx0001.XAC3DFR_ObFnc.ObRun(XAC3DFR_ObFnc.java:189)
...
When I step through my test, the NamingEnumeration list has no elements.
What are the console messages about missing classes about?
What am I missing?
I was not missing anything.
My project uses a Custom ClassLoader that breaks Tomcat JNDI.
I verified that with a simple servlet in a simple project.

Name is not bound in this Context... Datasource not found

Am building a small Jersey (1.9) REST Service and having a Java class as sub-resource where I connect to local database (Postgres 9.3).
For the datasource I have already add the entries in Context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/userProfile">
<Resource
auth="Container"
driverClassName="org.postgresql.Driver"
maxActive="100"
maxIdle="30"
maxWait="10000"
name="jdbc/apiUserProfile"
password="postgres"
type="javax.sql.DataSource"
url="jdbc:postgresql://localhost:5432/apiUserProfile"
username="postgres"/>
</Context>
When I run the application and call the following resource:
http://localhost:8084/userProfile/rest/user/conn
the page is blank - no content- and the tomcat (8.0) on netbeans (8.1) is throwing Error: Null Pointer Exception
javax.naming.NameNotFoundException: Name [jdbc/apiUserProfile] is not bound in this Context. Unable to find [jdbc].
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)
at net.rest.dao.DbConn.apiUserProfileConn(DbConn.java:23)
at net.rest.service.userProfile.returnDatabaseStatus(userProfile.java:51)
I also already have the JAR files in the librairies:
lib/mysql-connector-java-5.1.39-bin.jar
lib/postgresql-9.3-1100-jdbc4.jar
and here is the sub-resource class for the datasource connection:
package net.rest.dao;
import javax.naming.*;
import javax.sql.*;
public class DbConn {
private static DataSource DbConn = null;
private static Context context = null;
public static DataSource apiUserProfileConn() throws Exception {
if(DbConn != null){
return DbConn;
}
try {
if(context == null){
context = new InitialContext();
}
DbConn = (DataSource) context.lookup("jdbc/apiUserProfile");
}
catch (Exception e) {
e.printStackTrace();
}
return DbConn;
}
}
Any Idea pls. how to fix this..
Many Thanks
a.kasbi
The issue is resolved now.. the Apache Tomcat Doc was very helpful:
http://localhost:8080/docs/jndi-datasource-examples-howto.html
http://localhost:8080/docs/jndi-datasource-examples-howto.html#PostgreSQL
The solution for me was adding the following into context.xml under: META-INF
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/apiRest">
<Resource name="jdbc/apiUserProfile" auth="Container"
type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://127.0.0.1:5432/apiUserProfile"
username="postgres" password="postgres" maxTotal="20" maxIdle="10"
maxWaitMillis="-1"/>
</Context>
and the following in web.xml:
<resource-ref>
<description>postgreSQL Datasource example</description>
<res-ref-name>jdbc/apiUserProfile</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The lookup argument in the java Class for the Datasource connection:
...
DbConn = (DataSource) context.lookup("java:/comp/env/jdbc/apiUserProfile");
...
Thanks

Liferay portlet non-liferay JNDI data source null

For a Liferay 6.2 custom portlet accessing a non liferay Oracle database we are running into an issue where the data source returned is null.
We have configured the tomcat/conf/context.xml
<!-- Adding custom New non liferay datasource -->
<Resource name="jdbc/NewPool"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dbservernameorip)(PORT = 9999))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = dbSIDorservicename)))"
username="user"
password="pwd"
maxActive="35"
maxIdle="10"
maxWait="20000"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="3600000"
timeBetweenEvictionRunsMillis="1800000"
testOnBorrow="true"
testOnReturn="false"
/>
The portlet web.xml contains:
<resource-ref>
<description>Oracle Datasource example</description>
<res-ref-name>jdbc/NewPool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The code for lookup is:
String JNDI = "jdbc/NewPool"
_log.debug("JNDI Name is: " + JNDI);
_log.debug("dataSource in dbConnect is :" + dataSource);
Context context = new InitialContext();
Context envContext = (Context)context.lookup("java:/comp/env");
_log.debug("envContext in dbConnect is :" + envContext);
try {
DataSource ds = (DataSource)envContext.lookup(JNDI);
Liferay can use the context.xml resource with a similar data source for the Liferay Oracle database successfully.
Is some other wiring needed for Liferay portlet to establish a connection to another database?
The same portlet code works on weblogic without the web.xml change. Similar JNDI data source lookup code and configuration works on vanilla tomcat (without liferay) and a plain war (non liferay portlet) file.
Update:
I have checked db connections on the server with netstat -an|grep dbport. this does not show an established connection.
I have also tried setting the portal.security.manager.strategy=none in portal-ext.properties. This did not work either.
Any insight is much appreciated as we are kind of stuck here.
Thanks!
I just stumbled over this thread in the Liferay Forum which basically says. oput this in your tomcat/conf/server.xml
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
<Resource name="jdbc/XXX" auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="10" maxWait="5000"
removeAbandoned="true" removeAbandonedTimeout="250" validationQuery="SELECT 1"
username="user2" password="pwd2"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/myOtherDb"/>
and this in your context.xml:
<ResourceLink name="jdbc/XXX" global="jdbc/XXX" type="javax.sql.DataSource">
It should do the trick. If you really asking WHY Liferay can find the jndi resource, but not your portlet:
I have no clue...
We also had some problems using the resource and pools. Since we have very few requests to handle and performance were not a concern for our scenario we used a JDBC connection directly without a pool and it's working fine (we are connecting to a MS Sql server)
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url = "jdbc:jtds:sqlserver://host/dbname";
String driver = "net.sourceforge.jtds.jdbc.Driver";
String db_userName = PropsUtil.get("jdbc.default.username");
String db_password = PropsUtil.get("jdbc.default.password");
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, db_userName, db_password);
String sql = "SELECT * FROM Users";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
// DO WHAT YOU WANT
return true;
}
rs.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
conn.close();
}catch(SQLException se){
}// do nothing
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
And it's working fine. Username and password are configured in portal-ext.properties (We are using the same account used for liferay own db)
Hope this helps
I believe we found our issue. It seems like it was a typo.
All references to dataSource need to be changed to ds. There was a code changed. It turned out the the variable name was not changed to ds in code after the ds variable was declared during troubleshooting the issue.
String JNDI = "jdbc/NewPool"
_log.debug("JNDI Name is: " + JNDI);
_log.debug("dataSource in dbConnect is :" + ds);
Context context = new InitialContext();
Context envContext = (Context)context.lookup("java:/comp/env");
_log.debug("envContext in dbConnect is :" + envContext);
try {
DataSource ds = (DataSource)envContext.lookup(JNDI);
_log.debug("dataSource in dbConnect is :" + ds)
We need to test this out. I will post the results after the final test.

Configure DB Connection Pooling - Axis2 webservice

I'd like to know how to modify the server.xml file so all my webservices built on axis2 can talk to the DB using Connection Pooling. Each webservice has a different data source, one points to one instance of the DB and the other to another DB server. How do I specify the context that should be used by each service?
Thanks in advance,
Pojo
If you want to use connection pool in your project , Ensure that you have the following code set up for the Tomcat connection pooling to work in context.xml file:
1)Create file with name "context.xml" if it's not exist under directory "WebContent/META-INF/context.xml" with the following content:
For My Project , Please modify it with appropriate value :
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/dbcp" docBase="dbcp">
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
removeAbandoned="true" removeAbandonedTimeout="30" maxActive="80"
maxIdle="30" maxWait="10000" username="sontn" password="nhantien"
driverClassName="org.postgresql.Driver"
url = "jdbc:postgresql://localhost/group8" useUnicode="true"
characterEncoding="utf-8" characterSetResults="utf8"/>
</Context>
Or you can copy file : context.xml into directory "$Catalian\webapps\axis2\META-INF"
How can you get connection pool?
In your webservice method : create method getConnection() with following content:
public Connection getConnection() {
Connection connection = null;
try {
Context envCtx = (Context) new InitialContext().lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
connection = ds.getConnection();
}
catch (Exception e) {
System.out.println("Connection error: " + e.getMessage());
}
return connection;
}
Thanks

Resources