Hi All,
I have my DB and web application running in different machine. And
whenever my DB machine restart my application fail since it can't
connect to the DB. I have to restart my application every time my DB start.
I am using Struts Plug-in to load connection information from web.xml
file and creating the DAO factory from the information. DAO factory is
stored in servlet context. Now this daoFactory is used by each DAO class
to create the connection.
This problem exist in my system for long time and trying to fix it. I
have put my most code here to make things clear. I am using tomcat 7.0.26
1. Context parameter in web.xml
<context-param>
<description>Type of DB.{ 1 = Oracle }</description>
<param-name>dbType</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<description>Resource reference for the database.</description>
<param-name>resRef</param-name>
<param-value>jdbc/mydb</param-value>
</context-param>
2. Plug-in configuration in struts-config.xml
<plug-in className="com.anjib.plugin.DBConfigPlugin">
3. My DBConfigPlugin class
public class DBConfigPlugin implements PlugIn {
private static Log log =
LogFactory.getLog(DBConfigPlugin.class.getName());
private DBConfig dbConfig;
public void destroy() {
//Nothing to do here
}
public void init(ActionServlet servlet, ModuleConfig config)
throws ServletException {
ServletContext servletContext = servlet.getServletContext();
/* Create factory for database */
String resRef = servletContext.getInitParameter("resRef");
int dbType = 0;
if (resRef == null || resRef.trim().length() == 0) {
log.fatal("Parameter resRef is null or invalid");
}
try {
dbType =
Integer.parseInt(servletContext.getInitParameter("dbType"));
} catch (NumberFormatException nfe) {
log.fatal(nfe);
log.error("Parameter dbType is not numeric");
}
if (dbType != DBConfig.ORACLE) {
log.fatal("Parameter dbType has to be 1 (Oracle)");
}
DBConfig = new DBConfig(resRef, dbType);
DAOFactory daoFactory = DAOFactory.getDAOFactory(DBConfig);
servletContext.setAttribute("daoFactory", daoFactory);
}
public DBConfig getDBConfig() {
return DBConfig;
}
public void setDBConfig(DBConfig DBConfig) {
this.DBConfig = DBConfig;
}
}
4. Create connection in DAOFactory class
public abstract class DAOFactory {
private DBConfig dbConfig;
public static DAOFactory getDAOFactory(DBConfig dbConfig) {
switch (dbConfig.getDbType()) {
case DBConfig.ORACLE:
return new OracleDAOFactory(dbConfig);
default:
return null;
}
}
public DAOFactory(DBConfig dbConfig) {
this.dbConfig = dbConfig;
}
public Connection createConnection() throws DAOException {
try {
String str = "java:comp/env/" + dbConfig.getResRef();
DataSource dataSource = (DataSource)
ServiceLocator.getInstance().getDataSource(str);
return dataSource.getConnection();
} catch (SQLException se) {
throw new DAOException(se.getMessage(), se);
} catch (ServiceLocatorException tase) {
throw new DAOException(tase.getMessage(), tase);
}
}
}
5. In my com.anjib.actions.BaseAction class
public abstract class BaseAction extends
org.apache.struts.action.Action {
private static Log log =
LogFactory.getLog(BaseAction.class.getName());
protected DAOFactory daoFactory = null;
private String message = null;
private UserInfo userInfo = null;
@Override
public ActionForward execute(ActionMapping mapping, ActionForm
form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
userInfo = new UserInfo();
setUserInfo((UserInfo)
request.getSession().getAttribute("userInfo"));
ActionErrors errors = new ActionErrors();
if (request.getSession().getAttribute("loginStatus") ==
null) {
errors.add("error", new
ActionMessage("error.notloggedin"));
this.saveErrors(request, errors);
return mapping.findForward("sessionEnded");
}
ServletContext servletContext = servlet.getServletContext();
try {
daoFactory = (DAOFactory)
servletContext.getAttribute("daoFactory");
} catch (NullPointerException npex) {
log.debug(npex);
log.error("Couldn't find the valid factory class.");
message = "Factory value is NULL.";
errors.add("label", new
ActionMessage("error.null.factory"));
saveErrors(request, errors);
request.setAttribute("MYEXCEPTION", new
DAOException(message, npex));
}
}
protected abstract ActionForward executeAction(ActionMapping
mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException;
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
}
6. Context.xml
<Resource auth="Container"
driverClassName="oracle.jdbc.driver.OracleDriver"
maxActive="20"
maxIdle="10"
maxWait="2000"
name="jdbc/mydb"
password="passw0rd"
testOnBorrow="true"
type="javax.sql.DataSource"
url="jdbc:oracle:thin:@//localhost:5000/TESTDB"
username="scott"
validationQuery="SELECT 1 FROM DUAL"
/>