Android Studio [JDBC]: Why I'm not able to reach the database - java

I know there are some topics discussed this matter before but I tried almost all of the solutions with no luck, and I know some don't recommend using JDBC for dealing with DB in android but as for the purpose of my university project I need to use it.
I have a DB hosted by Hostgator and I'm sure of the information I'm using (Host name, user & pass) as I tried them with other Java IDE and they worked perfectly, so no my pc in not blocked either. I added the Mysql J connector to Android Studio as library, tried 2 versions the latest one and 3.0.17, but there's no luck, I don't know what I'm doing wrong as there's no errors or exceptions appearers in the logcat.
this is the code contain the connection to DB: (P.S.I removed exceptions statements to shorten the code)
protected Void doInBackground(Void... params) {
Connection start;
// tried localhost it didn't work
String url = "jdbc:mysql://xxx.xxx.xxx.xxx:3306/abed_impresent";
String username = "abed_bayoun";
String pass = "xxxxx";
Class.forName("com.mysql.jdbc.Driver").newInstance();
start = DriverManager.getConnection(url, username, pass);
Statement my;
if (start != null) {
test = new ArrayList<>();
my = start.createStatement();
ResultSet res = my.executeQuery("select code from Tutors");
while (res.next()) {
test.add(res.getString("code"));
}
for (int c = 0; test.size() > c; c++) {
if (text.getText().equals(test.get(c))) {
Intent i = new Intent(tStart.this, tChoose.class);
startActivity(i);
Toast.makeText(tStart.this, "test", Toast.LENGTH_LONG).show();
break;
} else continue;
}
}
return null;
all codes under if statement is begin skipped, as it seems the app can't connect to DB.

It is highly not recommended to use jdbc driver on android (as far I can remember ony one jdbc version works with android). Instead of jdbc driver consider creating web service which provides content from your database.

Ok I know what I was doing wrong,
I putted this code in a separate try-catch statement
start = DriverManager.getConnection(url, username, pass);
which is somehow blocked the other codes from getting the value of start and deal with it as a null value.
I included the rest of the code in the same try-catch statement and that did the trick for me.
Thanks everybody for your efforts.

Related

What to Do when JDBC Driver is Invalid?

I'm working on a Java project that uses an Oracle database. When I create a new Oracle driver:
jdbcDriver driver = new jdbcDriver();
...I check it to see if it is valid using:
if (!driver.isValid())
{
throw new UncheckedSqlException("jdbcDriver not valid");
}
What is the correct procedure if the driver is invalid? That is, there is no way to store the data and retry later asynchronously (i.e. without locking up the app), since the database is unavailable. Is the assumption that if I just retry a few times, I'll get a valid driver?
UPDATE
Thanks to EJP for correctly pointing out that jdbcDriver is a class in my code. That is correct -- it is a class in a code base I am working on. EJP requests to have the relevant details posted. Here they are.
package us.mydev.jdbc.util;
import java.sql.*;
import javax.naming.*;
import javax.sql.*;
import org.apache.log4j.Logger;
import us.mydev.data.exception.UncheckedSqlException;
public class jdbcDriver
{
[.....]
public jdbcDriver()
{
try
{
m_iActiveConnections++;
if (showLogMessages)
{
log.debug("jdbcDriver() created, hashcode = " + this.hashCode()
+ ",Active Connection Count is " + m_iActiveConnections);
log.debug("Data Source is " + DS_STANDARDUSER);
}
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(DS_STANDARDUSER);
mydevGetJDBCConn getConn = new sqlConn(ds);
m_conn = getConn.getConnection();
m_iDatabaseType = getConn.getDBType();
}
catch (NamingException _exp)
{ // handle any errors
log.error("failed", _exp);
}
}
public boolean isValid() throws SQLException
{
return m_conn != null && m_conn.isValid(10);
}
[.....]
}
I am finding that after this code:
jdbcDriver driver = new jdbcDriver();
boolean driverIsValid = driver.isValid();
...driverIsValid is false about once in every 1000 or so database accesses. I would imagine that this is an artifact of my current dev system -- I have Oracle running in a virtual machine.
Would it be unusual (or unheard of) for driverIsValid to be false in production in a situation like this? And if it is not unheard-of -- how is it usually handled, given that I can't save the relevant data to the database -- that is, can I just retry getting a database connection a few times and expect to get one?
UPDATE #2
Based on what I've learned from the responses, I need to ask this question using no code from the objects defined in the code base I am working on. I'm going to accept the answer provided by Wen-Bin Luo and re-ask the question more properly.
I think you are meaning if a connection is still valid at time of checking. The isValid method returns whether or not a connection is usable. This method can be invoked at any time you like and allows you to set a timeout.
According to the official manual, the method is
particularly useful in combination with a retry mechanism.
helpful when used in conjunction with the connection timeout and connection harvesting features.
You of course can retry the method in the hope of the database issue resolves afterwards, but more generally you set a timeout and after that you may have to take appropriate action and close the connection.
try { conn = poolDataSouorce.getConnection ... } catch (SQLException sqlexc)
{
if (conn == null || !((ValidConnection) conn).isValid())
// take the appropriate action
conn.close
}
For more information, please check https://docs.oracle.com/cd/B28359_01/java.111/e10788/connect.htm#CHDIDEEB

Huge time accessing database from Java

I'm a junior java programmer and I've finally made my first program, all by myself, apart from school :).
The basics are: you can store data on it and retrieve it anytime. The main thing is, I want to be able to run this program on another computer (as a runable .jar file).
Therefore I had to install JRE and microsoft access 2010 drivers (they both are 32 bit), and the program works perfect, but there is 1 small problem.
It takes ages (literaly, 17 seconds) to store or delete something from the database.
What is the cause of this? Can I change it?
Edit:
Here's the code to insert an object of the class Woord into the database.
public static void ToevoegenWoord(Woord woord) {
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
PreparedStatement addWoord =
conn.prepareStatement("INSERT INTO Woorden VALUES (?)");
addWoord.setString(1, woord.getWoord());
addWoord.executeUpdate();
} catch (SQLException ex) {
for (Throwable t : ex) {
System.out.println("Het woord kond niet worden toegevoegd aan de databank.");
t.printStackTrace();
}
}
}
Most likely creating Connection every time is slow operation in your case (especially using JDBC-ODBC bridge). To confirm this try to put print statements with timestamp before and after the line that get Connection from DriverManager. If that's the case consider not to open connection on every request but open it once and reuse, better yet use some sort of Connection Pooling, there are plenty of options available.
If that's mot the case then actual insert could be slow as well. Again simple profiling with print statements should help you to discover where your code is spending most of the time.
First of all, congrats on your first independent foray. To answer your question / elaborate on maximdim's answer, the concern is that calling:
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
every time you're using this function may be a major bottleneck (or perhaps another section of your code is.) Most importantly, you will want to understand the concept of using logging or even standard print statements to help diagnose where you are seeing an issue. Wrapping individual lines of code like so:
System.out.println("Before Connection retrieval: " + new Date().getTime());
try (Connection conn = DriverManager.getConnection("jdbc:odbc:DatabaseSenne")) {
System.out.println("AFTER Connection retrieval: " + new Date().getTime());
...to see how many milliseconds pass for each call can help you determine exactly where your bottleneck lies.
Advise: use another database, like Derby, hsqldb. They are not so different from MSAccess, (= can use a file based DB), but perform better (than JDBC/ODBC). And can even be embedded in the application (without extra installation of the DB).

JDBC connection hangs at executing rs.next()

I'm trying to read from a mySQL server (in my LAN) a huge resultSet. I implemented it the way I found looking for the setFetchSize method: BalusC's Example. So I did:
con = DriverManager.getConnection(url, user, password);
//con.setAutoCommit(false);
st = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
st.setFetchSize(Integer.MIN_VALUE);
rs = st.executeQuery(query);
int count = 0;
while (rs.next ()) {
// Process entry
String rsc = rs.getString ("resource");
String tpc = rs.getString("topic");
System.out.println(count + ": " + rsc);
++count;
}
Although, it hangs at row 1077 at the line rs.next(). It doesn't throw exception.
EDIT:
After a timeout something new happened. It returned this error
message:
JDWP exit error JVMTI_ERROR_NONE(0): getting frame location [../../../src/share/back/stepControl.c:641]
This error seems to be unrelated.
EDIT2: I've coded a PHP script for retrieving results by stream and happens exactly the same. So it has nothing to do with JDBC... I don't know what is going on!!
The second error message is a deadlock in the Eclipse debugger when hot-swapping and/or JRebel (source):
It is a known problem, actually two problems.
1) Eclipse debugger deadlocks sometimes on hot-swapping (true for any version of JRebel).
2) JVM crash on hotswapping - it is true for JRebel 4M1.
We are expecting bugfix release soon (3.6.2 together with Eclipse plugin) - It will fix first problem. Second problem should be fixed with 4M2 release.
Suggestions:
Update Eclipse to 3.7.2 and JRebel to the latest release
Start the application again.
Use logging/System.out.println() to debug
Check the log of your mysql server for problems (harddisk, network)
Run the query in a SQL workbench (to see whether this is a problem in the query/the server or your code)
OKay, the problem was at the query itself.
I've found that streaming is very sensitive on how query is built. If I make a little change (like adding SELECT DISTINCT) it buffers or hangs. Finally, I left a column out of the query and worked...

