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.
Related
We are running glassfish 4 for our java web application and are running into an issue with timers. Normal servlet calls are able to enjoy as many different connections as they want, which makes integrations much easier. Once we add timers however, the datasources need to be "XA" datasources instead. We set one up as such below:
public XADataSource getNewConnection() {
Encapsulations encap = new Encapsulations();
XADataSource ds = null;
try {
Context ctx = new InitialContext();
if(!encap.getDataSource().equals("Production")){
ds = (XADataSource) ctx.lookup("jdbc/XA_TEST");
}else{
ds = (XADataSource) ctx.lookup("jdbc/XA");
}
} catch (Exception e) {
CatchException.logException(null, e);
String error = e.toString();
}
return ds;
}
The problem is that when the ds = (XADataSource) ctx.lookup("jdbc/XA_TEST") line runs we get this error:
java.lang.ClassCastException: com.sun.gjc.spi.jdbc40.DataSource40 cannot be cast to javax.sql.XADataSource
We use the sqljdbc42 jar for our normal connections, so it is a bit strange to see 40 in there. Anyone know what the problem is? The datasource we are using was set up as an XADataSource, other than downloading a different jar I don't know what is missing.
It's been a while since I don't use Glassfish, but as far as I remember you should install the jar for your database provider that has the implementation of XADataSource interface. In MS SQL Server I've used the jTDS driver.
Another thing to consider from your code snippet is that you should have different configurations of glassfish for development and production, you should leave that kind of things to the application server and not inside your code. Glassfish is a full JavaEE Application Server, it has all the benefits including database connection pooling.
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.
I have been given a task to write a script in java, to connect oracle database from an app server. Scheduling tool will be used to schedule the job every 10 minutes.
If connection exists, the script will do nothing and just disconnect it. (and will be run again after 10 minutes).
If cannot connect after 10 secs, the program will send an email notification.
The whole thing is to ensure connection can be established between the app server and the oracle db.
Really have no clue on this. Could you please advise what are the steps to do this and what Java APIs I'll need??
Many many thanks in advance!
You will need classes out of the java.sql package. Assuming Java 7+.
import java.sql.*;
public class Test {
public static void main(String[] args) {
String url = "..."; // Specify according to JDBC driver in use
String sql = "SELECT 1 FROM DUAL"; // Test statement. Change depending on SQL vendor
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {/*Nothing to do*/}
} catch (SQLException e) {
// Send email here
}
}
}
If you are using J2EE App Server, create a database connection pool there which your application is also going to use.
One of the parameters of the database pool can be to verify the connection at regular intervals by sending simple SQL. Then your task boils down just to monitor the logs to see if database connection pool throws any errors when polling.
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");
I have create a getDBConnection method in my Java application. This returns a connection object, and hence I haven't closed this connection in this method itself.
Now, I am invoking this method from various methods in my application at regular intervals, and closing them inside a try - finally block. I thought this should free up the connection after use. However, I am seeing a large number of connections opened (about 50) in the MySQL Administrator's Server Connections tab.
//Defining a method to retrieve a database connection
// PropDemo is a properties class that retrieves Database related values from a file
public Connection getDBConnection() {
//Instantiating the Properties object
PropDemo prop = new PropDemo();
Connection con = null;
// Retrieving values from the parameters.properties file
String JdbcDriver = prop.getMessage("JdbcDriver");
String JdbcUrlPrefix = prop.getMessage("JdbcUrlPrefix");
String DBIP = prop.getMessage("DBIP");
String DBName = prop.getMessage("DBName");
String DBUser = prop.getMessage("DBUser");
String DBPassword = prop.getMessage("DBPassword");
try {
// Loading and instantiating the JDBC MySQL connector driver class
Class.forName(JdbcDriver).newInstance();
con = DriverManager.getConnection(JdbcUrlPrefix + DBIP + "/" + DBName, DBUser, DBPassword);
if (con.isClosed())
Logger.log("Connection cannot be established", "vm");
} catch (Exception e) {
Logger.log("Exception: " + e, "vm");
Logger.log(Logger.stack2string(e), "vm");
}
return con;
}
I am also closing the associated ResultSet and Statement Objects. What could be missing here?
I am planning to replace all the Statements with PreparedStatements for efficiency and security reasons. Will that help significantly? What else can be done?
EDIT:
This is just a core java application that is repeatedly quering for changes in some fields in a MySQL database through MySQL-JDBC connector. I am not using any framework like Spring or Hibernate.
Your code looks sane.
That's how you're creating a new connection.
Probably the error is where you close it.
You should close it in a finally block.
Some additional questions.
1) Are you sure those 50 conections come from this program ? Maybe there are some others comming from your same office. To confirm this you would need to stop the program, and look again in your connection monitor.
2) Does your application uses many connection simultaneously? Probably its a peak when you're using 50 at the same time.
If you can post the code where you close the connection. Chances are the problem is there.
Additionally I would suggest you to use a connection pool. You can build one your self or you can see the results from this page:
How many JDBC connections in Java?
Are you closing the connection object when you application closes as well?
Are you using your JDBC connection within a J2EE application server or with Hibernate?
Both of these tend to start out with a fairly high connection pool to begin with, so you would see a large number.
Check out the details on connection pooling.
You could take a Singleton approach to the problem and only create a new Connection object if the current one is null:
If (connectionObject != null){
return connectionObject;
}else {
//create new connection object
}
This will make sure that you only have one non-null connection at any time.