How to check if another instance of Derby is already booted? - java

I'm writing some Java application that uses Java DB (i.e. Apache Derby) as database. I use the following method to connect to database:
Connection getConnection() throws SQLException {
EmbeddedDataSource ds = new EmbeddedDataSource();
ds.setDatabaseName(dbUri);
ds.setPassword(password);
ds.setUser(username);
Connection conn = ds.getConnection();
conn.setSchema(schema);
return conn;
}
This works ok, but sometimes I get the following exception:
java.sql.SQLException: Another instance of Derby may have already booted the database
This happens when I run my application and at the same time SQuirreL SQL Client is connected to my database. So everything works as expected, but I would like to be able to check for this in my getConnection() method. I other words, I would like to check if any sessions are opened to my database, and for example, close them, throw my own exception or display error dialog box. I don't know how to do this.
Thx

Rather than declaring that your application "throws SQLException", you can use a "try" block to catch the SQLException, then examine the exception and decide if it is the "Another instance of Derby" exception or not.
Then, you can throw your own exception from your "getConnection" method accordingly.

I modified my getConnection() method to something like below. It does what i want:
Connection getConnection() throws SQLException, DAOConnection {
EmbeddedDataSource ds = new EmbeddedDataSource();
ds.setDatabaseName(dbUri);
ds.setPassword(password);
ds.setUser(username);
Connection conn = null;
try {
conn = ds.getConnection();
} catch (SQLException e) {
// check if cannot connect due to "Another instance of
// Derby may have already booted the database".
// The error code of this exception is 45000.
if (e.getNextException().getErrorCode() == 45000) {
throw new DAOConnection(e.getNextException().getMessage());
}
throw new SQLException(e);
}
conn.setSchema(schema);
return conn;
}

Prevention is better than cure. IMO, catching exception and then realizing it was duplicate Derby server started is not an ideal design. Better would be to prevent duplicate instantiation. If possible you can synchronize your getConnection() method or make it part of a singleton class or load the embedded Derby driver from static initializer block of a startup/main class which is loaded only once by JVM and hence Derby will be started only once. Something like following in the main/startup class should do the trick:
static {
try {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
}
catch(Exception e){
.....
}
}
Per the link here http://db.apache.org/derby/docs/10.3/devguide/tdevdvlp38381.html loading the Driver should start the Derby embedded system.

Related

How to avoid inactive sessions using wso2 connection pool on oracle?

I have a small set of custom WSO2 ESB mediators which use an oracle database to which I'm connecting via WSO2 Data Source like this:
private void Connect(boolean isRetry) throws SQLException {
DataSource ds = null;
try {
Hashtable environment = new Hashtable();
environment.put("java.naming.factory.initial", "org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory");
Context initContext = new InitialContext(environment);
ds = (DataSource)initContext.lookup("jndi/kernel");
} catch (NamingException e) {
throw new SQLException("Connection pool exception", e);
}
// Nawiazanie polaczenia
this.connection = ds.getConnection();
this.connection.setAutoCommit(false);
}
After using the connection I'm closing it like this:
public void Close() throws SQLException {
try {
if (this.connection != null) {
this.connection.close();
this.connection = null;
}
} catch (SQLException e) {
System.out.println(" ## Failed to close the connection!");
e.printStackTrace();
throw e;
}
}
Every custom mediator is using the above Connect method on the begining and Close method in the finally scope at the end.
In a single sequence (executed by a message processor) there are at least 2 custom mediators called, sometimes even 5.
The problem is that when there are a lot of messages passing through the queue there are hundreds of inactive session on the database (oracle). It looks like the Connect method doesn't try to get an inactive connection and use it and I thought that this is the whole point of having a connection pool.
Any help will be much appreciated..
I currently have a custom mediator that needs to get a connection on oracle db.
I don't have this problem of inactive sessions although this mediator is used in a sequence executed by a message processor (processing thousands of messages)
Don't know exactly what is wrong in your case but I hope this can help you :
the datasource is defined in WSO2 ESB with the web console.
The Driver used is oracle.jdbc.OracleDriver
A validation query is defined (select 1 from dual)
test on borrow is set to true
max active is a positive number
remove abandoned is set to true
and of course, the data source is exposed as a JNDI Data Source
In the java part, I don't use directly InitialContext to made a lookup : I use org.apache.synapse.commons.datasource.DataSourceFinder.find(dataSourceName, jndiProperties) where jndiProperties is just a new Properties()
In the finally, I just need to close resultset, statement and connection
It works well with ESB 4.8.1 and ESB 5
The problem was that I had "test on idle" set to true. After turning it off everything is fine now.

JDBC connection to derby in java method

