Establishing connection between Android app and Oracle DB using JDBC driver - java

I am having trouble establishing a connection between my app and an Oracle DB using JDBC drivers.
Host Oracle ver.: Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
.Jar jdbc drivers I have tried: ojdbc5.jar, ojdbc6.jar, ojdbc14.jar, all from oracle itself.
I have granted the application the permission in the manifest.
<uses-permission android:name="android.permission.INTERNET" />
I get absolutely no response, nothing in the logcat. The SQL statement has no effect on the remote DB.
I can connect the remote DB with the same login credentials on my machine with SQL Plus and have all the privileges.
Code from MainActivity.java
package testapp.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.sql.ResultSet;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
super.onCreate(savedInstanceState);
ConnectOra db = new ConnectOra();
ResultSet rs = db.getResult();
ArrayList<String> list = new ArrayList<String>();
while (rs.next()) {
list.add(rs.getString(1));
System.out.println(rs.getString(1));
}
} catch (Exception e) {
System.out.print(e);
}
}
public void btn(View view) {
startActivity(new Intent(MainActivity.this, MainActivity.class));//Just to refresh the mainact.
}
}
Code from ConnectOra.java:
package testapp.myapplication;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import android.util.Log;
public class ConnectOra {
private Connection conn;
private Statement stmt;
public ConnectOra() throws ClassNotFoundException {
try {
System.out.println("in try");
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:#103.A.B.C:15210/mdb";
this.conn = DriverManager.getConnection(url,"XXX","pw");
this.conn.setAutoCommit(false);
this.stmt = this.conn.createStatement();
} catch(SQLException e) {
Log.d("tag", e.getMessage());
}
}
public ResultSet getResult() throws SQLException {
ResultSet rset = stmt.executeQuery("select * from emp;");
System.out.println(rset+"");
stmt.close();
return rset;
}
}
The selected answer works and my code works too.
Android cant work with ojdbc5.jar, ojdbc6.jar as they require some Java SE components not available on Android. So, we have to use ojdbc14.jar since its older than ojdbc5.jar and ojdbc6.jar and doesn't require advance Java components, this also means that only the basic functions are there with ojdbc14.jar.
With ojdbc14.jar you might have to set "SQLNET.ALLOWED_LOGON_VERSION=8" in sqlnet.ora on the remote host running the DB. This will allow older clients to connect to newer DB otherwise it throws the error ORA-28040: No matching authentication protocol.
It is also vital to close the Connection and Statement after the SQL statements have been executed, else the changes aren't saved in the actual remote DB.

