IntelliJ cannot find MySQL JDBC driver - mysql

I have added MySQL JDBC driver but I keep getting the following error: No suitable driver found for jdbc.
Here's the code that I'm trying:
public class Test extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp1", "root", "");
System.out.println("Connected successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here are the project settings.
As soon as I add MySQL jar, one following problem appears:
I have tried all of the three options above, but I keep getting the same error.

Related

mocking database connection by using mockito

public List<Prisma> getProductCharacteristics(ResultSetLoadHandler<Prisma> rsLoadHandler, SqlSession sqlSession) throws Exception {
List<Prisma> ptos = null;
try {
sqlSession.select("Product.getProductInformation", params, rsLoadHandler);
ptos = rsLoadHandler.getResults();
} catch (Exception e) {
throw e;
}
return ptos;
}
I am trying to mock the select method
Mockito.doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return rsLoadHandler;
}
}).when(sqlSession).select(rsLoadHandler, sqlSession);
but not able to mock sqlSession.select(String statement, Object parameter, ResultHandler handler); in mockito framework.
Getting this issue:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not
get JDBC Connection; nested exception is
org.apache.commons.dbcp.SQLNestedException: Cannot create
PoolableConnectionFactory (ORA-28000: the account is locked )
I am using ibatis database, I need to mock the db calls
I should not hit the database and return the list size to be greater than zero.

How to troubleshoot problems when tomcat servlet connects to mysql

Tomcat servlet gets connection to mysql with getConnection(). Just fetch data from db test table shop.Connection to mysql is successful, but browser doesn't still show any data from backend. JavaScript shows request.status is 200 and request.readyState is 2 or 3. How can I find the problem? I even don't see any exceptions in tomcat log file.
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("ok");
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "***");
Statement statementQuery = connection.createStatement();
ResultSet set = statementQuery.executeQuery("select * from shop");
// connection.commit(); Error appears here(should be commented):
out.println("<div>");
while (set.next()) {
out.println("ok");
out.println(set.getInt(1) + " ");
out.println(set.getString(2) + " ");
out.println(set.getDouble(3));
}
} catch (Exception e) {
e.printStackTrace();
}
out.println("</div>");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
EDIT:
connection.commit() is wrong. Comment that line and it works.
Change Oracle driver to Mysql driver
Class.forName("com.mysql.jdbc.Driver");
SQL statements are executed sequentially. Change the order of execution to:
int ret = statement.executeUpdate("insert into shop values (53, 'fjd', 43.2)");
ResultSet s1 = statement.executeQuery("select * from shop");
Execute also a commit on the connection
connection.commit();
And add a finally to close statement and connection
}finally{
statement.close();
connection.close();
}

MySQL connection pooling with JERSEY

