I wrote a servlet and run it on tomcat6. When there is a query sent to the specified DNS, the servlet will get information and use them to search in the database(mysql), then write some thing back. I use connection pool in the tomcat6. However, when I'm trying to do a load test on my program, I found the throughput is extremely low and many exceptions like
Response code: Non HTTP response code:
java.net.SocketTimeoutException Non HTTP response message: Read timed
out
Your result:
Team and Account info\n at java.net.SocketInputStream.socketRead0(Native Method); at
java.net.SocketInputStream.read(SocketInputStream.java:152); at
java.net.SocketInputStream.read(SocketInputStream.java:122); at
org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166); at
org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90); at
org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281); at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92); at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:61); at
org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254); at
org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289); at
org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252); at
org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191); at
org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300); at
org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127); at
org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:715); at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:520); at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906); at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805); at
org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:475); at
org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:295); at
org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74); at
org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1105); at
org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1094); at
org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:429); at
org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:257); at
java.lang.Thread.run(Thread.java:745)
Can somebody give me some suggestions? Here is my code of servlet and this is the only Java code I use in this web project, thanks
#SuppressWarnings("serial")
public class Servlet extends HttpServlet {
#Override
public void doGet(final HttpServletRequest req, final HttpServletResponse res) throws IOException {
Connection conn = null;
DataSource ds = null;
InitialContext ctx;
try {
ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysql");
conn = ds.getConnection();
final Statement stmt = conn.createStatement();
stmt.executeQuery("SET NAMES 'utf8mb4'; ");
} catch (final SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
res.setContentType("text/plain;charset=UTF-8");
final PrintWriter pw = res.getWriter();
try {
final Statement stmt = conn.createStatement();
String teamInfo = "aa\n";
ResultSet rs = null;
final String info = req.getQueryString();
final String[] sp = info.split("&");
final String[] child0 = sp[0].split("=");
final String[] child1 = sp[1].split("=");
final String sqlString = "select * from tweets where timeandid=\"" + child1[1] + child0[1] + "\"";
rs = stmt.executeQuery(sqlString);
rs.next();
final String a = rs.getString(2);
teamInfo = teamInfo + rs.getString(3) + ":" + rs.getString(4).trim() + ":" + a + "\n";
pw.print(teamInfo);
pw.flush();
rs.close();
stmt.close();
} catch (final SQLException ex) {
System.out.println(ex);
} finally {
System.out.println("over");
}
pw.close();
try {
conn.close();
} catch (final SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Related
I was working on a java project and it was working just fine. I was able to make connections. I closed all the connections properly in finally block. Now I am not able to make connections or even open psql in my terminal. How can I make it work as before. Much much appreciated
import java.sql.Connection;
import com.mchange.v2.c3p0.*;
public class MyConnection {
public static Connection getConnection(){
ComboPooledDataSource cpds1 = new ComboPooledDataSource();
String dbDriver = "org.postgresql.Driver";
String dbName = "jdbc:postgresql://localhost/postgres";
cpds1.setJdbcUrl(dbName);
String userName = "user_1";
cpds1.setUser(userName);
String password = "mypass";
cpds1.setPassword(password);
cpds1.setMaxStatements( 180 );
try
{
cpds1.setDriverClass(dbDriver);
return cpds1.getConnection();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
This is where I'm calling it
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException
{
PrintWriter writer = response.getWriter();
JSONObject jo = new JSONObject();
JSONObject jObj;
Statement stmt = null;
Connection con = null;
PreparedStatement ps;
ResultSet rs = null;
try
{
jObj = UtilityClass.getJSON(request);
String uname = ((String) jObj.get("uname"));
String pass = ((String) jObj.get("pass"));
String sql = "SELECT * FROM users WHERE username = ?";
try
{
con = MyConnection.getConnection();
System.out.println("Got Connection");
stmt = con.createStatement();
ps = con.prepareStatement(sql);
ps.setString(1, uname);
rs = ps.executeQuery();
if(rs.next())
{
if(BCrypt.checkpw(pass,rs.getString("password")))
{
HttpSession session = request.getSession();
session.setAttribute("uname", uname);
if(session.isNew())
{
System.out.println("new");
}
if(uname.equals("admin"))
{
session.setAttribute("role", "admin");
jo.put("status", "admin");
}
else
{
session.setAttribute("role", "user");
jo.put("status", "authenticate");
}
}
}
writer.print(jo);
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Not Connected");
}
finally
{
if(rs != null)
{
rs.close();
}
if(stmt != null)
{
stmt.close();
}
if(con != null)
{
con.close();
}
}
}
catch(Exception e)
{
System.out.print("JSON Exception");
}
}
Usually, DB Admins are using pooling technologies on Databases. For PostgreSQL one of the more popularly is a PGBOUNCER. We used PGBOUNCER in our large project, the result is excellent. I recommend it to you. To get more information about the pooling system you can read this link. For About Pooling
I have imported the JDBC library, set it to be compiled, and gave the App permission to access Internet.
When a button on Screen is pressed, it should connect to the database and give me the values to implement in the list.
When I press the button, I can see it giving me the "Connecting to database" text, but after about half a second it says "Exception" as defined in that last catch block.
I commented out the three lines of code in onPostExecute, because when I kept them the App would just crash.
public void retrieveData(View view) {
GetData retrieveData = new GetData();
retrieveData.execute();
}
private class GetData extends AsyncTask<String,String,String> {
String msg = "";
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://" + DbStrings.DATABASE_URL + "/" + DbStrings.DATABASE_NAME;
#Override
protected void onPreExecute() {
progress.setText("Connecting to database");
}
#Override
protected String doInBackground(String... strings) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, DbStrings.USERNAME, DbStrings.PASSWORD);
stmt = conn.createStatement();
String sql = "SELECT * FROM video"; //
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
String name = rs.getString("title");
buildNames += name + " ### ";
}
msg = "Process complete.";
rs.close();
conn.close();
stmt.close();
} catch(SQLException connError) {
msg = "An exception was thrown for JDBC.";
connError.printStackTrace();
} catch (ClassNotFoundException e) {
msg = "A Class not found exception was thrown.";
e.printStackTrace();
} catch (java.sql.SQLException e) {
msg = "Exception";
e.printStackTrace();
} finally {
try{
if(stmt != null) {
stmt.close();
}
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
try{
if(conn != null) {
conn.close();
}
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String msg) {
progress.setText(this.msg);
//names = buildNames.substring(0,buildNames.length()-5).split(" ### ");
//itemAdapter = new ItemAdapter(thisContext, buildNames.substring(0,buildNames.length()-5).split(" ### ")); //crashes
//namesList.setAdapter(itemAdapter);
}
}
}
After checking the stack trace I found this:
java.sql.SQLException: Unknown initial character set index '192' received from server.
And so I knew what to search for;
I was using an outdated version of JDBC, (3.x). After importing Version 5.1.46, it is now working :).
App looks like this
In my Database class I have a method connect() and generateCSV(),
First one looks like this:
public void connect() throws Exception {
System.out.println("Begining of connect method");
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
throw new Exception("Driver not found");
}
String ser = "<ser name>";
String user = "<user name>";
String pass = "<password>";
String dbURL = "jdbc:sqlserver://" + ser + ";user=" + user + ";password=" + pass;
con = (Connection) DriverManager.getConnection(dbURL);
System.out.println("Connected! " + con);
}
and the second one generateCSV() like this
public void generate_CSV(String db,String tbl,String date, String out) {
try {
connect();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ResultSet rs = null;
try {
CallableStatement st = con
.prepareCall("{call dbo.generate_CSV(?,?,?,?)}");
st.setEscapeProcessing(true);
st.setString(1, db);
st.setString(2, tbl);
st.setString(3, date);
st.setString(4, out);
rs= st.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
When I fire event and call generateCSV method, method will call connect() and connect to the server and afterwards call my procedure written in mssql.
Unfortunately I receive this...
com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored
procedure 'dbo.generate_CSV'.
What am I missing?
I tried it without specifying the schema but nothing changes.
I'm getting "While trying to lookup 'jdbc.LogDB' didn't find subcontext 'jdbc'. Resolved ''" error when i try to get connection from the Weblogic. I created and tested the datasource and it's working. Also created the target servers. Datasource name is "jdbc/LogDb". Below is the test code i wrote.
public class TestUtils {
private static final Logger logger = LoggerFactory.getLogger(TestUtils.class.getName());
public DataSource ds = null;
public String testConnectionPool() throws SQLException {
Context ctx = null;
Hashtable ht = new Hashtable();
Connection conn;
String result = "";
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
ht.put(Context.SECURITY_PRINCIPAL, "weblogic");
ht.put(Context.SECURITY_CREDENTIALS, "weblogic");
try {
ctx = new InitialContext(ht);
ds = (DataSource) ctx.lookup("jdbc/LogDB");
logger.debug("Weblogic Connection Pool Created");
conn = ds.getConnection();
Statement stmt = conn.createStatement();
stmt.execute("some sql");
ResultSet rs = stmt.getResultSet();
if(rs.next()){
result = result + rs.getString(1);
}
stmt.close();
conn.close();
} catch (NamingException e) {
logger.error("Naming Exception occured at connect: " + e.getMessage());
} catch (Exception e){
logger.error("Exception occured at connect: "+ e.getMessage());
} finally {
try {
if (ctx != null) {
ctx.close();
}
}
catch (Exception e) {
logger.error("Ctx Error");
}
}
return result;
}
}
I tried the following names
"java:jdbc/LogDb"
"java:comp/env" variations etc.
Thanks for the kind answers
I have a servlet deployed on a Jetty 9 server that connects to a MySQL 5.6.17 server using the Connector/J JDBC driver from http://dev.mysql.com/downloads/connector/j/5.0.html.
This particular servlet fires a SQL statement inside a for loop that iterates around 10 times. I have to include the
DriverManager.getConnection(DB_URL, USER, PASSWORD);
line within this loop because the connection closes automatically after the SQL statement has been executed in every iteration of the loop.
Is there a way to keep the connection open, so that getConnection() need be executed only once before the loop starts and then i can manually close it in the finally block.
I have found many posts on this particular issue, but all refer to the connection pooling concept as the solution. But i am just interested in avoiding the connection being closed automatically after each query execution. Shouldn't this be a simple parameter? I am not facing any particular performance problem right now, but it just seems to be a waste of processor and network cycles.
Servlet Code :
public class CheckPhoneNumberRegistrationServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
System.err.println("started CheckPhoneNumberRegistrationServlet");
// define database connection details
final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
final String DB_URL = DatabaseParameters.SlappDbURL;
final String USER = DatabaseParameters.DbServer_Username;
final String PASSWORD = DatabaseParameters.DbServer_Password;
PreparedStatement prpd_stmt = null;
Connection conn = null;
ResultSet rs = null;
int resultValue;
// open a connection
/*try {
conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
} catch (SQLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}*/
JsonParser jsparser;
JsonElement jselement;
JsonArray jsrequestarray;
JsonArray jsresponsearray = new JsonArray();
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
jb.append(line);
} catch (Exception e) {
e.printStackTrace();
}
try {
jsparser = new JsonParser();
jselement = (JsonElement) jsparser.parse(jb.toString());
jsrequestarray = jselement.getAsJsonArray();
for (int i = 0; i < jsrequestarray.size(); i++) {
// System.err.println("i : " + i +
// jsrequestarray.get(i).toString());
try {
conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
prpd_stmt = conn
.prepareStatement("select slappdb.isPhoneNumberRegistered(?)");
prpd_stmt.setString(1, jsrequestarray.get(i).toString()
.replace("\"", ""));
rs = prpd_stmt.executeQuery();
if (rs.first()) {
//System.err.println("result sert from sql server : " + rs.getString(1));
//slappdb.isPhoneNumberRegistered() actually returns Boolean
//But converting the result value to int here as there is no appropriate into to Boolean conversion function available.
resultValue = Integer.parseInt(rs.getString(1));
if(resultValue == 1)
jsresponsearray.add(jsparser.parse("Y"));
else if(resultValue == 0)
jsresponsearray.add(jsparser.parse("N"));
else throw new SQLException("The value returned from the MySQL Server for slappdb.isPhoneNumberRegistered(" + jsrequestarray.get(i).toString().replace("\"", "") + ") was unexpected : " + rs.getString(1) + ".\n");
// System.err.println("y");
}
else throw new SQLException("Unexpected empty result set returned from the MySQL Server for slappdb.isPhoneNumberRegistered(" + jsrequestarray.get(i).toString().replace("\"", "") + ").\n");
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (prpd_stmt != null)
prpd_stmt.close();
} catch (SQLException e1) {
}
try {
if (conn != null)
conn.close();
} catch (SQLException e1) {
}
}
}
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/plain");
// resp.setContentLength(1024);
resp.getWriter().write(jsresponsearray.toString());
System.err.println(jsresponsearray.toString());
} catch (Exception e) {
// crash and burn
System.err.println(e);
}
The problem is that you're closing the connection inside the for loop. Just move both statements: connection opening and connection close, outside the loop.
conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
for (int i = 0; i < jsrequestarray.size(); i++) {
try {
//current code...
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (prpd_stmt != null)
prpd_stmt.close();
} catch (SQLException e1) {
}
}
}
try {
if (conn != null)
conn.close();
} catch (SQLException e1) {
}