connecting to a database through JDBC [duplicate] - java

This question already has answers here:
Connect Java to a MySQL database
(14 answers)
Closed 7 years ago.
I am trying to follow a tutorial in a book on connecting a program to a database with JDBC. I am confused on what the first block of code is doing in the class. whan i run the code i get an error saying that java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:8889/book_store
and the code is throwing an exception in that first block inside the class. do i need to add some sort of dependency or library to the project?
as you can tell this is my first attempt at using a db...
package com.apress.books.dao;
import com.apress.books.model.Author;
import com.apress.books.model.Book;
import com.apress.books.model.Category;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BookDAOImpl implements BookDAO {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException ex) {
}
}
private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:8889/book_store",
"root", "password");
}
private void closeConnection(Connection connection) {
if (connection == null)
return; try {
connection.close();
} catch (SQLException ex) {
}
}
#Override
public void insert(Book book) {
}
#Override
public void update(Book book) {
}
#Override
public void delete(Long bookId) {
}
}

In essence this is a ClassNotFoundException. Your first catch clause is empty and thus, although the exception is being caught, you are not acting upon it. In the least, I would do something like this:
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException ex) {
throw ex;
}
}
This would help you to see better what is causing your troubles.
Moving on to a solution:
If you are using Maven, you need to add the following dependency in your pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
And if you want, change the version to any one found here.
Otherwise, you need to download the jar from the same link and include it in your project dependencies.

Related

Deployment of Azure Function in Visual Studio Code does not include .jar file

