I am new to this JDBC driver. I am looking for ways to save user data from my android app to the google cloud mySQL. I happen to come across that JDBC might get this done.
However, I encounter this error No suitable driver found for jdbc:mysql://google/waveUserData?cloudSqlInstance=wavdata&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false
I have already downloaded the JDBC driver and put inside /library/java/extensions
Please help me with this, or please recommend me a method to efficiently user data from app to Google cloud mysql.
This is the code I am referring to: https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/blob/master/examples/compute-engine/src/main/java/com/google/cloud/sql/mysql/example/ListTables.java
package com.google.cloud.sql.mysql.example;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* A sample app that connects to a Cloud SQL instance and lists all available tables in a database.
*/
public class ListTables {
public static void main(String[] args) throws IOException, SQLException {
// TODO: fill this in
// The instance connection name can be obtained from the instance overview page in Cloud Console
// or by running "gcloud sql instances describe <instance> | grep connectionName".
String instanceConnectionName = "<insert_connection_name>";
// TODO: fill this in
// The database from which to list tables.
String databaseName = "mysql";
String username = "root";
// TODO: fill this in
// This is the password that was set via the Cloud Console or empty if never set
// (not recommended).
String password = "<insert_password>";
if (instanceConnectionName.equals("<insert_connection_name>")) {
System.err.println("Please update the sample to specify the instance connection name.");
System.exit(1);
}
if (password.equals("<insert_password>")) {
System.err.println("Please update the sample to specify the mysql password.");
System.exit(1);
}
//[START doc-example]
String jdbcUrl = String.format(
"jdbc:mysql://google/%s?cloudSqlInstance=%s"
+ "&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false",
databaseName,
instanceConnectionName);
Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
//[END doc-example]
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("SHOW TABLES");
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
}
}
}
}
Related
I'm new to Android Studio and I hope you don't consider my question silly.I am trying to write a small program in the terminal of the android studio.When I try to run the same program in my terminal(not android studio) it's working fine.I added the MySQL-connector.jar file in android studio lib by going through this mysql JDBC driver to the android studio.But it didn't work.Please help me.Thanks in advance.
//MySQConnectionExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class MySQLConnectionExample {
public static void main(String[] args) {
Connection conn1 = null;
String result = " ";
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
String sql = " select address from pharmacy";
PreparedStatement prest = conn1.prepareStatement(sql);
ResultSet rs = prest.executeQuery();
while(rs.next()) {
result = rs.getString(1);
System.out.println(result);
}
} catch (SQLException ex) {
System.out.println("An error occurred. Maybe user/password is invalid");
ex.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//Error after execution
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MySQLConnectionExample.main(MySQLConnectionExample.java:16)
When I remove "Class.forName("com.mysql.jdbc.Driver")" from the program this is the error i get
An error occurred. Maybe user/password is invalid
java.sql.SQLException: No suitable driver found for
jdbc:mysql://127.0.0.1:3306/demo
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at MySQLConnectionExample.main(MySQLConnectionExample.java:22)
You can't connect directly to databases from android devices. Build APIs that connects to your database. then connect your Android Application to these APIs.
Check this answer for a the same question https://stackoverflow.com/a/12233178/4442067
I assume you're trying to directly connect to a MySQL database from your Android device. But first, you have a ClassNotFound exception, which means you haven't imported the library.
And when you get the driver to work, there's more problem in this part:
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
By specifying 127.0.0.1 on your Android device, you're trying to connect to a MySQL server on your device. Now I don't know if you can install MySQL on Android, but you may want to install a MySQL server on your computer. This goes without saying that you must use the IP of that computer and have the MySQL port (3306) open on your computer.
So, what you may want to see is something like
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://192.168.1.10:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
This assumes your MySQL server is installed and configured on your computer with IP address 192.168.1.10
Good luck.
EDIT: I can't really recommend this approach for a production application though, because I'm afraid what a hacker who can decompile your code can do with it.
First of all I'd like to say that it is a project for a course in my university and at the same time my first app for Android which is more complicated that a calculator, so I understand that I could have done some unforgivable mistakes, but my priority is that the code should work. It can be insecure and not considering some cases, but as long as those cases won't appear, it will do.
My app is intended to be running on Android and first of all there should appear login screen which takes login and password, makes the hash of the password and contacts a database on a web server to compare hashes. I was told to use a free database db4free.net.
I created a class Serwer, which would be responsible exclusively for contacting the database. As far as I understood from tutorials and stackoverflow questions and answers, the connection should consist of:
Loading the driver,
Registering it in the DriverManager class,
Using getConnection method to open the connection, passing the credentials,
Preparing and executing SQL query,
Fetching a result set.
I also learned that I should download a mysql-connector-java-5.1.38-bin.jar file. As some threads on stackoverflow suggested, I copied it into main directory of the project (I have to copy the workspace and take to professor's computer when I finish), added it to Libraries tab of properties as an external library. Now when I run the project on my smartphone, I get a java.lang.ClassNotFoundException: Didn't find class "com.mysql.jdbc.Driver" error. I also tried to check the library in Order and Export tab - then it even doesn't compile, returning Conversion to Dalvik format failed with error 1.
I've tried many scenarios in other stackoverflow threads, such as cleaning the project in many configurations, changing the order of build path, etc. I suspect that I've made a simple, stupid mistake that I do not see and I hope you will recognize it.
Here is my Serwer class:
package com.planer.serwer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Driver;
import com.planer.MainActivity;
import com.example.planer.R;
import com.planer.pracownik.Pracownik;
public class Serwer {
private Connection conn = null;
private static Driver driver;
private static int status;
private MainActivity parentActivity;
private final String user = parentActivity.getResources().getString(R.string.db_login);
private final String pass = parentActivity.getResources().getString(R.string.db_pass);
private final String url= "jdbc:mysql://db4free.net:3306/kalendarzplaner";
public static final int STATUS_GOOD = 0;
public static final int STATUS_NO_CONNECTION = 1;
public static final int STATUS_NOT_AUTHENTICATED = 2;
public static final int STATUS_SQL_EXCEPTION = 4;
public static final int STATUS_NO_DRIVER = 8;
public Serwer(MainActivity parentActivity){
status = STATUS_NO_CONNECTION;
try {
driver = new com.mysql.jdbc.Driver();
} catch (Exception ex) {
status |= STATUS_NO_DRIVER;
} catch (NoClassDefFoundError e){
status |= STATUS_NO_DRIVER;
}
this.parentActivity = parentActivity;
}
public Pracownik authorize(String login, String passhash){
Pracownik pracownik = new Pracownik("","",false,status);
status |= this.polacz();
if(status != Serwer.STATUS_GOOD) {
pracownik.status |= status;
return pracownik;
}
Statement statement = null;
ResultSet resultSet = null;
String query = "select passhash, imie_nazwisko, czy_kierownik from auth where login='" + login + "';";
try {
statement = conn.prepareStatement(query);
resultSet = statement.executeQuery(query);
resultSet.first();
if(resultSet.getString("passhash").toString().compareTo(passhash)!= 0){
status |= Serwer.STATUS_NOT_AUTHENTICATED;
pracownik.status |= status;
return pracownik;
}
pracownik.login = login;
pracownik.imie_nazwisko = resultSet.getString("imie_nazwisko");
pracownik.czy_kierownik = resultSet.getBoolean("czy_kierownik");
} catch (SQLException ex) {
pracownik.status |= Pracownik.STATUS_SQL_EXCEPTION;
}
return pracownik;
}
public int polacz() {
int done = STATUS_NO_CONNECTION;
if((status & STATUS_NO_DRIVER) != 0)
return done;
// Connection
try {
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(url, user, pass);
done = Serwer.STATUS_GOOD;
} catch (java.sql.SQLException ex) {
done |= Serwer.STATUS_SQL_EXCEPTION;
System.out.println("SQLException: " + ex.getMessage());
}
return done;
}
}
As I said, the status of the result of authorise method is 9, which is expected when the driver is not loaded. I also append my workspace contents.
First, I want to start by suggesting that you tried out Android Studio. It's the new more modern IDE developed specifically for the purpose of Android Development.
Secondly, contacting a database on Android is a lot different than for example contacting a DB from Java/C# in an Desktop application.
To contact an online MySQL Database you need a RESTful service (written in PHP for example) that gets the data from the database and sends it over to the application. The service is like a communication point between the App and the Database. The service usually sends data to the application in a human-unfriendly format like JSON, so your app needs to parse that and then display it.
Here is all of my code. I am trying to connect to my SQL server. These contents in sentences are actually exist. Real username and passwords. But I am getting Null on error catch (not connected). Please let me know where the error could be.
And I also added Internet permission in manifest.
I came across from this article - link
package com.eample.databasetester;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class MainActivity extends Activity {
TextView txv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txv1=(TextView)findViewById(R.id.text_view);
query2();
}
public void query2()
{
txv1.setText("connected");
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
String connString = "jdbc:jtds:sqlserver://50.62.209.49:3306/test;encrypt=fasle;user=XXXX;password=YYYY;instance=SQLEXPRESS;";
String username = "XXXX";
String password = "YYYY";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from test");
while(reset.next()){
txv1.setText("Data:"+reset.getString(3));
}
conn.close();
} catch (Exception e)
{
txv1.setText("Error connection" + e.getMessage());
}
}
}
THis is a really bad idea. You should not connect to a database over the network from a phone. First off, it requires your DB to be publically addressable which is a security risk. Secondly, it means your password for the db is on the clients, and you don't physically control them. Your app will be reverse engineered, they'll get your password, and then your data is fucked. You should always abstract access to the database from any hardware you don't control by use of a webservice. Then the password never leaves your machines and the damage an attacker can do is limited.
Third, this code wont work anyway, you cant do network IO on the UI thread. That's likely why conn returned null. But take this as a sign of the universe telling you to fix things the right way rather than just changing threads.
I have android native application & web service. Our application is University application. Generate long live token for session issue.So we planned to go for MDM, i searched on Google, , I got some solution
Open Mobster (Open Source Mobile Enterprise Backend)
Apache USerGrid_ (Mobile Backend as a service)
OpenMeap - not support native
Problem is I could not find out , whether this MDM are provide device identification facility.If any one knows about it please tell me. Device identification may be any unique id or mac address
or If i am going to developed our own middle layer , how we can get mac address from request header. without passing to service method , from the request should take.
is there any way to take sort-out this issue?
Please help me
Here is how OpenMEAP grabs the Mac address and passes it in the header.
package com.openmeap.thinclient;
import java.io.ByteArrayInputStream;
import com.openmeap.http.HttpRequestExecuter;
import com.openmeap.http.HttpResponse;
import com.openmeap.util.Utils;
public class FirstRunCheck implements Runnable {
private SLICConfig config;
private String macAddress;
private HttpRequestExecuter executer;
public FirstRunCheck(SLICConfig config, String macAddress, HttpRequestExecuter executer) {
this.config = config;
this.macAddress = macAddress;
this.executer = executer;
}
public void run() {
if( config.isDevelopmentMode().equals(Boolean.TRUE) ) {
return;
}
if( config.getNotFirstRun()==null ) {
config.setNotFirstRun(Boolean.TRUE);
try {
String macWithSalt = macAddress+".OPENMEAP#$!#3__234";
String hashValue = Utils.hashInputStream("sha1", new ByteArrayInputStream(macWithSalt.getBytes("UTF-8")));
HttpResponse response = executer.get("http://usage.openmeap.com/tracker.gif?hash="+hashValue);
Utils.consumeInputStream(response.getResponseBody());
} catch( Exception ioe ) {
return;
}
}
}
}
Code for the GCMService:
package com.avilyne.gcm;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Sender;
/**
* Servlet implementation class GCMBroadcast
*/
#WebServlet("/GCMBroadcast")
public class GCMBroadcast extends HttpServlet {
private static final long serialVersionUID = 1L;
// The SENDER_ID here is the "Browser Key" that was generated when I
// created the API keys for my Google APIs project.
private static final String SENDER_ID = "AIzaSyCOLAYwS2P3ELqnTiPs3VPHGquQy1UoEIQ";
// This is a *cheat* It is a hard-coded registration ID from an Android device
// that registered itself with GCM using the same project id shown above.
private static final String ANDROID_DEVICE = "APA91bEF-_Y7t3Vc59OGuK9gnBWDegE4g2KyVgNeVIZbjGWe-4b9FMHrL82oOEYRPVz7_GaCOHbq3PatsuU_pk8jhvGng3Xp-CAv48iPqamer8Y2aajyTvUho9hsy39uNudA8XI4ML09eUsPNH87zcuGc_v2uJj65g";
// This array will hold all the registration ids used to broadcast a message.
// for this demo, it will only have the ANDROID_DEVICE id that was captured
// when we ran the Android client app through Eclipse.
private List<String> androidTargets = new ArrayList<String>();
/**
* #see HttpServlet#HttpServlet()
*/
public GCMBroadcast() {
super();
// we'll only add the hard-coded *cheat* target device registration id
// for this demo.
androidTargets.add(ANDROID_DEVICE);
}
// This doPost() method is called from the form in our index.jsp file.
// It will broadcast the passed "Message" value.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// We'll collect the "CollapseKey" and "Message" values from our JSP page
String collapseKey = "";
String userMessage = "";
try {
userMessage = request.getParameter("Message");
collapseKey = request.getParameter("CollapseKey");
} catch (Exception e) {
e.printStackTrace();
return;
}
// Instance of com.android.gcm.server.Sender, that does the
// transmission of a Message to the Google Cloud Messaging service.
Sender sender = new Sender(SENDER_ID);
// This Message object will hold the data that is being transmitted
// to the Android client devices. For this demo, it is a simple text
// string, but could certainly be a JSON object.
Message message = new Message.Builder()
// If multiple messages are sent using the same .collapseKey()
// the android target device, if it was offline during earlier message
// transmissions, will only receive the latest message for that key when
// it goes back on-line.
.collapseKey(collapseKey)
.timeToLive(30)
.delayWhileIdle(true)
.addData("message", userMessage)
.build();
try {
// use this for multicast messages. The second parameter
// of sender.send() will need to be an array of register ids.
MulticastResult result = sender.send(message, androidTargets, 1);
if (result.getResults() != null) {
int canonicalRegId = result.getCanonicalIds();
if (canonicalRegId != 0) {
}
} else {
int error = result.getFailure();
System.out.println("Broadcast failure: " + error);
}
} catch (Exception e) {
e.printStackTrace();
}
// We'll pass the CollapseKey and Message values back to index.jsp, only so
// we can display it in our form again.
request.setAttribute("CollapseKey", collapseKey);
request.setAttribute("Message", userMessage);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
Since it is a web service, it does not have android_manifest.xml. So permission for internet cannot be added.
If I want to change the host(android.googleapis.com), then how should I do it. (it seems broken).
Have you tried to turn off your firewall? You have to enable gcm ports.
If your organization has a firewall that restricts the traffic to or
from the Internet, you need to configure it to allow connectivity with
GCM. The ports to open are: 5228, 5229, and 5230. GCM typically only
uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide
specific IPs, so you should allow your server to accept incoming
connections from all IP addresses contained in the IP blocks listed in
Google's ASN of 15169.
BTW GCM message request is a simple http post, without Message Builder you have to post a message in json format.
Android developer site
More information about message fields