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.
Related
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.
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.
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.
I am using Eclipse and tomcat 7. I have little experience with either product and for that matter Java itself. I was trying to connect to a derby database from a Servlet. Initially, all I had in my doGet() is the following:
conn = DriverManager.getConnection(connectionURL);
I have connectionURL defined as
static private String connectionURL = "jdbc:derby://localhost:1527/seconddb";
Then I added the following to the Build Path and Deployment Assembly.
C:\DERBY\db-derby-10.10.1.1-bin\lib\derbyclient.jar
That is all I did. I sort of assumed that Tomcat will find the driver class and load it. I got the following error
java.sql.SQLException: No suitable driver found for jdbc:derby://localhost:1527/seconddb
Then I went on to add the following code in doGet() to load the driver class:
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
Now it worked. I thought that after Java 1.4 there was no need to explicitly load JDBC driver class. So what am I doing wrong here? I have given the entire code below.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Connection conn = null;
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
try {
conn = DriverManager.getConnection(connectionURL);
//DriverManager.getConnection("jdbc:derby://localhost:1527/testdb;create=true");
}
catch (SQLException e) {
e.printStackTrace();
}
PrintWriter p = response.getWriter ();
p.println("Connected to database");
try {
if (conn != null) {
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
I am using java 1.7
I cannot really explain why, but here is how I do :
if the driver is located in the war, I must call Class.forName("...Driver"); in in initialization method somewhere in the web application.
if the driver is located in Tomcat libraries, it is automacally loaded when I need it.
I know it's more a rule of thumb than a clear explaination, but my knowledge in class loading does not allow me to a better answer ...
Your Derby driver doesn't support the JDBC 4 auto-loading, so you have to do it manually. Try to find a more up to date version.
I could be wrong here but in your second code sample connectionURL
static private String connectionURL = "jdbc:derby://localhost:1527/seconddb";
doesn't include "create=true"; to complete the statement. In your full code sample it's included, but commented out.
While the build paths are not correct I obtain “com.microsoft.sqlserver.jdbc.SQLServerDriver” from the stack trace. As they are built correctly, I obtain my printed statement “Successfully connected”. The JDBC is living within the getter/setters of the webservice as a method.
When I place the JDBC content in its own file with no builds and run as a java application I receive: “com.microsoft.sqlserver.jdbc.SQLServerDriver”
When I place the JDBC content in its own file with builds and run as a java application I receive: “Successfully connected”
When the method is called from a test file as a java application I receive: “Successfully connected”
Ex:
public static void main(String[] args) {
insert.main(args);
When the method is run as a java application on PO I receive: “Successfully connected”
When I place the method to be called under a setter (which will be invoked by the client, which will cause the jdbc to be invoked) I receive: “com.microsoft.sqlserver.jdbc.SQLServerDriver”
Would you happen to have any tips for me? I’m clueless why it will work under being invoked as an application but not via client?
public class insert{
public static void main(String[] args) {
Connection con = null;
Statement st = null;
final String DB_URL = "jdbc:jtds:sqlserver://00.00.00.00:0000/DB";
// Database credentials
final String USER = "usrname";
final String PASS = "pw";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(DB_URL, USER, PASS);
st = con.createStatement();
System.out.println("successfully connected!");
} catch (Exception err) {
System.out.println(" " + err.getMessage ());
}
finally {
try {
con.close();
} catch (Exception e) { /* ignored */ }
try {
st.close();
} catch (Exception e) {
/* ignored */
}
}
}
}
Any tips at this point would be greatly appreciated.
The problem is that your jar misses the necessary libraries that provides com.microsoft.sqlserver.jdbc.SQLServerDriver class and others to communicate with your SQL server. You have to make sure the library is loaded and available when is being executed from tomcat. Just copy your library and drop it inside %TOMCAT_INSTALL%/lib folder, where %TOMCAT_INSTALL% is the folder where your tomcat is installed, so the library will be available for every project (war, jar, etc) that runs in your tomcat installation.