I'm trying to create a simple java method to create a connection to a Derby db created in Netbeans. The db was named group1 with user/pass of group1/group1. The database is connected when I look at the services tab. I am calling this method from a jsp and i am getting the exception handled message instead of actually creating a connection. Below is my method... right now it returns a success or fail message, but will later be used within other methods to create the connection prior to executing queries or updates. I have imported "java.sql.*" to handle the connection and other sqly things and my connection "conn" is defined earlier in the java class. Any advice as to why would be so greatly appreciated.
public static String createConnection(){
String result;
try{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
conn = DriverManager.getConnection("jdbc:derby://localhost:1527/group1","group1","group1");
result="connection successful";
} catch (Exception noConnection) {
System.err.println("Connection Failed!");
result="connection failed";
} // end connection try-catch
return result;
} // end createConnection method
Maybe your driver class isn't the most suitable here, give a try to this one instead :
org.apache.derby.jdbc.ClientDriver
you are using a different driver class
Use client driver instead
Configuration error. Class [org.apache.derby.jdbc.EmbeddedDriver] not found while connecting to DB
Connection con= <ClassName>.createConnection();
Try this code in your main method hope it will run.
If not then check that either you have configured derby jar file in your library or not.

Working with Java & SQL

I have been playing around with JDBC drivers. I would like some advice from the experience code masters out there. I was wondering if this is a good way to find if am connected to a database. If it is not, could someone let me know how would they do it?
Connection con = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/"+database+"?+user="+user+"&password="+password);
} catch (SQLException e) {
System.out.println(e.getMessage());
if (con != null) {
System.out.println("hello");
} else {
System.out.println("Not Connected!");
}
}
I would really appreciate all helpful comments. Many thanks in advance.
If the getConnection method returns normally, and does not throw an exception, then a connection to the database has been made. The logic within the catch clause is unrequired, because if an exception is caught a connection was not established.
The returned Connection object must be close()d (as many of the JDBC classes must, such as Statements and ResultSets for example). Assuming Java7, a convenient way to ensure the Connection is closed is using the try-with-resources statement:
try (Connection con = DriverManager.getConnection(...))
{
}
catch (final SQLException e)
{
}
As stated by SnakeDoc in the comments this may be impractical in production systems because establishing a connection to the database is a typically expensive operation.
The JDBC API will perform these checks for you. Whenever you perform a database operation, such as opening a connection, executing a statement, it will check to see if the connection is valid. If not it will throw an exception.
For example, the method Connection.createStatement throws the following:
SQLException - if a database access error occurs or this method is called on a closed connection
All you have to do is some basic exception handling. Surrounding your JDBC calls with try-catch blocks is one way do this. You could also throw the exception and handle it somewhere else.
That's definitely a good way of doing it! If conn can't be initialised it's either your connection string that is wrong or the database is down.

sharing a JDBC Connection object between other objects

I have created a Database class which uses a static connection object in order to be used in common between instances of itself. my question is that is there any problem with this approach or not?
class Database {
private static Connection connection = null;
public Database() {
if(connection == null){
...
connection = DriverManager.getConnection(...);
...
}
}
}
If you are going to have many (hundreds) of queries per second then implementing a connection pool is the way to go. See the answer to this question for more details. However, if you a Java novice (we all were one day!) then I don't imagine you will be needing this requirement, and probably will struggle to implement it.
Instead, the simple pattern of creating a new connection if required, and then closing it when finished will be the best way to go forward for you. Below is a modified version of your Database class which I think is a good way to move forward.
class Database {
private Connection con = null;
private final String connectionString;
public Database(String connectionString) {
this.connectionString = connectionString;
}
public void connect() throws SQLException {
if (con != null // if the connection exists
&& !con.isClosed() // and has not been closed
&& con.isValid(0)) { // and appears to be functioning (with a test timeout of 0ms)
return; // skip connection creation
}
// create the connection
con = DriverManager.getConnection(connectionString);
}
public void testFunction() {
try {
connect();
// .. do some stuff with the connection ..
} catch (Exception e) {
// log or otherwise deal with the error
} finally {
try {
con.close();
} catch (Exception e) {
System.err.println("Failed to close connection: " + e.toString());
}
}
}
}
Some things to note about this solution:
It is not very efficient - creating a new connection always takes more time than using an existing one
This class if not thread safe - if you need this requirement, I recommend using a thread pool. However, if you create a new instance of this class per thread then it will be thread safe (as there is not static connection to worry about!)
It does do the job - certainly for simple cases. I use the model for a relatively low volume database which has approx 50-100 connections made/closed per minute and it does not add a noticeable lag
It is very robust - nothing is safer than opening and closing a connection per query. You are guaranteed to be able to handle a connection failure per query, and the connection will always be closed (unless it already has been).
Disclaimer The solution above is not a particularly amazing solution. However, I believe it is simple to implement and a good way for a Java novice to get to know the ropes before jumping into external libraries.
There is nothing wrong with creating an object to manage your connections, however, connections should be opened and closed and can be used in multi-threaded environments, so having a static connection is not a good idea. For a method that needs a connection, get a connection use it, close it. Even if you are not using it in a multi-threaded environment, the connection can time-out, then you need to constantly check if the connection is up and available, instead of just saying, get me a connection, use the connection, close it.