An Azure Function that I am building needs to be able to execute a procedure in an Azure SQL Server Database.
I have working Java code in Eclipse (based on #duffmo's answer in Java DB connection)
I then ported the code to an Azure Function in Visual Studio Code, for deployment to Azure. (Note I have removed security code etc.) I created the project using View/Command Palette/Azure Functions - Create New Project
package com.function;
import java.sql.*;
import java.util.*;
import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
/**
* Azure Functions with HTTP Trigger.
*/
public class Function {
/**
* This function listens at endpoint "/api/HttpTrigger-Java". Two ways to invoke
* it using "curl" command in bash: 1. curl -d "HTTP Body" {your
* host}/api/HttpTrigger-Java&code={your function key} 2. curl "{your
* host}/api/HttpTrigger-Java?name=HTTP%20Query&code={your function key}"
* Function Key is not needed when running locally, it is used to invoke
* function deployed to Azure. More details:
* https://aka.ms/functions_authorization_keys
*/
private static final String DEFAULT_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static final String DEFAULT_URL = "jdbc:sqlserver://myserver.database.windows.net:1433;database=mydb;loginTimeout=10;user=myuser#myserver;password=mypassword;";
#FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(#HttpTrigger(name = "req", methods = { HttpMethod.GET,
HttpMethod.POST }, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
Connection connection = null;
try {
connection = createConnection(DEFAULT_DRIVER, DEFAULT_URL,context);
connection.setAutoCommit(false);
String sqlUpdate = "{call MYDB.MYPROC(?,?}";
List<Object> parameters = Arrays.asList("Bar", "Foo");
execute(connection, sqlUpdate, parameters);
connection.commit();
} catch (Exception e) {
rollback(connection);
e.printStackTrace();
} finally {
close(connection);
}
return null;
}
public static Connection createConnection(String driver, String url, ExecutionContext context) throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection(url);
}
public static void close(Connection connection) {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement st) {
try {
if (st != null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(Connection connection) {
try {
if (connection != null) {
connection.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static double execute(Connection connection, String sql, List<Object> parameters) throws SQLException {
CallableStatement call = connection.prepareCall(sql);
try {
int i = 0;
for (Object parameter : parameters) {
call.setObject(++i, parameter);
}
call.executeUpdate();
} finally {
close(call);
}
return 0;
}
}
However the line
Class.forName(driver);
causes the following error
java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
I tried to solve this by
Putting the sqljdbc4.jar in a "lib" directory
Manually adding the following to the pom.xml
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
Trying to install the jar from the terminal via
mvn install:install-file -Dfile=’C:=myPath\myFunction\lib\sqljdbc4.jar'
-DgroupId=package -DartifactId=sqljdbc4 -Dversion='4.0' -Dpackaging=jar
experimented with changing the order of 'microsoft' and 'sqlserver' in the DEFAULT_DRIVER string.
Try and add SQLJDBC from the new Java Dependencies view (see #hemangs answer) - but it does not appear in the list
I edited the .classPath as per #asndr's answer in .classpath - note that I did not manage to access the .classPath from within VS Code, but rather via File Explorer - and then ran view/Command Palette/Java: Clean the java language server workspace
Any ideas?
Based on #nirmal's answer in Missing artifact com.microsoft.sqlserver:sqljdbc4:jar:4.0
I did the following:
Explorer/Java Dependencies/Maven Dependencies - then clicked on '+'
Typed in mssql-jdbc and pressed Enter
Selected mssql-jdbc from com.microsoft.sqlserver
This opened the pom.xml within VS Code with the following added
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.3.0.jre14-preview</version>
</dependency>
I changed the version number to 6.1.0.jre8 (the higher version caused compile errors)
Saved
VS Code asked me if I want to 'A build file was modified. Do you want to synchronize the Java classpath/configuration?'
I said yes, and then it worked.
What seems to be crucial is to edit the pom.xml from within VS Code. It seems that when I edited it outside of VS Code, then VS Code did not trigger a synchronization of the configuration.

remotely connecting oracle database with java

I'm trying to figure out how to connect to oracle database remotely, in order to fetch information/data from it. I don't know the steps on how to go about it. I would also like to use datasource to connect with the oracle DB. I'm completely new to this, and if its not too much to ask can I get step by steps on how to do this. I'm using liberty server.
All I have done is read through the internet for something that answers my query but i just cant seem to find what I'm looking for. Below is what I have and I'm trying to see how to achieve my goal from what I have.
In this scenario I want to use datasource and connect remotely with oracle DB.
package com.dBconnect;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DatabaseUtility {
private static DataSource dataSource;
static Connection conn;
public static void main(String ars[]) {
try {
conn = dataSource.getConnection();
System.out.println("connection established");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Your example code is a standalone Java program, although you also tagged the question with websphere-liberty. There are different ways of obtaining a data source from a standalone Java program vs when running in an application server (the latter).
Here is how to achieve it in Liberty.
Edit the server configuration (server.xml) file to enable one of the jdbc features,
<featureManager>
<feature>jdbc-4.2</feature>
<feature>jndi-1.0</feature> <!-- for JNDI lookup of the data source -->
<feature>servlet-4.0</feature> <!-- or other features that you want to use -->
</featureManager>
<dataSource id="myDataSource" jndiName="jdbc/myOracleDataSource">
<jdbcDriver libraryRef="OracleLib"/>
<properties.oracle URL="jdbc:oracle:thin:#//localhost:1521/SAMPLEDB" user="user1" password="password1"/>
</dataSource>
<library id="OracleLib">
<file name="C:/Oracle/lib/ojdbc8.jar"/>
</library>
Refer to example configuration on this knowledge center page for more information on data source configuration.
From a web or ejb component (servlet is used here), use resource injection as follows (this does not require the jndi-1.0 feature),
#WebServlet("/*")
public class ExampleServlet extends javax.servlet.http.HttpServlet {
#Resource(lookup = "jdbc/myOracleDataSource")
private DataSource dataSource;
public void init() throws ServletException {
// Here is another way of accessing the data source - via JNDI lookup.
// This requires the jndi-1.0 feature
DataSource anotherDataSource = InitialContext.doLookup("jdbc/myOracleDataSource");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
conn = dataSource.getConnection();
System.out.println("connection established");
response.getWriter().println("connection established");
} catch (Exception e) {
e.printStackTrace();
response.getWriter().println("failed to establish connection: " + e);
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

JDBC connection not working with PowerMockito

I am trying to use PowerMockito to mock by DBUtil. Unlike typical testcase, I don't want to mock the db calls completely. Whenever Dbutil.getConnection() is called. I want to return the connection object to my local Database.
The simple jdbc connection code below is not working when i call from #BeforeClass method. But it works when I call from the java class.
public static Connection getConnection() throws Exception {
System.out.println("-------- Connecting to " + Constants.CONNECTION_STR + " ------");
try {
Class.forName(Constants.ORACLE_DRIVER_NAME);
}
catch (ClassNotFoundException e) {
throw new Exception("JDBC Driver not found... " + e);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("getConnection :: exp :: "+ e);
}
System.out.println("Oracle JDBC Driver Registered Sucessfully!");
Connection connection = null;
try {
connection = DriverManager.getConnection(Constants.CONNECTION_STR, Constants.USERNAME, Constants.PASSWORD);
}
catch (SQLException e) {
throw new Exception("Connection Failed!",e);
}
if (connection != null) {
System.out.println("Connected to Database Sucessfully, take control your database now!");
return connection;
}
System.out.println("Failed to make connection!");
return null;
}
My Testclass
#RunWith (PowerMockRunner.class)
#PrepareForTest(DbUtil.class)
public class MyUtilTest {
#Mock
private DbUtil dbUtil;
#InjectMocks
private MyUtil myUtil;
private static Connection myDBConn;
#BeforeClass
public static void beforeClass() throws Exception {
myDBConn = OracleJDBCConnetion.getConnection(); // This always throws invalid username/password exception.
}
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testIsAdminUser() throws Throwable{
PowerMockito.mockStatic(DbUtil.class);
PowerMockito.when(DbUtil.getConnection()).thenReturn(myDBConn);
String accId= "TH123" ;
boolean isAdmin = MyUtil.isAdminUser(cloudAccGuid);
System.out.println("isAdmin : " + isAdmin);
//then
PowerMockito.verifyStatic(Mockito.times(1));
DbUtil.getConnection();
assertTrue(isAdmin);
//Finally I am closing my connection.
if(myDBConn!=null && !myDBConn.isClosed())
OracleJDBCConnetion.closeConnection(myDBConn);
}
}
The beforeClass method always throws below expection.
Connection Failed! java.sql.SQLException: ORA-01017: invalid username/password; logon denied
But the same code works, when i try from normal Java class.
Can anyone help in understanding whats wrong here?
I am using ojdbc6.jar and powermokito-1.5.6 and my Oracle database version is 11.2.0.4.0
Thanks.
Edit :
I found that #PrepareForTest annotation is causing the error. without the annotation connection is successful but mock does not work. can anyone help me in understanding what is happening? I am very new to these mocking stuff.
The problem with #PrepareForTest annotation is, it recursively creates stubs for all dependent classes. Since DBUtil class uses java.sql.Connection class , a stub is created for Connection class also.
So, When i try to create connection, it refers to stub class and throws expection.
Add #PowerMockIgnore annotation to the class,to avoid it. #PowerMockIgnore annotation tells the powermock not to create for the classes that falls under the given package.
#RunWith (PowerMockRunner.class)
#PrepareForTest({DbUtil.class})
#PowerMockIgnore({"java.sql.*"})
public class MyUtilTest {
...
}
This worked for me.

Connecting to SQL Express DB: connection refused

I have SQL Express 2012 installed on my local machine. I tried connecing with it, by using JDBC 6.2. I downloaded it and declared the dependency(IntelliJ: CTRL, SHIFT, ALT + S --> "Modules" --> "Add" --> "Jars or directories").
Eventually I adjusted the provided code above to my needs, looking like the following:
For some reason, the imported class is not being used at all(it´s greyed out by IntelliJ) - did I made a mistake in terms of dependencies? I´m fairly new to JAVA: to my understanding, setting up the classpath is equal to setting up the depndencies(?).
Moreover I get the error "connection refused". I checked different login credentials as well as the ports(SQL configuration manager as well as netstate) - they are fine. Both, Windows- and SQL authentication didn´t work.
What am I missing?
package com.company;
import java.sql.*;
import com.microsoft.sqlserver.jdbc.*;
public class Main {
public static void main(String[] args) {
String connectionString = "jdbc:sqlserver://localhost:1433;"
+"database=QMT;"
+"user=superadmin;"
+"password=myPassword.;";
// Declare the JDBC objects.
Connection connection = null;
try {
connection = DriverManager.getConnection(connectionString);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (connection != null) try { connection.close(); } catch(Exception e) {}
}
}
}

Jersey: The mysql java.lang.ClassNotFoundException: com.mysql.jdbc.Driver although inclueded

I am trying to send GET request from the postman chrome plugin and I am getting this error java.lang.ClassNotFoundException: com.mysql.jdbc.Driver I have already included the mysql-connector-java-5.1.35-bin in my project
jersey endpoint:
#Path("/test")
public class Driver{
#GET
#Produces(MediaType.TEXT_PLAIN)
public void mysqltest(){
Database db = new Database();
db.connection();
}
}
Database class:
public class Database {
public void connection() {
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("jar works :) ");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have already tested it with this class in the same project and I am getting the output driver works
Driver class:
public class Driver {
public static void main(String[] args){
connection();
}
public static void connection() {
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("driver works :) ");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Why when am I calling it from the jersey method I am getting the error in the title?
You need to add the following dependency in your pom.xml file. (I assume you are working with Maven project)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
P.S. I was getting the same exception. This worked for me.
Adding to what #LuiggiMendoza wrote, you need to understand the packaging of your artifacts and trace the classloader delegation to understand if the classloader that invokes your Driver class also has access to the MySQL driver JAR. For instance, adding the MySQL JAR to WEB-INF/lib may not help if Jersey is a dependency of an EJB JAR that itself is in the WEB-INF/lib of the webapp.

Categories