You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Eric Wulff <ew...@gmail.com> on 2005/01/09 04:42:18 UTC

connection pool ? tomcat hangs

Hi all, I am still experiencing a problem by which tomcat hangs upon
attempting to execute a query under a specific circumstance, but I
don't know why.  I am attempting to utilize a connection pool and the
problem here in lies the problem I believe.  This is what happens,
Tomcat will hang until my session times out and then report the
following...
      java.sql.SQLException: System or internal error... 
then the app seems to login again immediately after that, without user
prompt, and immediately returns...
      java.net.SocketException: Broken pipe

Then I am required to restart my app.  All works fine until there is
inactivity for 20 minutes.   Note that my session is set to time out
after 20 minutes and it does... still this problem occurs after
inactivity of > 30 minutes.  I am able to log out and log back in
after the session times out (20 minutes) but before the 30 minute
mark.  Then the problem occurs at my "rset = stmt.executeQuery()" code
in the login process.  Details...

 - OS: fedora core 2
 - tomcat 5.0.28
 - connecting to informix dynamic server 9.1
 - $CATALINA_HOME/common/lib/ contains, among other jars...
commons-collections-3.1.jar
commons-dbcp-1.2.1.jar
commons-pool.1.2.jar
ifxjdbc.jar

Notes: these jars are located NOWHERE else as recommended by the Tomcat docs.
Also my $CLASSPATH does not include the commons jars or ifxjdbcx.jar
drivers specifically but they are placed in the
$CATALINA_HOME/common/lib/ as per the Tomcat config docs...

 - my context descriptor is located @ $CATALINA_HOME/conf/engine/host/
 - my app sits in $CATALINA_HOME/webapps/
 - I have no context descriptor in my server.xml
 - I have a SessionListener class that closes the connection and
invalidates the session when it's destroyed

 - below copied is code I use to connect and where it gets stuck,
context, server.xml, web.xml.  Sorry for all the DEBUG stmts... 
obviously I've been working on this for awhile...

Thx much
Eric