Can you try out this code and post the error log. Also a word of caution, you really shouldnt do this, you should have an application sever like this to manage connections to Oracle DB. But if you wanna play it unsafe, try out this code :
String driver = "oracle.jdbc.driver.OracleDriver"; //
String serverName = "localhost";
String portNumber = "1521";
String db = "XE";
String url = "jdbc:oracle:thin:#" + serverName + ":" + portNumber + ":"
+ db; // connectOracle is the data
// source name
String user = "system"; // username of oracle database
String pwd = "root"; // password of oracle database
Connection con = null;
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
Class.forName(driver);// for loading the jdbc driver
System.out.println("JDBC Driver loaded");
con = DriverManager.getConnection(url, user, pwd);// for
// establishing
// connection
// with database
Statement stmt = con.createStatement();
serverSocket = new ServerSocket(8888);
System.out.println("Listening :8888");
while (true) {
try {
socket = serverSocket.accept();
System.out.println("Connection Created");
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
System.out.println("ip: " + socket.getInetAddress());
// System.out.println("message: " +
// dataInputStream.readUTF());
ResultSet res=stmt.executeQuery("select * from person");
while(res.next()){
System.out.println(res.getString(1));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And read again, this is not recommended.

Related

Android studio can't connect to database in Azure sql server

I am using android studio to develop an application and using Azure Sql Server to host my database. The problem is I was able to connect to my database on SQL server but it has an error of Object not found in my database.
I found out that it might be connecting to my master database instead of the database I want it to connect to. Is there any solution to solve the problem?
package com.example.lenovo.testing1;
import android.annotation.SuppressLint;
import android.os.StrictMode;
import android.util.Log;
import java.sql.*;
public class ConnectionClass {
String hostName = "haozailai.database.windows.net";
String dbName = "haozailai";
String user = "username";
String password = "password";
#SuppressLint("NewApi")
public Connection CONN() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String ConnURL;
Connection conn = null;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
String url = String.format("jdbc:jtds:sqlserver://haozailai.database.windows.net:1433;database=haozailai;user=username;password=password;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;");
conn = DriverManager.getConnection(url);
}catch (SQLException se)
{
Log.e("error here 1 : ", se.getMessage());
}
catch (ClassNotFoundException e)
{
Log.e("error here 2 : ", e.getMessage());
}
catch (Exception e)
{
Log.e("error here 3 : ", e.getMessage());
}
return conn;
}
}
Picture of my database structure
I tried to connect my sqlserver via java jdbc and did not reproduce your issue.
I can connect to my application db successfully.
My test code:
import java.sql.*;
public class Test {
public static final String url = "jdbc:sqlserver://***.database.windows.net:1433;database=***;user=***password=***;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
public static final String name = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
public static Connection conn = null;
public static PreparedStatement pst = null;
public static Statement stmt = null;
public static ResultSet rs = null;
public static void main(String[] args) {
try {
String SQL = "select * from dbo.Student";
Class.forName(name);
conn = DriverManager.getConnection(url);
stmt = conn.createStatement();
rs = stmt.executeQuery(SQL);
while (rs.next()) {
System.out.println(rs.getString("name"));
}
close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void close() {
try {
conn.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
After some research, I found out it is because of your connect url.
You need to modify your connect url :
jdbc:jtds:sqlserver://haozailai.database.windows.net:1433/<your application db name> ...
You could refer to the pages below for more details.
https://sourceforge.net/p/jtds/discussion/104389/thread/a672d758/
how to connect sql server using JTDS driver in Android
Update answer:
I have made a slight adjustment to your connect URL and can connect to my application database normally.
try {
String SQL = "select * from dbo.Student";
Class.forName("net.sourceforge.jtds.jdbc.Driver");
String url = String.format("jdbc:jtds:sqlserver://***.database.windows.net:1433/<your database name>;user=***;password=***;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;");
conn = DriverManager.getConnection(url);
stmt = conn.createStatement();
rs = stmt.executeQuery(SQL);
while (rs.next()) {
System.out.println(rs.getString("name"));
}
close();
} catch (Exception e) {
e.printStackTrace();
}
Notice that remove the database=*** and add "/<your database name>" after your host string.
Please refer to the above code and try again.Any concern, please let me know.
Hope it helps you.
I know this answer is waay too late, but I found this video that totally works: https://www.youtube.com/watch?v=WJBs0zKGqH0
The thing is, you have to download a jtds jar, the guy in the video says where you can get it from and also, you need to add "jtds" before "sqlserver" in connection url and edit the way the 'databe' is written in the connection url, like this:
jdbc:jtds:sqlserver://serverName.database.windows.net:portNr:DatabaseName=dbName;user=....

unable run restfull webservice in java while connecting to sqlsever

I am trying to call a web service that returns data from my sqlsever database in json format
This my code to get data from sqlsever and convert it to a json.
Here a function getAllDataJson() returns a String value of the result.
This is working fine when i call it to display as
SqlDatabase db = new SqlDatabase();
System.out.println(db.getAllDataJson);
but it is not working when i call it from a webservice (This webservice configuration is also fine, i used this webservice to return json String before there it worked fine)
if i combine these both it is showing error in the function getAllData() (which is in the below return code)
at the line:
rs = stmt.executeQuery("select * from persons");
it is showing nullPointerException
It is showing this error
The same error is not there if run it as java application, it is only there when i am running on webservice
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class SqlDatabase {
private static final String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
"databaseName=FIRST;integratedSecurity=true;";
Connection con = null;
Statement stmt = null;
private void connectToDb(){
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
stmt = con.createStatement();
} catch (SQLException e) {
System.out.println("error occured at Database Connection");
} catch (ClassNotFoundException e) {
System.out.println("Class not found");
}
}
void closeDb(){
try{
if(con != null){con.close();}
if(stmt!=null){stmt.close();}
}catch(SQLException e){
System.out.println("error occured while closing Database Connection");
}
}
public ResultSet getAllData(){
ResultSet rs = null;
connectToDb();
try {
rs = stmt.executeQuery("select * from persons");
} catch (SQLException e) {
System.out.println("error occured while getting data");
}
return rs;
}
public String getAllDataJson() throws JSONException{
ResultSet rs = getAllData();
if(rs == null){return null;}
JSONArray jArray = new JSONArray();
JSONObject json = null;
//data to json
try {
while(rs.next()){
for(int i = 1;i<=rs.getMetaData().getColumnCount();i++){
json = new JSONObject();
json.put(rs.getMetaData().getColumnName(i), rs.getString(i));
}
jArray.put(json);
}
} catch (SQLException e) {
System.out.println("near Json");
}
return jArray.toString();
}
}
See at your DB host URL dbc:sqlserver://localhost:1433
It says localhost. Means it will always checks for DB server installed in the same machine where it is getting executed.
Check the DB server and web server are installed in the same machine. If not instead localhost you better to use IP address. Replace the localhost with the IP of DB server running.
Assume the IP of the system where DB server is running is 182.10.10.45 then
dbc:sqlserver://182.10.10.45:1433

Unable to connect Cassandra using jdbc driver

Hi I am trying to connect with Cassandra using jdbc driver. I am getting the following exception.
java.sql.SQLNonTransientConnectionException: Connection url must specify a host, e.g., jdbc:cassandra://localhost:9170/Keyspace1
at org.apache.cassandra.cql.jdbc.Utils.parseURL(Utils.java:190)
at org.apache.cassandra.cql.jdbc.CassandraDriver.connect(CassandraDriver.java:85)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.sub.cas.CqlJdbcTestBasic.main(CqlJdbcTestBasic.java:14)
My cassandra server is running fine and can be accessed from cql shell in windows 10 OS.
This is the java class that I have written.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CqlJdbcTestBasic {
public static void main(String[] args) {
Connection con = null;
try {
Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
con = DriverManager.getConnection("jdbc:cassandra:/root/root#localhost:9160/hr");
String query = "SELECT empid, emp_first, emp_last FROM User WHERE empid = 1";
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery(query);
while (result.next()) {
System.out.println(result.getString("empid"));
System.out.println(result.getString("emp_first"));
System.out.println(result.getString("emp_last"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
con = null;
}
}
}
}
I have gathered my jars from this url :: https://code.google.com/archive/a/apache-extras.org/p/cassandra-jdbc. Unable to find any possible solution. Please help.
Please, check if you have two slashes before your user name. According to
http://www.dbschema.com/cassandra-jdbc-driver.html

Connection Timeout while running sql procedure from servlet

I want to run a procedure which takes approx 15 minutes to run in sql environment. Whereas when I am trying to run it using Servlet I am getting Network error(TCP error). I am using Http Server using ajp to transfer request to Tomcat server. This is my code. can anybody tell me what is going wrong here.
import com.itech.softensity.utils.Utils;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
public class JdbcServlet extends HttpServlet
{
protected static Logger logger = Logger.getLogger(JdbcServlet.class);
static final String jtdsurl = "jdbc:jtds:sqlserver://<server_name>;instance=<instance>;DatabaseName=<databasename>;socketTimeout=100000;socketKeepAlive=true";
static final String USER = "username";
static final String PASS = "password";
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
Connection con = null;
CallableStatement stmt = null;
ResultSet result =null;
try
{
Class.forName("net.sourceforge.jtds.jdbc.Driver");
logger.info("Connecting to database...");
con = DriverManager.getConnection(jtdsurl, "username","password");
logger.info("Creating statement...");
String sql = "exec populateMobRefLit";
stmt = con.prepareCall(sql);
stmt.setQueryTimeout(100000);
stmt.executeQuery();
logger.info("Executing stored procedure check new...");
if(stmt != null){
stmt.close();
}
if(con != null){
con.close();
}
logger.info("Procedure run successfully values: ");
}
catch (Exception e) {
try {
if(stmt != null){
stmt.close();
}
if(con != null){
con.close();
}
}catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
logger.info(Utils.stackTraceToString(e));
}
finally{
try {
if(stmt != null){
stmt.close();
}
if(con != null){
con.close();
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have tried it with JTDS driver as well as microsoft provided jdbc driver as the drivers have specific timeouts. I have tried Hibernate, I have tried Spring, but nothing works.

The service class "WBSer_RwCnt.Rw_Count" does not comply to one or more requirements of the JAX-RPC 1.1 specification

package WBSer_RwCnt;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Rw_Count {
public static Connection getConnection() throws Exception {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/hospital_data";
String username = "root";
String password = "mysql";
Class.forName(driver); // load MySQL driver
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
public static int countRows(Connection conn, String tableName) throws SQLException {
// select the number of rows in the table
Statement stmt = null;
ResultSet rs = null;
int rowCount = -1;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
// get the number of rows from the result set
rs.next();
rowCount = rs.getInt(1);
} finally {
rs.close();
stmt.close();
}
return rowCount;
}
public static void main(String[] args) {
Connection conn = null;
try {
conn = getConnection();
String tableName = "hospital_status";
System.out.println("tableName=" + tableName);
System.out.println("conn=" + conn);
System.out.println("rowCount=" + countRows(conn, tableName));
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
// release database resources
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Error --->
The method "getConnection" on the service class "WBSer_RwCnt.Rw_Count" uses a data type, "java.sql.Connection", that is not supported
When i compile it without creating it as webservice it works correctly
but when i make it as web service it gives output as
Output --->
WBSer_RwCnt.Rw_CountSoapBindingStub#121a412b
Please Help !
Next Try
So this is what i have done after what you have said even then it gives following errors
Exception:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/hospital_data
Message:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/hospital_data
package WBSer_RwCnt;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Rw_Count {
public static int countRows() throws SQLException {
// select the number of rows in the table
Statement stmt = null;
ResultSet rs = null;
System.out.println("ram");
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/hospital_data";
String username = "root";
String password = "mysql";
try {
Class.forName(driver);
}
catch (ClassNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
// load MySQL driver
Connection conn = DriverManager.getConnection(url, username, password);
int rowCount = -1;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM hospital_status");
// get the number of rows from the result set
rs.next();
rowCount = rs.getInt(1);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
finally {
rs.close();
stmt.close();
conn.close();
}
return rowCount;
}
}
i have the added all jar files including the java mysql connectors
This is not going to be a full answer as I'm not exactly sure about the tools you are using to compile the web service, but anyway, here goes:
Basically, a connection is something that is only valid on a particular machine. If it's a TCP/IP connection, it consists of two pairs: source host and port, and target host and port. If it's a Linux socket, then it is an entry in that particular machine's directory tree.
A database connection is usually built on one of those constructs, so it, too, is particular to a machine.
Therefore, it doesn't make sense to pass a Connection object to the user who calls your method from some remote machine. And since it doesn't make sense, the JAX-RPC standard does not include a serialization for Connection, and that's why it fails.
Your problem is that you have designed your method such that it accepts a connection as a parameter, and uses that connection to access the database. This works OK locally, but is not a good design for a remote service.
Instead, your method should acquire the connection internally. The remote user should access just the countRows method, with the name of the table, and countRows should call getConnection, use the connection, and the close it.
You shouldn't have a main method in a web service. And the getConnection method should be changed from public to private, so that countRows can access it. When it is private, I believe the web service compiler will not complain about it because it doesn't have to create a serialization for it.

Categories