android.os.on main thread exception - java

I am trying to connect to my sql DB on my sql server, using the below code.
But when I run it, the above error shows.
I have added the permissions line to the manifest, but still no luck.
Any advice will be appreciated!
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
//test = com.microsoft.sqlserver.jdbc.SQLServerDriver.class;
String connString = "jdbc:jtds:sqlserver://server_ip_address :1433/DBNAME;encrypt=fasle;user=xxxxxxxxx;password=xxxxxxxx;instance=SQLEXPRESS;";
String username = "xxxxxx";
String password = "xxxxxxxxxx";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from TableName");
//Print the data to the console
while(reset.next()){
Log.w("Data:",reset.getString(3));
//Log.w("Data",reset.getString(2));
}
conn.close();
} catch (Exception e) {
Log.w("Error connection","" + e.getMessage());
}

NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence AsyncTask is better.
http://android-developers.blogspot.in/2009/05/painless-threading.html

Related

Blocking " Unknown database" message when connecting a new MYSQL database in Java

I am making an FXML application with intelliJ and MYSQL in Java 11 that allows the user to create a database that has a name of their own choosing. The application:
recognises that the database doesn't yet exist
creates the database via a connect string that uses URL without a specfic DB name
connects to the new database and executes an sql.txt file thereby creating all the required tables.
This approach works save for the fact that when the final statement of the code below executes an automated alert pops up with:
"Cannot connect to database. Please close the program, check the driver is available and that the connection details are correct and then try logging on again".
It does this even though the new database with all required tables has been created and connected to.
Question: Is there anyway to disable this auto-generated message?
protected void execute() throws Exception {
// Connect using URL without DBNAME:This is a re-assignment of inherited value
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// Create database at user request:
String sql = "CREATE DATABASE " + this.newDBName;
stmt = conn.prepareStatement(sql);
stmt.executeUpdate(sql);
StringBuilder sqlText = new StringBuilder();
File file = new File(this.getClass().getResource("createSQLScript.txt").toURI());
/*
Read in the Sql statement text file resource to create tables
using try-with resources and automatic resource closure.*/
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
sqlText.append(line);
}
}
// Set connection object to allow multiple queries in createSQLScript.txt
// A re-assignment of inherited value
conn = DriverManager.getConnection(DB_URL + this.newDBName + "?allowMultiQueries=true", USER, PASS);
stmt = conn.prepareStatement(sqlText.toString());
stmt.executeUpdate(sqlText.toString());
}
PS: DB_URL is - jdbc:mysql://localhost:3306/
This could be related to the fact that you created database in one connection and started accessing it in another connection without closing the previous one.
Connection and PreparedStatement are closable resources. You should always close them with try-finally or try-with-resources pattern, e.g.:
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
// execute stmt...
// populate database...
}
}
try (Connection conn = DriverManager.getConnection(
DB_URL + this.newDBName + "?allowMultiQueries=true", USER, PASS) {
// access newly created database...
}

AS400 system connection with JNDI

I can figure out how to connect to an AS400 through jt400 with JNDI resources just fine:
Connection conn = null;
Statement stmt = null;
try {
Context ctx = (Context) new InitialContext().lookup("java:comp/env");
conn = ((DataSource) ctx.lookup("jdbc/AS400")).getConnection();
System.out.println(conn.getClientInfo());
stmt = conn.createStatement();
//SQL data fetch using the connection
ResultSet rs = stmt.executeQuery("SELECT * FROM LIBRARY.TABLE");
while (rs.next()) {
System.out.println(rs.getString("COLUMN1"));
}
conn.close();
conn = null;
}
catch(Exception e){System.out.println(e);}
However, another part of the application utilizes DataQueues (from the same jt400 library):
String queue = "/QSYS.LIB/" + libraryName +".LIB/" + queueName +".DTAQ";
try{
system = new AS400(server, user, pass);
DataQueue dq = new DataQueue(system, queue);
// Convert the Data Strings to IBM format
byte[] byteData = message.getBytes("IBM285");
dq.write(byteData);
System.out.println("Wrote to DataQueue");
}catch(Exception e){
e.printStackTrace();
System.err.println(e);
}finally{
// Make sure to disconnect
if(system != null){
try{
system.disconnectAllServices();
System.out.println("Disconnected from DataQueue.");
}catch(Exception e){
System.err.println(e);
}
}
}
Inside of this working code for DataQueues references server, user, pass, which isn't ideal.
I'd like to utilize the AS400 JNDI connection I already set up, but every example I see about connecting Java to DataQueues references an example much like this one.
The documentation all seem to point to AS400 system objects which are hard-coded references to servername, user, pass, etc.
Is there better way to utilize DataQueue() with a JNDI reference?
As assumed in the comments above, the DataQueue is not part of the JDBC connection at all, it can't be used to configure the connection for usage to reading and writing to a DataQueue. Since this is the case, it can't also share connection methods that JDBC uses even though the jt400 library connects with JDBC. A properties file or other server-based solutions is required unless a hard-coded connection is specified in the DataQueue/Java examples online (All 1 of them).

Error: Data source rejected establishment of connection, message from server: "Too many connections"

I created an application that writes data to the database every 5 minutes.
However after some time this error appears:
Error: Data source rejected establishment of connection, message from server: "Too many connections"
I've been searching around and tells you to close the connection to the database after every request side.
I tried this:
conexao.close();
But it gives me this error:
No operations allowed after conection closed.
I apologize if the question is not well formulated.
Thanks for the help
---------------------What I tried but didn't work---------------------------
Add
finally{
if(conexao!=null)
conexao.close();
}
Class.forName("com.mysql.jdbc.Driver");
Connection conexao = (Connection) DriverManager.getConnection("jdbc:mysql://localhost/bdTeste", "root", "root");
Statement stm = conexao.createStatement();
BufferedReader reader = new BufferedReader(new FileReader("C:/Users/RPR1BRG/Desktop/test.txt"));
String dados[] = new String[6];
String linha = reader.readLine();
while (linha != null) {
StringTokenizer st = new StringTokenizer(linha, ";\"");
dados[0] = st.nextToken();
dados[1] = st.nextToken();
dados[2] = st.nextToken();
dados[3] = st.nextToken();
dados[4] = st.nextToken();
dados[5] = st.nextToken();
DateFormat dateFormat = new SimpleDateFormat("d-M-yy");
PreparedStatement stmt = (PreparedStatement) conexao.prepareStatement("replace into registos"
+ " (data_registo, hora_registo, IdSensor, Temperatura, Humidade, pt_orvalho) values (?,?,?,?,?,?)");
try {
stmt.setDate(1, new java.sql.Date(dateFormat.parse(dados[0]).getTime()));
stmt.setString(2, dados[1]);
stmt.setString(3, dados[2]);
stmt.setString(4, dados[3]);
stmt.setString(5, dados[4]);
stmt.setString(6, dados[5]);
} catch (java.text.ParseException ex) {
Exceptions.printStackTrace(ex);
}
stmt.executeUpdate();
linha = reader.readLine();
PrintWriter writer = new PrintWriter("C:/Users/RPR1BRG/Desktop/test.txt");
writer.print("");
writer.close();
Verifica();
}
} catch (ClassNotFoundException | SQLException | IOException e) {
System.err.println("Erro: " + e.getMessage());
}finally{
if(conexao!=null)
conexao.close();
}
This kind of problem arises when you are NOT properly closing the connection after usage.
Please use finally block after catch to close the connections appropriately. This is because to ensure that the connection gets closed properly even when there is an unexpected exception or error. Please note that statements inside finally block gets executed always. it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
As you have asked in comment, I have added the code sample to demonstrate practically!
Connection con = null
try{
//Establishing connection to datasource
con = DBConnection.getConnection();
//perform DB operations
...
...
...
}catch(SQLException sqlEx){
/*To catch any SQLException thrown during DB
*Operations and continue processing like sending alert to admin
*that exception occurred.
*/
}finally{
/*This block should be added to your code
* You need to release the resources like connections
*/
if(con!=null)
con.close();
}
Please note that the declaration of Connection variable should be in proper scope to close it in finally block.
Hope this helps!
This may be because of the configured max_connections is not suitable with the Connection Pool size set in JDBC or number of connections you open against DB.
to check number of max_connections in mysql:
show variables like 'max_connections';
make sure you have proper value of opened connections with the DB Max connections.
As from Java 7, java.sql.Connection is AutoCloseable. From now on, you can write your code like this:
try(Connection con = (Connection) DriverManager.getConnection(url, username, pazzword)) {
//your statements
}catch(RuntimeException e) {
}
Restart apache tomcat server will work. This worked for me.
Welcome

