So people are probably going to tell me this is a bad idea, but I'd like to at least give it a go.
EDIT The intention of this app is that it can only work when the device is part of the same network the oracle db is on or is connected to the network via VPN. The information in the database is not going to be globally accessible, which is why I will need direct connection to the oracle db.
Now according to this thread
Connecting the oracle in android application
He was successful in querying the oracle db.
So I have a fairly basic class that when initialised will try to get a connection to my database.
package com.producermobile;
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 {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:#x.x.x.x:1521:PR10";
this.conn = DriverManager.getConnection(url,"xxx","xxx");
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 customer from customers");
stmt.close();
return rset;
}
}
And in my main activity onCreate method I have this
#Override
public void onCreate(Bundle savedInstanceState) {
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));
}
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, list));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
} catch(Exception e) {
}
}
In Eclipse I add the external ojdbc14.jar file to the build path.
However when I run
this.conn = DriverManager.getConnection(url,"xxx","xxx");
I receive the following exception
"Io exception: The Network Adapter
could not establish the connection"
If however I create an instance of this class inside a standard java app with a main method, the connection works. Any ideas?
Oracle has a product that provides both data sync with Oracle DB as well as offline capabilities; it's called Mobile Server
They way it works is, you just store your data in SQLite, and the Oracle client will handle sync. Of course you have to install and configure mobile server, and each new device will need to be provisioned, but once that is done, it "just works!"
There is a download tab in the link above, you can download and try it out of you like.
I hope that helps. Good luck with your problem.
Regards
Eric, Oracle PM
:) yes, I'm one that'll tell u it is a "bad" idea. IMHO, given that Android apps are intended to run on mobiles where connectivity might be an issue or be lost temporarily, I claim each good app should have some degree of offline capabilities. So you'd implement some very basic sync mechanism - as for instance demonstrated with the SampleSyncAdapter - which synchronizes with the apps local SQLite db.
I think this is the best way to go (also for the user experience).
Have you added in the AndroidManifest.xml the
uses-permission android:name="android.permission.INTERNET"
I've to create an app with the same constraint of connectivity and database. I've done this, and I've a lot of Exception (ArrayIndexOutOfBound during the connexion to the database.)
I use ojdbc14.jar for that. So, I "just have to" fix the Exception I have, and it would be OK...
For more information, see this topic
Sorry to revive an old thread but I had this problem for a long time and finally fixed it. Just run eclipse or whatever you're developing in "as administrator" and the error will go away.
Another and much easier approach is to use a Virtual JDBC Driver that relies on a secure three-tier architecture: your JDBC code is sent through HTTP to a remote Servlet that filters the JDBC code (configuration & security) before passing it to the Oracle JDBC Driver. The result is sent you back through HTTP.
There are some free software that use this technique.
Just Google "Android JDBC Driver over HTTP".
Related
A few classmates and I are creating a Java project which requires a database. I have created a connection in MySQL and connected it to my Java project successfully using the following Connect class:
package com.example.javaworkoutgame.Model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Connect {
static Connection con;
public Connect() {
connect();
}
// attempt to connect to MySQL database
public static void connect() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("Driver Loaded Successfully");
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/lab3", "root",
"**********"); // not the actual password
System.out.println("Successful Connection");
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
} catch (SQLException sqle) {
System.err.println(sqle);
}
}
}
This code runs properly on my machine.
I committed and pushed the code to Bitbucket so my partners could access it. However, when they run the code on their computers, they get the following error message:
java.sql.SQLException: Access denied for user 'root'#'localhost' (using password: YES)
Is there something I need to change in MySQL workbench in order for other people to be able to access the database? I could not find any information on this.
The only thing I was able to try was found at this thread:
java.sql.SQLException: Access denied for user 'root'#'localhost' (using password: YES)
I opened a new .sql file and tried running the command:
GRANT ALL PRIVILEGES ON . TO 'root'#'localhost' IDENTIFIED BY '%password%' WITH GRANT OPTION;
(I replaced '%password%' with the actual password)
When I tried that I got the following error message:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY '*********' WITH GRANT OPTION'
No, and you need to stop this line of thought and do some research first.
Your current configuration says that the mysql server is on the very same physical machine that the code is running on. You installed mysql on your dev machine, your friends need to install it on theirs, and each has their own unique database (nothing is shared).
You could, instead, take your mysql server, open it up to the world (which, for virtually all ways internet is made available in residential connections, requires messing with your router to 'open a port').
But then you have an open mysql server, and the username and password are on a public bitbucket site.
It also requires either a permanent IP (which few residential internet providers offer) or a dyndns service. More generally, hosting open MySQL servers that see lots of traffic gets your internet shut down, for good reason. You'd end up hosting a whole bunch of hackers. All hardware in your network will be p0wned and turned into bot nets. Hence, very very bad idea.
Good ways to solve this problem:
Everybody installs their own MySQL server. This is sensible; you're writing code and bound to make mistakes, it'd be real bad if all code you write is first-run and tested on live data. You don't want one of your friends to wipe your database. If you need some initial data to test with, set it up properly, and read up on how to make an SQL dump. With such a dump file you can reset any mysql server to that exact state - and that'd be how you and your friends develop: Set up the DB to be in that known state, write some code, and if you ruin the db by doing so, no problem. Just reset it again.
Set up a VPN between your friends. NOW you can share the IP your system has within the VPN (it'll be 10., 172.16., 192.168.* - if it's 127.0.0.1, it's localhost, i.e. everybody needs to install mysql on their own and nothing is shared, and if it's anything else, you're opening it to the world, which you don't want to do). Do not put the VPN username/password info anywhere in that bitbucket. And you need to trust your friends.
You should have a properties type file so that each person who is going to interact with the code has their local data without the need to replicate yours, in the same way you can have different values in the properties for test or production environments.
example of a property file:
system.properties
#BD
db.driver=com.mysql.cj.jdbc.Driver
db.user=user
db.pass=password
db.server=server_IP
db.port= port_IP
db.db = DB
Then you should have a procedure to read from java the properties inside the file
Utils.java
package com.example.javaworkoutgame.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public final class Utils {
public static Properties getProperties() {
String path = String.format("PATH to your properties FILE/system.properties",
System.getProperty("user.dir"));
Properties properties = new Properties();
try (InputStream is = new FileInputStream(new File(path))) {
properties.load(is);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return properties;
}
}
And finally you make a call to the function that gets the properties from your connection class
Connect.java
package com.example.javaworkoutgame.Model;
import com.example.javaworkoutgame.util.Utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Connect {
Properties properties = Utils.getProperties();
static Connection con;
public Connect() {
connect();
}
// attempt to connect to MySQL database
public static void connect() {
try {
String driver = properties.getProperty("db.driver");
String ip = properties.getProperty("db.ip");
String port = properties.getProperty("db.port");
String db = properties.getProperty("db.db");
String user = properties.getProperty("db.user");
String pass = properties.getProperty("db.pass"):
Class.forName(driver);
System.out.println("Driver Loaded Successfully");
con = DriverManager.getConnection("jdbc:mysql://"+ip+":"+port+"/"+db, user,
pass);
System.out.println("Successful Connection");
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
} catch (SQLException sqle) {
System.err.println(sqle);
}
}
}
About the MYSQL error, if your partners do not have a local mysql environment with the same values as you, they will experience the error you describe, since your configuration is a local configuration, if you need your partners to connect to your pc, you must open the ports of mysql and give them your public IP (not recommended)
I hope this answer helps you!
i am trying to implement java RMI client server connection, i made my server in NetBeans IDE and client class made in oracle database as java store procedure and use this via oracle function in my PLSQL block, everything is working fine but I stuck in little issue below:
I made this java store procedure in SYSTEM user and give dbms_java.grant_permission('SYSTEM','java.net.SocketPermission','192.168.43.25:*','connect,resolve') to SYSTEM user via SYSDBA, "*" is used for all available ports. I get perfect response from my server but till specific session expiry.
Whenever I logout from SYSTEM user and login back again, its again throws me an exception the Permission ("java.net.SocketPermission" "192.168.43.25:56792" "connect,resolve") has not been granted please guide me how can I get rid from this repeated task? because in development environment I'll manage it but how can deploy it on production with this issue. My Environment is Oracle DB 18c XE, Thank You!
Following is my java store procedure:
create or replace and compile java source named rmi as
package rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.Naming;
import java.security.Policy;
public class RmiClient {
public RmiClient(){
}
public static String getRequestFromClient(){
Policy.setPolicy(new MyPolicy());
String result = "";
try {
IServer server = getServer();
result = server.getRequestFromClient();
} catch (Exception ex) {
result = ex.getMessage().toString();
}
return result;
}
private static IServer getServer() throws Exception {
Parameter configurationParameters = new Parameter();
IServer server = (IServer) Naming.lookup( configurationParameters.objectName);
return server;
}
}
Granting permissions with DBMS_JAVA is a little different than a typical Oracle grant. After granting a permission using DBMS_JAVA.GRANT_PERMISSION, you will need to COMMIT at some point after the grant as been executed for it to take affect permanently. Notice how there is a COMMIT after the DBMS_JAVA call in the Oracle documentation.
To pretense, i'm new to web development. I have a java web application that is deployed through Jetty, and I have an issue that is really confusing me. In order to display data from my database in the web app I must establish a database connection, which I can do when I am unit testing my code, but when I call the same methods from .jsp pages to populate the web app I get a message telling me this:
java.sql.SQLException: No suitable driver found for jdbc:sqlserver://localhost:1433;integratedSecurity=true;database=TicketITBookingSystemDatabase;loginTimeout=30;
Here is the rest of the relevant code:
public void queryDatabase(String query){
ResultSet resultSet = null;
String connectionUrl = establishDatabaseConnection();
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();) {
//Execute the sql statement passed as the query parameter.
resultSet = statement.executeQuery(query);
processResultSet(resultSet);
statement.close();
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace(); //why is this being hit but only on the web build
}
And the event that is being called:
public List<String[]> getAllEvents(){
queryDatabase("EXEC dbo.sp_GetAllEventDetails");
return events;
}
Thanks.
You have to add the driver of the database on the classpath of Jetty.
Check if it is present or not.
The problem is that either you did not add the driver jar to the classpath of Jetty, or - if you deployed it with the application - you need to load the driver explicitly with Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"). JDBC automatic driver loading only works when the driver is on the initial classpath, not if it is on a context classpath.
However, it is generally inadvisable to use DriverManager directly from a web application. The use of a DataSource is usually better, especially if the data source implementation provides a connection pool.
This code isn't providing the connection to my local database. There is no error after executing the code below. Connecting with JDBC using DriverManager:
package first;
import java.sql.Connection;
import java.sql.DriverManager;
public class Demo {
public static void main(String[] args){
Connection con=null;
try{
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","XXXXXXXX");
if(con!=null)
{
System.out.println("connected successfully");
}
}
catch(Exception e)
{
System.out.println("not connected to database");``
}
}
}
When troubleshooting a connection string one of the first steps is to try to connect using another tool that allows a nice user interface for providing the connection information. In this case you could MySql Workbench which comes with the community edition of MySql. Once you have a solid connection using the tool you can then copy the connection string it uses to your code. This will help eliminate the connection string errors in your code.
In addition as #Elliot Frisch suggested outputting the stacktrace should give you some good information to help troubleshoot your connection string, as well.
I am trying to upload some data to a MySQL database using Java, as I'm working on an Android app. So far, this code compiles and runs, but is uploading nothing to my database. I assume because I'm not accessing the database "streakly" anywhere, but when I've searched around for a way to solve this I haven't found anything.
Snippet of code I'm trying to upload
String addStreakName = chooseName.getText().toString();
String addCategory = prefs.getString("Category", "");
String addToday = new SimpleDateFormat("dd-MM-yyyy").format(new Date());
if(prefs.getInt("todayOrChosen", 1) == 1){
int addStartedZero = 0;
streakList.add(new Streak(addStreakName, addCategory, addToday, addStartedZero));
try {
Connection con = DriverManager.getConnection("127.0.0.1", "[myusername]", "[mypassword]");
Statement st = con.createStatement();
st.executeUpdate("INSERT INTO `users`(userId, addStreakName,addCategory,addToday,addStartedZero) VALUE ('"+addStreakName+"', '"+addCategory+"', '"+addToday+"', '"+addStartedZero+"', '"+userID+"')");
} catch (SQLException e) {
e.printStackTrace();
}
}
You are trying to connect to localhost, which in your case is the android device. I am pretty sure there's no MySQL server running on your device, thus the problem you see. You can probably connect to a MySQL server using JDBC driver, but I really wouldn't recommend it. Mobile apps live on users devices, and having direct access to your database server is not such a good idea. If you need a local database, you can use SQLite, Couchbase Lite, Firebase, Realm, etc. If you want to then synchronize with a server, you can either implement an application server and sync via REST for example, or use a solution like Couchbase Lite+Sync Gateway or Google's Firebase
Regards,
Vladimir