Olá pessoal!
Estou cursando o FJ-21 e estava tentando reproduzir um exercício de JSP em casa.
Construí uma classe Contatos, seu respectivo DAO e o ConnectionFactory. No ConnectionFactory, não estava utilizando o Class.forName, pois na própria apostila do FJ21 consta a informação de que ele não é mais necessário no JDBC4.
Quando rodo os testes em modo de aplicação, tudo funciona perfeitamente (adiciono e removo contatos).
Já no meu JSP, quando acesso qualquer método do meu DAO (getLista, por exemplo), o Tomcat exibe o erro abaixo:
org.apache.jasper.JasperException: java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:sqlserver://localhost\SQLEXPRESS;databaseName=fj21;user=sa;password=********;
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Após colocar o Class.forName antes do DriverManager.getConnection(), passou a funcionar.
Afinal, o Class.forName é ou não dispensável? :roll:
Obrigado!
Acho que a versão do driver da Microsoft para o SQL Server que você está usando não implementa o JDBC 4 - alguém me corrija se estiver errado.
Obrigado por responder entanglement
Então, eu baixei este driver no site da Microsoft , e lá constava como JDBC4
Mas eu havia tentado o mesmo teste apontando a conexão para um MySQL em uma VM linux que eu possuo e tive o mesmo problema, só não tinha descoberto que a solução estava no uso do Class.forName().
[]'s
Sempre usei com usando a chamada Class.forName agora quanto ao driver de SQLServer te indico o jTDS que é o melhor ao meu ver.
O uso de Class.forName (sem usar o parâmetro “initialize” como no caso deste overload de forName: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String,%20boolean,%20java.lang.ClassLoader) ) força o carregamento da classe, assim como a execução de blocos “static” que são necessários para inicializar o driver.
A partir do JDBC 4, a idéia é que isso não fosse mais necessário, mas na prática isso ainda é um pouco falho (por exemplo, pode ser que funcione corretamente em uma aplicação Desktop mas não Web, dependendo de classloaders e outras coisas chatas). Por isso, pode continuar a usar Class.forName para inicializar o seu driver.
(Isso não está muito claro na documentação do método Class.forName)
Se você chamar aquele overload forName que tem 3 parâmetros e passar initialize = false, vai só retornar um objeto da classe java.lang.Class<?> que pode ser usado para se referir a classe, mas não vai fazer a inicialização propriamente dita (chamada de blocos static), até a primeira chamada de um método qualquer dessa classe (por exemplo, um construtor ou um método estático).
Obrigado entanglement, agora ficou claro!