Handling Read Timeout caused by network fluctuation

I am having a java application which reads the records(count of records to b read is configurable) from the sql 2008 database.
And process them and this is done in a infinite loop and only stops when application is stopped manually.
The issue im facing here is that the application stops fetching records from database when I get Read Time out error.
And I guess this is because of the network fluctuations.
The code for reading from the db is written in try catch block.so when the error occurs it gets logged but also stops.
I have no idea how to handle such situation and make the application run continuously in spite of the error.
Please let me know how can I handle the error such that my application continues to run.
While reading you should store the information on where you stopped and set the connection up again after it failed to continue.
Like this:
boolean programRuns = true; // set this to false at the end
public void doMyStuff() {
int myLastPosition = 0;
while(programRuns) {
try {
Connection con = /* open your connection */
String statement = /* your statement */ + "WHERE id > " + myLastPosition;
PreparedStatement pstmt = /* prepare your statement */
while(true) {
ResultSet rs = pstmt.executeQuery();
myLastPosition = rs.getInt("id");
/* do whatever you want with the result */
}
} catch (Exception ex) { /* handle the exception */ }
}
}

When my app loses connection, how should I recover it?

I have an app that I'm connecting to a MySQL database. It loses connection in the middle of the night and then spouts about null connections and JDBC hasn't received messages in X seconds.
I call getConnection() before I do anything that requires communication with the SQL server.
This is my getConnection() method:
private Connection getConnection() {
try {
if (connection != null) {
if (connection.isClosed() || !connection.isValid(10000)) {
this.initializeRamsesConnection();
}
} else {
this.initializeRamsesConnection();
}
} catch (Exception e) {
debug("Connection failed: " + e);
}
return connection;
}
In the initializeRamsesConnection() method I put the password and so on information into a string and then I create the connection in the standard JDBC way.
Then I call this method:
private Connection getConnectionFromConnectionString() {
Connection con = null;
String driver = "com.mysql.jdbc.Driver";
try {
Class.forName(driver);//jdbc sorcery
//if there is no connection string
if (getConnectionString() == null) {
HMIDatabaseAdapter.debug("No connection string");
}
//makes a string out of the values of db/host
String str = getConnectionString();
//if there is no driver
if (driver == null) {
debug("" + ": " + "No driver");
}
//Tries to make a connection from the connection string, username, and the password.
con = DriverManager.getConnection(str, username, password);
//if for some reason the connection is null
if (con == null) {
HMIDatabaseAdapter.debug("CONNECTION IS NULL, WHAT?");
}
} catch (Exception ex) {
HMIDatabaseAdapter.debug("getConnection() " + ex);
}
return con;
}
What can I change in either of these methods to accommodate losing connection?
This is not the correct way of retrieving a connection. You're retrieving the connection and assigning it as an instance (or worse, static) variable of the class. Basically, you're keeping the connection open forever and reusing a single connection for all queries. This may end up in a disaster if the queries are executed by different threads. Also, when it's been kept open for too long, the DB will reclaim it because it assumes that it's dead/leaked.
You should acquire and close the connection in the shortest possible scope. I.e. in the very same try block as where you're executing the query. Something like this:
public Entity find(Long id) throws SQLException {
Entity entity = null;
try (
Connection connection = dataSource.getConnection(); // This should return a NEW connection!
PreparedStatement statement = connection.prepareStatement(SQL_FIND);
) {
statement.setLong(1, id);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
entity = new Entity(
resultSet.getLong("id"),
resultSet.getString("name"),
resultSet.getInt("value")
);
}
}
}
return entity;
}
If you worry about connecting performance and want to reuse connections, then you should be using a connection pool. You could homegrow one, but I strongly discourage this as you seem to be pretty new to the stuff. Just use an existing connection pool like BoneCP, C3P0 or DBCP. Note that you should not change the JDBC idiom as shown in the above example. You still need to acquire and close the connection in the shortest possible scope. The connection pool will by itself worry about actually reusing, testing and/or closing the connection.
See also:
Am I Using JDBC Connection Pooling?
JDBC MySql connection pooling practices to avoid exhausted connection pool
Where in your code are the errors on losing connection coming from? This would probably be the best place to start.
Off the top of my head (and I may be wrong), JDBC connections will only close on an actual fatal error, so you won't know they've failed until you try to do something.
What I've done in the past is to invalidate the connection at the point of failure and retry periodically.
Maybe this is what you are looking for:
http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html
For java see autoReconnect:
http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html

Categories

Resources