How to connect MySQL to Java program

I ve installed MySQL (last update).
I need to code, that ll create & establish a connection with SQL DB
& manage the DB(using SELECT, INSERT, CREATE).
I did everything but, I am not able to create connection. I've also installed the MySQL/J connector, I just extracted the .zip pack in a folder & added the folder path in Variables).
Can anyone tell me wat is meant by URL in the below line?
Connection connection = DriverManager.getConnection(url, username, password);
I ve tried this:
String url = "jdbc:odbc:sqlserver://localhost:3306/myfirstdb";
Connection con = DriverManager.getConnection(url, "root", "1234");
But it's not working. I am unable able to understand the term 'URL'.
Can anyone explain, the meaning of 'url' and wat should be done to connect to a SQL server from Java.
Update:
This is the Full code. It still cannot connect.
import java.sql.*;
public class TestDriver {
public static void main(String[] args) {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//This s wat actually i did for connection
System.out.println("Driver Loaded Succesfully");
}
catch (Exception e){
System.out.println("Unable to Load Driver!!!");
}
try {
Class.forName(com.mysql.jdbc.Driver"); // initialise the driver
String url ="jdbc:mysql://localhost:3306/myfirstdb";
Connection con = DriverManager.getConnection(url, "root", "1234");
System.out.println("connection Established");
}
catch(Exception e) {
System.out.println("Couldnt get connection");
}
}
}
Can you tell me wat is the purpose of MySQL Connector/J?
In the question you seem to be using a MySQL jdbc driver with a SQL Server jdbc URL. This won't work.
If you are using a MySQL database:
Class.forName("com.mysql.jdbc.Driver"); // initialise the driver
String url ="jdbc:mysql://localhost:3306/myfirstdb";
If you are using a SQL Server database you are going to need a completely different jdbc driver. jTDS is open source and a good option. Include the jtds.jar file in your classpath and use something like:
Class.forName("net.sourceforge.jtds.jdbc.Driver"); // initialise the driver
String url = "jdbc:jtds:sqlserver://localhost:1433/myfirstdb";
Here's an extract from your code:
} catch (Exception e) {
System.out.println("Couldnt get connection");
}
You should never suppress exceptions as long as you don't understand its cause. Replace it by at least:
} catch (Exception e) {
System.out.println("Could not get connection");
e.printStackTrace();
}
Or maybe
} catch (Exception e) {
throw new RuntimeException("Could not get connection", e);
}
Either way, you should see the exception type, message and trace. In your code snippet the possible exceptions are ClassNotFoundException and SQLException. The first one would mean that the driver is not properly placed in the classpath. The second one would mean that connection cannot be obtained. The exception message and/or trace should tell in detail about the underlying root cause of the problem.
You should always observe exceptions. They tell something about the cause of the problem. You know, once a cause is understood, the solution is nothing more than obvious :)
See also:
Short MySQL/JDBC tutorial - Contains explanation about exception causes.
Further,
Can anyone tell me wat is meant by URL in the below line?
An URL is an Uniform Resource Locator. It's a common way to locate (identify) unique resources in computer systems and networks. The URL syntax for the MySQL database is explained in the documentation of the JDBC driver.
Can you tell me wat is the purpose of MySQL Connector/J?
It's the JDBC driver. The JDBC API exist of almost only interfaces. The DB vendors should provide their own concrete JDBC API implementation, which is the JDBC driver. With a JDBC driver you'll be able to connect a specific database using JDBC API.
If its MS SQL Server,
String driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
Class.forName(driver);
String url = "jdbc:microsoft:sqlserver://host:1433/database";
Connection conn = DriverManager.getConnection(url, "username", "password");
For more info, see this to get started with Microsoft JDBC.
You can use any of the two JDBC drivers for MSSQL:
Microsoft SQL Server JDBC Driver
2.0
jTDS
For MS SQL Server driver 2.0, use
URL: jdbc:sqlserver://server:port; DatabaseName=dbname
Class name: com.microsoft.sqlserver.jdbc.SQLServerDriver
For MySql & Java, see this on SO.
You forgot a " at Class.forName(com.mysql.jdbc.Driver");
It should be
Class.forName("com.mysql.jdbc.Driver");

Categories