Sobre o uso do Class.forName

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 :slight_smile: - 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 :frowning:

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!