How can I update my MySQL database from a Java applet?

I'm new to Java and I need some advice/information on how to debug my Java Applet.
I have created a applet that simply updates a MySQL database. The applet seems to load in the web page with no errors. When I click on my button to update the database it seems to actually make the call to the applet, BUT nothing happens, i.e. no new inserts are made to the database, and the page returns properly.
I have taken the applet code and tested it in a Java desktop app. It works fine, no changes other than removing the "extend Applet" modifier. In the desktop app the database gets updated properly.
If I was given some pointers on how to write to the Java Console window that might help me in debugging the code - but I don't know how to do that. I'm not sure what else to try to find the issue. Everything seems correct to me.
BTW: I'm using Netbeans 6.7 in Windows 7 with the MySQL server and Glassfish 2.1 on a CENTOS (Linux) system.
Here is my code for the applet:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.me.db;
import java.applet.*;
import java.sql.*;
/**
*
* #author Rick
*/
public class dbapplet extends Applet {
/**
* Initialization method that will be called after the applet is loaded
* into the browser.
*/
public void init() {
// TODO start asynchronous download of heavy resources
}
public long SaveToDatabase(String subject, String note, int priority,
String category, String isOpen, String currentSession) {
Connection con = null;
Statement stmt = null;
StringBuilder sb = new StringBuilder();
long lastInsertId = -1;
try {
//build the insert
int IsOpen = (isOpen.contains("1")) ? 1 : 2;
sb.append("INSERT INTO 'LogDetails' ('category', 'priority',
'subject', 'note', 'is_open', 'has_attachements') VALUES");
sb.append(" (");
sb.append("'" + category + "',");
sb.append(priority + ",");
sb.append("'" + subject + "',");
sb.append("'" + note + "',");
sb.append("b'" + IsOpen + "',");
sb.append("b'0');");
//connect and execute the insert
String dbURL = "jdbc:mysql://localhost/authentication";
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbURL, "xxxxxxx", "yyyyyyyy");
stmt = con.createStatement();
stmt.execute(sb.toString());
//get the last inserted id
ResultSet rs = null;
rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next()) {
lastInsertId = rs.getLong(1);
}
rs.close();
} catch (Exception e) { //database problem
System.out.println("Error " + e.getMessage());
System.out.println(sb.toString());
}
return lastInsertId;
} //end of SaveToDatabase
public void QuickSaveToDataBase() {
//disgard the result for now - lets see if we can get this working
this.SaveToDatabase("Quick Save", "Testing of the Quick Save Function",
1, "Testing", "1", "skjdkjd-junk");
}
}
JDBC in Applet should be avoided if all possible. Here are the security issues you will be facing,
You have to open up your database to all IP addresses unless this is an inhouse or enterprise app.
Your database password will be in the applet, readable by anyone with a little reverse-engineering.
If you really want do this, you need to use trusted Applet by signing it.
Since you've got localhost as the server's address..., unless you're running the mysql server on the same box, this will cause a problem. Also, I believe there are security restrictions that disallow contacting localhost over a port from a Java Applet.
Hope this helps.
Applets run in a sandbox that (when in browser) dramatically restrict what they can do. In general, they can't open up connection to any host other than the one they were served up from.
This site: http://www.securingjava.com/chapter-two/chapter-two-2.html is a little dated, but gives you a good general idea for what restrictions you'll be facing.
The most likely reason for the failure is a classloader exception. The applet's classloader is a URLClassloader that can load classes only from certain URLs due to the security implications.
In this case, the applet classloader is most likely unable to load the MySQL JDBC driver. If you have to make the applet work, place the MySQL driver's jar files in an area on the web server that is accessible by the applet, and use the archive attribute of the applet tag to enable the classloader to load the driver.
Why should you not do this?
Although the answer given above will work technically, it is a really bad practice to expose your database on the internet or a DMZ(de-militarized zone); that normally includes an intranet as well in certain companies. Presumably, you are doing this for studying applets and not for production usage. ZZ Coder has already pointed this out.