I'm developping a RESTful API with Jersey and MySQL.
I'm actually using the JDBC driver to connect to the database and I create a new connection everytime I want to acess it. As it clearly is a memory leakage, I started to implement the ServletContextClassclass but I don't know how to call the method when I need to get the result of a SQL query.
Here is how I did it wrong:
DbConnection.java
public class DbConnection {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
}
catch (SQLException e) {
throw e;
}
}
}
DbData.java
public ArrayList<Product> getAllProducts(Connection connection) throws Exception {
ArrayList<Product> productList = new ArrayList<Product>();
try {
PreparedStatement ps = connection.prepareStatement("SELECT id, name FROM product");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Product product = new Product();
product.setId(rs.getInt("id"));
product.setName(rs.getString("name"));
productList.add(product);
}
return productList;
} catch (Exception e) {
throw e;
}
}
Resource.java
#GET
#Path("task/{taskId}")
#Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(#PathParam("taskId") int taskId) throws Exception {
try {
DbConnection database= new DbConnection();
Connection connection = database.getConnection();
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
Here is where I ended up trying to implement the new class:
ServletContextClass.java
public class ServletContextClass implements ServletContextListener {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
} catch (SQLException e) {
throw e;
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
DbConnection database = new DbConnection();
try {
Connection connection = database.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
//con.close ();
}
}
But problem is, I don't know what to do next. Any help? Thanks
You need to set the Connection variable as an attribute of the ServletContext. Also, I would recommend using connection as a static class variable so you can close it in the contextDestroyed method.
You can retrieve the connection attribute in any of your servlets later on for doing your DB operations.
public class ServletContextClass implements ServletContextListener {
public static Connection connection;
public Connection getConnection(){
try {
String connectionURL = "jdbc:mysql://root:port/path";
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
} catch (SQLException e) {
// Do something
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
getConnection();
arg0.getServletContext().setAttribute("connection", connection);
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
try{
if(connection != null){
connection.close();
}
}catch(SQLException se){
// Do something
}
}
}
Finally access your connection attribute inside your Servlet (Resource). Make sure you pass #Context ServletContext to your Response method so you can access your context attributes.
#GET
#Path("task/{taskId}")
#Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(#PathParam("taskId") int taskId, #Context ServletContext context) throws Exception {
try {
Connection connection = (Connection) context.getAttribute("connection");
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
Now that we have solved your current issue, we need to know what can go wrong with this approach.
Firstly, you are only creating one connection object which will be used everywhere. Imagine multiple users simultaneously accessing your API, the single connection will be shared among all of them which will slow down your response time.
Secondly, your connection to DB will die after sitting idle for a while (unless you configure MySql server not to kill idle connections which is not a good idea), and when you try to access it, you will get SQLExceptions thrown all over. This can be solved inside your servlet, you can check if your connection is dead, create it again, and then update the context attribute.
The best way to go about your Mysql Connection Pool will be to use a JNDI resource. You can create a pool of connections which will be managed by your servlet container. You can configure the pool to recreate connections if they go dead after sitting idle. If you are using Tomcat as your Servlet Container, you can check this short tutorial to get started with understanding the JNDI connection pool.

derby In memory database + junit

I got an exception below when trying to use derby in memory database in JUNITTEST.
java.sql.SQLNonTransientConnectionException: Database 'memory:testDB'
dropped. at
org.apache.derby.iapi.error.StandardException.newException(Unknown
Source)
#Before
public void setUp() throws Exception {
String driver = "org.apache.derby.jdbc.EmbeddedDriver";
String connectionURL = "jdbc:derby:memory:testDB;create=true";
Class.forName(driver);
Connection conn = DriverManager.getConnection(connectionURL);
super.setUp();
}
#After
public void tearDown() throws Exception {
String connectionURL = "jdbc:derby:memory:testDB;drop=true";
DriverManager.getConnection(connectionURL);
}
If you are using Maven for your build, you can use the derby-maven-plugin, which I wrote and is available on GitHub and via Maven Central. It will take care of starting and stopping the database for you before your tests.
You can check here for my answer to a similar question.

How to redirec to to HTML if exception occured

I've been trying to search for a way to redirect to an HTML file if a SQLException occurs. I'm going to give you an example.
I have my connection class something like this:
public class DBConection{
Connection con = null;
public DBConnection() throws RuntimeException{
try {
Class.forName("org.gjt.mm.mysql.Driver");
String user = "root";
String pass = "12345";
String db = "java";
con = DriverManager.getConnection("jdbc:mysql://localhost/" + db, user, pass);
}catch (ClassNotFoundException ex) {
throw new RuntimeException();
}catch (SQLException ex) {
throw new RuntimeException();
}
}
}
and I'm calling it from a Servlet class,
public class ElectionsServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String RETURN_PAGE = "index.jsp";
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
DBConnection con = new DBConnection();
response.sendRedirect(RETURN_PAGE);
}
}
If an error ocurres during the DBConnection I want to redirect it to my RETURN_PAGE. Can anybody help me?
Just use the builtin container managed exception handling facilities. You need to rethrow the caught exception as ServletException and define the error page as <error-page> in web.xml.
You only need to change your DB access logic accordingly. It's far from sane, safe and efficient. The exception handling is also strange. You seem to have ripped this from a completely outdated resource given the fact that you're using the deprecated MySQL JDBC driver class name.
Here's a basic kickoff example:
public final class Database {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost/java";
private static final String USER = "root";
private static final String PASS = "12345";
static {
try {
Class.forName(DRIVER);
}
catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError("The JDBC driver is missing in classpath!", e);
}
}
private Database() {
// Don't allow construction.
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASS);
}
}
Finally use and handle it in the servlet as follows:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Connection connection = null;
// ...
try{
connection = Database.getConnection();
// ...
}
catch (SQLException e) {
throw new ServletException("DB fail!", e);
}
finally {
// ...
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
}
(better would be to wrap the DB job in a DAO class which in turn throws a SQLException, but that's a different problem)
And declare the error page in web.xml as follows:
<error-page>
<exception-type>java.sql.SQLException</exception-type>
<location>/WEB-INF/errorpages/database.jsp</location>
</error-page>
You can of course also use <location>/index.jsp</location> but that's not very friendly to the enduser as it's completely confusing why he returns back to there. Rather put that as a link in the database.jsp error page along with something user friendly like
Sorry, an unrecoverable problem has occurred while communicating with the DB. Please click the following link to return to the index page.
See also:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
The question is already answered, but I'll add a few comments:
I don't see the need of catching SQLException and ClassNotFoundException only to rethow RuntimeException instances. If you're planning to do nothing when this exception raises in your DBConnection class, just add throws to your constructor signature. With that, the compiler will check that a try-catch block be added when using your constructor.
There's no need of adding throws RuntimeException to your constructor signature. RuntimeException is a non-checked exception.
Add try-catch block to your doPost method and if any exception occurs in try block, catch that exception and redirect to RETURN_PAGE.
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try{
DBConnection con = new DBConnection();
}catch(Exception e){
response.sendRedirect(RETURN_PAGE);
}
}