CONNECTION POOL METHOD LOCATED IN THE CONTROLLER O FMY APP
	private void setConnectionPool() {
		try{
			// next two lines obtain our environment naming context
			Context initialContext = new InitialContext();  // throws NamingException
			Context environmentContext = (Context)
initialContext.lookup("java:comp/env");  // throws NamingException
			// look up our data source
			dataSource = (DataSource) environmentContext.lookup("jdbc/wms"); 
// throws NamingException
			console.println("DEBUG: Dispatcher.setConnectionPool(): dataSource set...");
		} catch(NamingException e) {
			console.println("EXCEPTION:
Dispatcher.setConnectionFromConnectionPool(): " + e);
		}
	}
	

LOGIN METHOD OF CONTROLLER/DISPATCHER OF APP:
	private void login(HttpSession session, HttpServletRequest req,
HttpServletResponse res) {
		//if(dataSource == null) {
			//if(DEBUG){console.println("DEBUG: Dispatcher.login(): dataSource
null...");}
			setConnectionPool();  // setting data source
			if(DEBUG){console.println("DEBUG: Dispatcher.login(): set
connection pool...");}
		//}
		if(connection == null) {
			if(DEBUG){console.println("DEBUG: Dispatcher.login(): connection null...");}
			try { 
				// allocate and use a connection from the pool
				connection = dataSource.getConnection(); 
				if(DEBUG){console.println("DEBUG: Dispatcher.login(): connection
received... ");}
				session.setAttribute("connection", connection);
			} catch(SQLException e) { 
				if(DEBUG){console.println("EXCEPTION: Dispatcher.login():
dataSource - getConnection() failed: " + e);}
			}
		}
		EmployeeBean employee = new EmployeeBean();
		MessageBean message = getMessage(session);
		message.setView("login");
		String employeeId = req.getParameter("employeeId");
		String employeePassword = req.getParameter("employeePassword");
		// EMPLOYEE ID OR PASSWORD DO NOT CONTAIN INPUT VALUES ?
		if(UtilityBean.isEmpty(employeeId) || UtilityBean.isEmpty(employeePassword)) {
			message.setInputError("employee id or password are empty.  Please
try again.");
			session.setAttribute("message", message);
			forwardTo(req, res, ".");
		} else { // EMPLOYEE ID AND PASSWORD CONTAIN VALUES
			employee.login(session, employeeId, employeePassword, message);  //
LOGIN AND SET EMPLOYEE
			//employee.login(connection, employeeId, employeePassword,
message);  // LOGIN AND SET EMPLOYEE
			// employee.login(employeeId, employeePassword, message);  // LOGIN
AND SET EMPLOYEE
			session.setAttribute("message", message);  // MSG PUT TO SESSION REGARDLESS
			//if(DEBUG) {console.println("DEBUG: Dispatcher.login(): context
path: " +  req.getContextPath() + "; ");}
		    if(!message.containsError()) { // IF LOGIN SUCCESS
				session.setAttribute("employee", employee);
				forwardTo(req, res, "./inventory/");
			} else { // LOGIN FAILURE
				forwardTo(req, res, ".");
			}
		}		
		if(connection != null) {
			try { 
				if(!connection.isClosed()) { 
					if(DEBUG){console.println("DEBUG: Dispatcher.login(): CLOSING
CONNECTION");}
					connection.close(); 
				}
			} catch(SQLException e) { 
				; 
			}
		}
		connection = null;
	}
	
	
STUCK IN HERE -> LOGIN OF OBJ WHERE CONNECTION AND QRY HAPPENS:
	public void login(HttpSession session, String id, String pwd,
MessageBean message) {
		Connection conn = (Connection) session.getAttribute("connection");
		if(conn == null) {
			if(DEBUG){console.println("DEBUG: employee.login(), conn == null");}
			if(DEBUG){console.println("");}
			return;
		}
		Statement stmt = null;
		ResultSet rset = null;
		try {
			String loginQry = 
			"SELECT * " +
			"FROM employee " +
			"WHERE (id = '" + id + "') and (password = '" + pwd + "');";
			if(DEBUG){console.println("DEBUG: employee.login(), loginQry: " +
loginQry + "; ");}
			if(DEBUG){console.println("");}
			stmt = conn.createStatement();  // TOMCAT HANGS ON THIS******
			if(DEBUG){console.println("DEBUG: employee.login(),
conn.createStatement() successful; ");}
			if(DEBUG){console.println("");}
			rset = stmt.executeQuery(loginQry);
			if(DEBUG){console.println("DEBUG: employee.login(), executed query; ");}
			if(DEBUG){console.println("");}
			if(rset.next()) {  // LOGIN SUCCESS ?
				// OPTIMIZE: add a login success, now adjusting your settings message
				employeeId = id;
				employeePassword = pwd;
				setEmployeeAttributes(conn, rset, message);
			} else {  // FIELDS HAD VALUES BUT LOGIN FAILED - 11/23: DECIDED
MORE SECURE NOT TO REPORT WHY, JUST SAY FAILED FOR ONE OF THOSE
REASONS
				//stmt = conn.prepareStatement( 
				//"SELECT id FROM employee " +
				//"WHERE (id = '" + id + "')");
				//ResultSet rsetId = stmt.executeQuery();
				//if(!rsetId.next()) {  // no results means employeeId failed, so we're done
				//	message.setInputError("Employee Id Failure.  Password not checked.");
				//} else { // not employee_id failure, then it was a password failure
				//	message.setInputError("Password Failure");
				//}
				message.setInputError("NOT AUTHORIZED:  Invalid id and/or
password."); // AS OF 11/23/2004
			}
			rset.close();
			rset = null;
			stmt.close();
			stmt = null;
			conn = null; // clear the pointer - closing it in Dispatcher and
SessionListener only
		} catch (Exception e) {
			if(DEBUG){console.println("EXCEPTION: Employee.login(): " + e);}
			message.setApplicationException("EXCEPTION: Employee.login(): " + e);
		} finally {  // Always make sure result sets and statements are
closed, and the conn is returned to the pool (this is taken care of in
Dispatcher) - see:
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html
-> 'Random Connection Closed Exceptions' at bottom of page
			if(rset != null) {
				try { rset.close(); } catch(SQLException e) { ; }
				rset = null;
			}
			if(stmt != null) {
				try { stmt.close(); } catch(SQLException e) { ; }
				stmt = null;
			}
			if(conn != null) {
				conn = null; // clear the pointer - closing it in Dispatcher and
SessionListener only
			}
		}
	}

CONTEXT...  $CATALINA_HOME/conf/Catalina/engine/host/
<Context path="/wms" docBase="wms" debug="0" reloadable="true">
	<Logger className="org.apache.catalina.logger.FileLogger"
    		prefix="localhost_INFORMIXDB_log." suffix=".txt"
			timestamp="true"/>
	<Resource name="jdbc/wms" auth="Container" type="javax.sql.DataSource" />
	<ResourceParams name="jdbc/wms">
		<!-- causes application NOT to be deployed
		<parameter>
		    <name>factory</name>
			<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
			</parameter>
		-->
		<parameter>
			<name>driverClassName</name>
			<value>com.informix.jdbc.IfxDriver</value>
		</parameter>
		<parameter>
			<name>url</name>
			<value>jdbc:informix-sqli://foobar...</value>
		</parameter>
		<parameter>
			<name>username</name>
			<value>foo</value>
		</parameter>
		<parameter>
			<name>password</name>
			<value>bar</value>
		</parameter>
		<!-- Maximum number of dB connections in pool. Make sure you
			configure your connections large enough to handle
			all of your db connections. Set to 0 for no limit.
		-->
		<parameter>
			<name>maxActive</name>
			<value>20</value>
		</parameter>
		<!-- Maximum number of idle dB connections to retain in pool.
			Set to -1 for no limit.  See also the DBCP documentation on this
			and the minEvictableIdleTimeMillis configuration parameter.
		-->
		<parameter>
			<name>maxIdle</name>
			<value>10</value>
		</parameter>
		<!-- Maximum time to wait for a dB connection to become available
			in ms, in this example 30 seconds. An Exception is thrown if
			this timeout is exceeded.  Set to -1 to wait indefinitely.
		-->
		<parameter>
			<name>maxWait</name>
			<value>30000</value>
		</parameter>
		<parameter>
			<name>removeAbandoned</name>
			<value>true</value>
		</parameter>
		<parameter>
			<name>removeAbandonedTimeout</name>
			<value>60</value>
		</parameter>
		<parameter>
			<name>logAbandoned</name>
			<value>true</value>
		</parameter>
	</ResourceParams>
</Context>

server.xml without comments
<Server port="8005" shutdown="SHUTDOWN" debug="0">

  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"
            debug="0"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"
            debug="0"/>

  <GlobalNamingResources>

    <Environment name="simpleValue" type="java.lang.Integer" value="30"/>

    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
       description="User database that can be updated and saved">
    </Resource>
    <ResourceParams name="UserDatabase">
      <parameter>
        <name>factory</name>
        <value>org.apache.catalina.users.MemoryUserDatabaseFactory</value>
      </parameter>
      <parameter>
        <name>pathname</name>
        <value>conf/tomcat-users.xml</value>
      </parameter>
    </ResourceParams>

	</GlobalNamingResources>

  <Service name="Catalina">

    <Connector port="8080"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               debug="0" connectionTimeout="20000" 
               disableUploadTimeout="true" />
    <Connector port="8009" 
               enableLookups="false" redirectPort="8443" debug="0"
               protocol="AJP/1.3" />

    <Engine name="Catalina" defaultHost="localhost" debug="0">
  
      <Logger className="org.apache.catalina.logger.FileLogger"
              prefix="catalina_log." suffix=".txt"
              timestamp="true"/>

      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                 debug="0" resourceName="UserDatabase"/>

   <Host name="localhost" debug="0" appBase="webapps"
	   unpackWARs="true" autoDeploy="true"
       xmlValidation="false" xmlNamespaceAware="false">
	   
        <Logger className="org.apache.catalina.logger.FileLogger"
                 directory="logs"  prefix="localhost_log." suffix=".txt"
            timestamp="true"/>

      </Host>
	  
	   
    </Engine>

  </Service>

</Server>

web.xml...
<web-app>
	<distributable />
	<listener>
		<listener-class>wms.SessionListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>Dispatcher</servlet-name>
		<display-name>WMS 2000 Interface</display-name>
		<servlet-class>wms.Dispatcher</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Dispatcher</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<session-config>
		<session-timeout>20</session-timeout>
	</session-config>
	<resource-ref>
		<description>
			 - wms data source -
			Resource reference to a factory for java.sql.Connection instances that 
			may be used for talking to a particular database that is configured in 
			the web app context XML
		</description>
		<res-ref-name>jdbc/wms</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>
	<welcome-file-list>
		<welcome-file>
			index.jsp
		</welcome-file>
		<welcome-file>
			index.html
		</welcome-file>
		<welcome-file>
			index.htm
		</welcome-file>
	</welcome-file-list>
</web-app>

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org