Creating a sqlite-file within appengine - java

Im struggeling with the gae filesystem restrictions.
I am creating a tool that can export a datastructur into a lot of different output-files (json, xml...)
One of them is a sqlite-database-file.
Do you have any ideas how this can be done in this restricted environment?
I tried creating an inmemory database without success:
DriverManager.getConnection("jdbc:sqlite::memory:");
I also tried to use the file-storage bucket:
DriverManager.getConnection("jdbc:sqlite:gs://"+bucketnameü+"/sqllite");
Neither of them worked. I'm afraid this is not possible at all :( I dont want to start a compute engine instance in order to create a sqllite file.
Are there any other frameworks out there that could possible create that database file on the fly.
Here the whole code:
Connection c = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:gs://"+bucketnameü+"/sqllite");
Statement statement = c.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("create table person (id integer, name string)");
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
e.printStackTrace(System.out);
}
I already found an interesting approach in Google AppEngine: Use SQLite file uploaded by user
I tried SQLJet with an inmemory database without success. gaevfs does not look like a good idea either.

If you still need to access the file system you can create a Managed VMs which let you avoid much of App Engine's limitations, particularly the access to the file system.

Related

Java sqlite error (error or missing database) no such table

This is the class where I connect sqlite
public static Connection ConnectDB() {
try {
Class.forName("org.sqlite.JDBC");
Connection con= DriverManager.getConnection("jdbc:sqlite:C:\\Users\\abh\\eclipse-workspace \\Training\\Database.db");
return con;
}
catch (Exception e) {
JOptionPane.showMessageDialog(null,e);
return null;
}
}
The jar file inside the project folder name is sqlite-jdbc-3.7.2 I'm confused whether it's because of the version or if it's from my database created in sqlite
SQLite is a pretty good database platform, I highly doubt it's the problem as is the JDBC version your using as well.
The Connection method you presented does indeed work but you need to keep in mind that the connection has nothing to do with tables. It has everything to towards a connection to a particular SQLite database file and if the path doesn't exist to get to the database file specified, then it simply can not find that database. If the path does exist, and local system permissions allow it, and the database file does not exist, then the connection call will automatically create the database file specified but it will be empty. Never the less, the connection is now made and ready for a database Table to be either Created or Accessed via a query (providing there is actual data in the table).
If there was an error regards to the connection then you would receive a Message Box on the screen, and if you do then it's probably because of the whitespace that exists in the specified database path between eclipse-workspace and \\Training:
"jdbc:sqlite:C:\\Users\\abh\\eclipse-workspace \\Training\\Database.db"
Edit: Oh...as already specified by #lazylead :)
On a side: It's not a good idea to hard-code the path to your database file. This will never be the path when the application is run in the real world.

Connect SymmetricDS to an Existing H2 Databse File

I've a H2 database file which I need to replicate using SymmetricDS.
I can access the database from web console in embedded mode using this url:
jdbc:h2:file:E:/Folder/database;AUTO_SERVER=TRUE;IFEXISTS=TRUE;
But using the same url in node properties file of symmtericds throws following error:
ERROR [server-000] [AbstractSymmetricEngine] [symmetric-engine-startup-0] Could not get a connection to the database: Cannot create PoolableConnectionFactory (IO Exception: "E:/Folder/database outside D:/symmetric-server-3.7.26/tmp/h2" [90028-182]). Waiting for 10 seconds before trying to connect to the database again.
Though if the following url is used in the node properties file of symmetricds, everything works fine but the database is created in symmetric-server-3.7.26/tmp/h2 directory.
jdbc:h2:file:database;AUTO_SERVER=TRUE;
I've not had any luck in solving this issue in past couple of days.
Any kind of help will be greatly appreciated.
Going through H2 documentation I found out that the this behaviour is due to -baseDir option: http://www.h2database.com/html/advanced.html#remote_access .
But how is this option being set automatically and how to disable it..?
Doing some extensive research on the issue, root cause turns out to be the static block of AbstractCommandLauncher class of SymmetricDS:
static {
String symHome = System.getenv("SYM_HOME");
if (symHome == null) {
symHome = ".";
}
System.setProperty("log4j.sym.home", symHome);
if (isBlank(System.getProperty("h2.baseDir"))) {
System.setProperty("h2.baseDir", symHome + "/tmp/h2");
}
DEFAULT_SERVER_PROPERTIES = System.getProperty(SystemConstants.SYSPROP_SERVER_PROPERTIES_PATH, symHome + "/conf/symmetric-server.properties");
log = LoggerFactory.getLogger(AbstractCommandLauncher.class);
initFromServerProperties();
}
And as it turns out, source code of SymmetricDS will have to be modified to resolve it.
This behaviour can not be disabled altogether but overriding it is possible by setting -Dh2.baseDir while running SymmetricDS. The original answer is here

How do you access RDS databases from AWS

I'm looking at the AWS API and I can't seem to find a method to help me get info on an existing RDS database. I also tried to use a method that gets a list of all the RDS databases but failed at that too.
I looked at 2 methods and apparently they aren't what I'm looking for or I'm using them wrong.
Method 1:
I looked at ModifyDBInstanceRequest, to see if I could specify the name of an existing database and if I could query it for its properties (mysql version, storage size, etc.)
The following piece of code didn't do as I expected. ad-dash-test is an existing db in RDS. When I ran my code, it said the engine version is null, even though this is an existing db and I specified it by its DB Instance name.
ModifyDBInstanceRequest blah = new ModifyDBInstanceRequest("ad-dash-test");
System.out.println("the engine ver is " + blah.getEngineVersion());
Method 2:
I tried using the DescribeDBInstancesResult method but it looks like it's used for newly created RDS databases, not existing ones.
DescribeDBInstancesResult db = new DescribeDBInstancesResult();
List<DBInstance> list = db.getDBInstances();
System.out.println("list length = " + list.size());
The list length that returns is 0 and I have 8 RDS instances.
I didn't find any examples in Amazon's SDK for RDS and using my logic and the API docs didn't seem to help. Hopefully someone can point me in the right direction. Thanks in advance for your help.
In both of your methods, you are just building a Request object, and you are never sending the request to AWS.
Try the following in your second example:
// Instantiating rdsClient directly is deprecated, use AmazonRDSClientBuilder.
// AmazonRDSClient rdsClient = new AmazonRDSClient(/*add your credentials and the proper constructor overload*/);
AmazonRDS rdsClient = AmazonRDSClientBuilder.defaultClient();
DescribeDBInstancesRequest request = new DescribeDBInstancesRequest();
DescribeDBInstancesResult result = rdsClient.describeDBInstances(request);
List<DBInstance> list = result.getDBInstances();
System.out.println("list length = " + list.size());
An example for method 1 (for modifying your instance(s)) should be similar.

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).

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.

Categories