Hello in my project to connect to the DB I was using contex.xml file (where I had all DB data) and #Resource(name = "xyz") annotation to and use it to create dataSource in my Servlet:
#WebServlet(name = "BookControllerServlet", urlPatterns = {"/BookControllerServlet"})
public class BookControllerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private BookDbUtil bookDbUtil;
#Resource(name = "sql2226123")
private DataSource dataSource;
// init method will be called by the app server when this servlet is loaded or initialized
#Override // we inherit it from GenericServlet
public void init() throws ServletException {
super.init(); //To change body of generated methods, choose Tools | Templates.
// create our book db util ... and pass in the connection pool / datasource
try {
bookDbUtil = new BookDbUtil(dataSource); // bookDbUtil is a data member that we've defined
} // dataSource is resource injection item our connection pool and we're passing it right here
catch (Exception exc) {
throw new ServletException(exc);
}
}
However, from day to day it suddenly stopped working. I mean #Resource(name = "sql2226123") does not provide any data. dataSource == null, myConn == null; What happened? context.xml is 100% good was not changed by this time. I had some jdk update recently if I remember correctly. Maybe it has something to do with it? My current java version is: 1.8.0_81-b13. Any ideas? Did anyone hear something about it?
Here is my context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Context path="jadbc/ParkingSystem">
<Resource name="sql2226123"
auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="5" maxWait="10000"
username="sql2226123" password="xxxxxxxx"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://sql2.freemysqlhosting.net:3306/sql2226123"/>
</Context>
I also manage to get following error:
Related
I'm trying to connect a JEE app to a MySQL database. There is a lot of documentations and similar questions on this topic, but none of the solutions i've found works so far (Nonetheless, I may have miss one in particular so feel free to propose).
The server name is db and the database name is joinmyparty
Here is my java code to connect :
public class MySqlConnection {
private static Connection conn;
public static Connection getConn() {
try {
Context initContext = new InitialContext() ;
Context envContext = (Context)initContext.lookup("java:/comp/env") ;
DataSource ds = (DataSource) envContext.lookup("jdbc/joinmyparty") ;
conn = ds.getConnection();
} catch (NamingException e) {
System.out.println("Cannot get connection: " + e);
} catch (SQLException e) {
System.out.println("Cannot get connection: " + e);
}
return conn;
}
Every time I call a DAO, I use this method getConn() to open a connection and i close it in the finally block.
I wrote this into my /tomcat/conf/context.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Resource url="jdbc:mysql://db:3306/joinmyparty"
driverClassName="com.mysql.jdbc.Driver" password="mypassword"
username="myusername" maxWait="10000" maxIdle="30"
maxActive="100" type="javax.sql.DataSource" auth="Container"
name="jdbc/joinmyparty" validationQuery="select 1" testOnBorrow="true"/>
</Context>
I've tried to put the mysql-connector .jar into the /tomcat/lib or into the /WEB-INF/lib and into the build-path. I've also tried multiple versions of connectors (but only one at a time), especialy to get the one with same level as MySQL database.
When I call a servlet which requires to connect the database, I've a blank page with a POST() method and an error 5OO with a GET() method.
Here is the log error (I tried to translate it my best since i'm not english native) :
description : this server has encountered an internal error which prevents it from fulfilling your request
exception
java.lang.NullPointerException
com.picco.user.dao.UserDao.findByEmail(UserDao.java:40)
com.picco.user.servlet.Index.doGet(Index.java:56)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
And here the part of the code concerned (but as I said, all codes using DAO have the same problem).
try {
UserDao udao = new UserDao();
User u = udao.findByEmail(myCookieVal);
SongDao sdao = new SongDao();
ArrayList<Song> list = sdao.getAllSongs(u.getId());
Random rd = new Random();
int count = udao.count();
request.setAttribute("currentSong", list.get(rd.nextInt(list.size())));
request.setAttribute("songList", list);
request.setAttribute("partyCount", count);
this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
} catch(SQLException e) {
e.printStackTrace();
} finally {
HsqlConnection.closeInstance();
}
Dont hesitate to ask me for details if I did not describe enought the problem.
Maybe the problem is that you try to fetch the resource User before having instantiated the connection that is set to null.
The MySQL JDBC JAR belongs in the Tomcat /lib folder. You want the Tomcat class loader to find it first.
Shouldn't your DAO get a connection? I'd add it to the constructor.
I'm using a Payara application server on which I have defined a connection pool in order to lookup after it in my application. The ping made from application server to database works.
In my domain.xml database resource is configured as follows:
<jdbc-resource pool-name="MasterPool" jndi-name="jdbc/master"></jdbc-resource>
<jdbc-connection-pool datasource-classname="org.apache.derby.jdbc.ClientDataSource40" name="MasterPool" res-type="javax.sql.DataSource">
...
</jdbc-connection-pool>
The setup of Context is made on servlet init method.
public void init() throws ServletException {
Context env = null;
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFactory");
try {
env = new InitialContext(ht);
pool = (DataSource) env.lookup("master");
System.out.println("Data source found");
}
catch(NamingException ne) {
throw new ServletException(ne);
}
}
Can you give some insight about the message:
javax.servlet.ServletException: javax.naming.NameNotFoundException: master
I've tried to make the lookup after jdbc/master and java:/comp/env/jdbc/master
Regards,
Make sure you have below line in META-INF/context.xml
<Resource auth="Container"
driverClassName="com.mysql.jdbc.Driver"
......
name="master" // this line is important
.......
/>
I have made a web application using tomcat that is connecting to the database and made some transactions on it, but my database oracle admin is complaining of so many connection from it and tells me that it is always cause the database to hang up due to many connection . so my question is what the best context.xml file to use and what modification should i do to mine?
my context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/applicationName">
<Resource driverClassName="oracle.jdbc.OracleDriver"
maxActive="100" maxIdle="-1" maxWait="30000" name="name" password="password"
type="javax.sql.DataSource" url="url"
username="username" />
</Context>
my Dao Class
public Dao(){
}
Context initContext;
Context envContext;
DataSource ds;
Connection conn;
public Connection getConnection() throws Exception {
initContext = new InitialContext();
envContext = (Context) initContext.lookup("java:/comp/env");
ds = (DataSource) envContext.lookup("name");
conn = ds.getConnection();
if(conn != null){
return conn;
}
return null;
}
Verify that you are closing the connection properly in the code.
Also, you should try
finally {
if(connection!= null) {
connection.close();
connection = null;
}
}
I have an application which is configured to connect to a specific database as per the URL with their unique credentials-
eg -
demo.mydomain.com (DB Name - demo)
client1.mydomain.com (DB Name - client1)
client2.mydomain.com (DB Name - client2)
I have defined the data source in context.xml in my web-inf dir as below -
<!-- demo Environment Configuration Starts -->
<Resource type="javax.sql.DataSource"
name="jdbc/demo"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/demo"
username="demo"
password="demo"
initialSize="10"
maxActive="100"
maxIdle="30"
minIdle="0"
suspectTimeout="60"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
/>
<!-- Client1 Environment Configuration Starts -->
<Resource type="javax.sql.DataSource"
name="jdbc/client1"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/client1"
username="client1"
password="client1"
initialSize="10"
maxActive="100"
maxIdle="30"
minIdle="0"
suspectTimeout="60"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="60000"
/>
The list goes on for all the available clients.
The SysServlet is defined in web.xml with a URL mapping -
<servlet>
<servlet-name>SysInfo</servlet-name>
<servlet-class>com.emsproject.action.common.SysServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SysInfo</servlet-name>
<url-pattern>/eapp/*</url-pattern>
</servlet-mapping>
public class SysServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet{
static final long serialVersionUID = 1L;
private static DataSource dataSource;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
try {
String clientName = request.getPathInfo();
String esmPool = clientName.substring(1, clientName.length()).trim();
/******************************************************
* Below code prepares the datasource by JNDI lookup *
******************************************************/
dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/"+esmPool);
} catch (Exception e) {
e.printStackTrace();
}
}
/*Returns a connection */
public Connection getConnection() throws Exception {
return dataSource.getConnection();
}
/*Closing connection when transaction is over*/
public void freeConnection(Connection dbConn) {
try {
if(null != dbConn){
dbConn.close();
}
} catch (SQLException e){
e.printStackTrace();
}
}
}
The Application is built using -
Struts 2
MySql 5
Tomcat 6
The application works fine without any issue for a single client at a time but
the problems I am facing are as below -
When a client1 performs some insert/update it is reflected to client2 & so on when application is accessed simultaneously by them.
When a Client1 performs a login (I keep certain details in session) & later Client2 logs in to the system the Client2 info is shared or visible to client1.
Simultaneous access is troubling me
Kindly suggest me a solution for the same ....
I have made few changes to the code as below while fetching a connection -
public Connection getConnection(String clientName) throws Exception {
DataSource dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/"+clientName);
return dataSource.getConnection();
}
But I have one concern regarding the statement -
DataSource dataSource = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/"+clientName);
Is it ok to initialize a DataSource every time I need a connection...
Kindly suggest...
You are not technically initializing a DataSource each time you need a connection. You are looking up the DataSource in the JNDI context each time. There will only ever be one instance of each DataSource.
The lookup is pretty fast (essentially just a map lookup) so I personally wouldn't worry too much.
What is going to be much much slower is creating the InitialContext. The creation of InitialContext() is slow and should only be done once in your application and cached.
#Pace
I am adding it as an answer to better format the code in the post I have modified,
The ctx throws a null pointer ........ (I have no idea about caching the InitialContext)
public class SysServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet{
static final long serialVersionUID = 1L;
//Context ctx = null;
InitialContext ctx = null;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
try {
ctx = new InitialContext();
String clientName = request.getPathInfo();
String esmPool = clientName.substring(1, clientName.length()).trim();
} catch (Exception e) {
e.printStackTrace();
}
}
/*Returns a connection */
public Connection getConnection(String clientName) throws Exception {
DataSource dataSource = (DataSource) ctx.lookup ("java:/comp/env/jdbc/"+clientName);
return dataSource.getConnection();
}
/*Closing connection when transaction is over*/
public void freeConnection(Connection dbConn) {
try {
if(null != dbConn){
dbConn.close();
}
} catch (SQLException e){
e.printStackTrace();
}
}
I need sugestions to avoid doing new InitialContext() on every getConnection();
I made few changes to initialize the Context only once per login & this seems to be working fine....
Only had to change the
InitialContext ctx = null;
to
private static InitialContext ctx = null;
Just construct the InitialContext during object construction of the Servlet:
public class SysServlet ....{
private InitialContext ctx = new InitialContext();
....
}
After that, you can do the look-up in the getConnection() and it should work.
This is the first time I am using SQL Server, previously I was working on MySQL and I was creating db connection pool in tomcat successfully. I am trying to use same code to create a connection pool for sql server. Please guide me where I am going wrong.
I am trying login as Windows Authentication, I have copied sqljdbc_auth.dll in tomcat bin directory.
Following is the code I wrote in my context.xml file under META-INF:
Context antiJARLocking="true" path="">
<Resource
auth="Container"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
logAbandoned="true"
maxActive="100"
maxIdle="30"
maxWait="1000"
name="jdbc/mydb"
removeAbandoned="true"
removeAbandonedTimeout="60"
type="javax.sql.DataSource"
url="jdbc:sqlserver://localhost;integratedSecurity=true;" />
</Context>
And below is the java class which is providing connections:
public class ConnectionPool {
private static ConnectionPool pool=null;
private static DataSource dataSource = null;
public synchronized static ConnectionPool getInstance(){
if (pool == null){
pool = new ConnectionPool();
}
return pool;
}
private ConnectionPool(){
try{
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:/comp/env/jdbc/mydb");
}
catch(Exception e){
System.out.println(e);
}
}
public Connection getConnection(){
try{
return dataSource.getConnection();
}
catch (SQLException sqle){
System.err.println(sqle);
return null;
}
}
public void freeConnection(Connection c){
try{
c.close();
}
catch (SQLException sqle){
System.err.println(sqle);
}
}
}
When I tried calling getConnection() then I got following exception:
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
Exception in thread "main" java.lang.NullPointerException
at ConnectionPool.getConnection(ConnectionPool.java:39)