How do I connect to an Access database over a LAN using Java?

Do you know of any good guides on how to access an Access database using Java?
I know the basics and basic SQL, but I'm thinking more about access control.
private static final String accessDBURLPrefix = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
private static final String accessDBURLSuffix = ";DriverID=22;READONLY=false}";
// Initialize the JdbcOdbc Bridge Driver
static {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch(ClassNotFoundException e) {
System.err.println("JdbcOdbc Bridge Driver not found!");
}
}
/** Creates a Connection to a Access Database */
public static Connection getAccessDBConnection(String filename) throws SQLException {
filename = filename.replace('', '/').trim();
String databaseURL = accessDBURLPrefix + filename + accessDBURLSuffix;
return DriverManager.getConnection(databaseURL, "", "");
}
Some useful links:
http://blog.taragana.com/index.php/archive/how-to-access-ms-access-database-from-jdbc/
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2691&lngWId=2
If you mean using relational databases in Java, you'll need to know JDBC.
You won't be able to do much with security using JDBC. You'll have to build it into the application using something like JAAS or Spring Security.
You can share a database over a shared drive on LAN n then add it to System DSN of other PCs and you can share access database over LAN .. Worked for me like that
I know string is old but maybe useful for someone like me i was frustrated finding a proper and easy way for sharing
JDBC is the way to go. Google for "JDBC tutorial" + mysql, you will get all you need.

Categories