[RESOLVIDO] - Tomcat + Mysql - problema com integração (No suitable driver found)

Boa tarde!

Trabalho desenvolvendo aplicações desktop, mas há muito sinto vontade de estudar desenvolvimento para web, e agora estou começando com isso.
Como porta de entrada, estou usando a apostila FJ21 da caelum (a agenda).

Cheguei na parte em que os dados sao inseridos no BD a partir de uma pagina HTMLe um servlet, mas quando dou submit, me aparece esse erro:

java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/fj21
	br.com.agenda.dao.ConnectionFactory.getConnection(ConnectionFactory.java:12)
	br.com.agenda.dao.ContatoDAO.<init>(ContatoDAO.java:18)
	br.com.agenda.servlets.AdicionaContatoServlet.service(AdicionaContatoServlet.java:42)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/fj21
	java.sql.DriverManager.getConnection(DriverManager.java:640)
	java.sql.DriverManager.getConnection(DriverManager.java:200)
	br.com.agenda.dao.ConnectionFactory.getConnection(ConnectionFactory.java:10)
	br.com.agenda.dao.ContatoDAO.<init>(ContatoDAO.java:18)
	br.com.agenda.servlets.AdicionaContatoServlet.service(AdicionaContatoServlet.java:42)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

Ao que parece, driver do mysql nao tá sendo encontrado, mas ele está devidamente adicionado ao buildpath (dentro de WEB-INF/lib), tanto que quando rodo uma classe de teste, o acesso ao banco ocorre sem problemas.

Em outros tópicos vi que esse problema poderia ser resolvido colocando o conector no lib do próprio Tomcat, e foi o que fiz, mas o mesmo problema persiste.

O que posso estar fazendo errado?

Obrigado!

posta sua classe de conexão, o método onde você chama a conexão.

já debugou? em qual linha exatamente ocorre a excpetion?

Conexao:

package br.com.agenda.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionFactory {
	public static Connection getConnection(){		
		try {
			return DriverManager.getConnection("jdbc:mysql://localhost/fj21", "root", "root");
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

Dao:

package br.com.agenda.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import br.com.agenda.modelo.Contato;


public class ContatoDAO {
	private Connection connection;
	
	public ContatoDAO(){
		connection = ConnectionFactory.getConnection();
	}
	
	public void inserir(Contato contato){
		String sql = "insert into contatos(nome, email, endereco, dataNascimento) values (?, ?, ?, ?)";
		try{
			PreparedStatement stmt = getConnection().prepareStatement(sql);
			stmt.setString(1, contato.getNome());
			stmt.setString(2, contato.getEmail());
			stmt.setString(3, contato.getEndereco());
			stmt.setDate(4, new Date(contato.getDataNascimento().getTime()));
			
			stmt.execute();
			stmt.close();
			
		}catch (SQLException e) {
			throw new RuntimeException(e);
		} 
	}
	
	public List<Contato> lista(){		
		try {
			List<Contato> lista = new ArrayList<Contato>();
			String sql = "select * from contatos order by id";
			PreparedStatement stmt = getConnection().prepareStatement(sql);
			ResultSet rs = stmt.executeQuery();
			
			while(rs.next()){
				Contato contato = new Contato();
				contato.setId(rs.getLong("id"));
				contato.setNome(rs.getString("nome"));
				contato.setEmail(rs.getString("email"));
				contato.setEndereco(rs.getString("endereco"));
				contato.setDataNascimento(rs.getDate("dataNascimento"));
				
				lista.add(contato);
			}
			rs.close();
			stmt.close();
			return lista;
		} catch (SQLException e) {
			throw new RuntimeException(e);			
		}		
	}
	
	public void editar(Contato contato){
		String sql = "update contatos set nome=?, email=?, endereco=?, dataNascimento=? where id=?";
		try{
			PreparedStatement stmt = getConnection().prepareStatement(sql);
			stmt.setString(1, contato.getNome());
			stmt.setString(2, contato.getEmail());
			stmt.setString(3, contato.getEndereco());
			stmt.setDate(4, new Date(contato.getDataNascimento().getTime()));
			stmt.setLong(5, contato.getId());
			stmt.execute();
			stmt.close();
		}catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	public void excluir(Contato contato){
		String sql = "delete from contatos where id = ?";
		
		try {
			PreparedStatement stmt = getConnection().prepareStatement(sql);
			stmt.setLong(1, contato.getId());
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public Connection getConnection() {
		return connection;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}
}

Ainda nao procurei saber como debugar um projeto web, mas a excessão é lançada aqui:

try {
			return DriverManager.getConnection("jdbc:mysql://localhost/fj21", "root", "root");
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}

Pra quem ja viu, é identico ao exemplo da apostila fj-21.

voce colocou o driver do mysql dentro de lib?

se não colocou va até o site do mysql e baixe o driver e jogo dentro da pasta lib de seu projeto

java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost/fj21  

A exceção acima me parece um pouco esclarecedora, que tal você verificar se todos os .jars estão devidamente mapeados no classpath.

Vide primeiro post.

Realmente, a exceção é esclarecedora, mas não vejo motivo de ela estar sendo lançada. Segundo tudo o que li e observei, ao adicionar um jar no WEB-INF/lib, este é automaticamente adicionado ao classpath(comprovado pelo fato de eu conseguir acesso sem o tomcat). Não funcionando, colocei dentro do diretório lib na raiz do tomcat (solução pra muitos), mas mesmo assim continuo com o problema.

Repetindo, quando executo uma classe de teste, a conexao com o banco ocorre sem problemas.

  1. Para web não é necessário vc colocar o driver no class path como vc coloca em aplicações para desktop, coloque diretamente no lib dentro de web content WEB_INF.
  2. Sete o driver em bloco static no início da classe:
static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (Exception e) {
			System.out.println("ERRO");
			e.printStackTrace();
		}
	}
  1. Procure setar a porta do Mysql, pois ele pode estar startado em outra porta…
jdbc:mysql:3306//localhost/fj21

[quote=espiaoweb2011]1) Para web não é necessário vc colocar o driver no class path como vc coloca em aplicações para desktop, coloque diretamente no lib dentro de web content WEB_INF.
2) Sete o driver em bloco static no início da classe:

static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (Exception e) {
			System.out.println("ERRO");
			e.printStackTrace();
		}
	}
  1. Procure setar a porta do Mysql, pois ele pode estar startado em outra porta…
jdbc:mysql:3306//localhost/fj21
  1. foi exatamente o que eu disse nos meus primeiro e segundo posts;
  2. Segundo a apostila fj21, o .forName não é mais necessário a partir do java 5 ou 6 (não me lembro exatamente qual, e a apostila está em casa).
  3. A configuração do tomcat está padrão (8080). De qualquer forma, vou explicitar a porta pra testar, quando for pra casa.

Só relembrando o que já disse nos posts anteriores, não sou programador experiente, mas tambem nao sou iniciante. Só estou começando com os conceitos de web agora, seguindo exatamente os exercicios da FJ21 (Exceto pelas versões). Tambem por isso nao entendo o motivo de não estar conseguindo acesso ao banco pelo tomcat.

Sei que é a intenção de todos ajudar, mas peço que procurem entender o problema antes de responder.

Obrigado, galera.

[quote=JhowTroMundo][quote=espiaoweb2011]1) Para web não é necessário vc colocar o driver no class path como vc coloca em aplicações para desktop, coloque diretamente no lib dentro de web content WEB_INF.
2) Sete o driver em bloco static no início da classe:

static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (Exception e) {
			System.out.println("ERRO");
			e.printStackTrace();
		}
	}
  1. Procure setar a porta do Mysql, pois ele pode estar startado em outra porta…
jdbc:mysql:3306//localhost/fj21
  1. foi exatamente o que eu disse nos meus primeiro e segundo posts;
  2. Segundo a apostila fj21, o .forName não é mais necessário a partir do java 5 ou 6 (não me lembro exatamente qual, e a apostila está em casa).
  3. A configuração do tomcat está padrão (8080). De qualquer forma, vou explicitar a porta pra testar, quando for pra casa.

Só relembrando o que já disse nos posts anteriores, não sou programador experiente, mas tambem nao sou iniciante. Só estou começando com os conceitos de web agora, seguindo exatamente os exercicios da FJ21 (Exceto pelas versões). Tambem por isso nao entendo o motivo de não estar conseguindo acesso ao banco pelo tomcat.

Sei que é a intenção de todos ajudar, mas peço que procurem entender o problema antes de responder.

Obrigado, galera.

[/quote]
A versão do java que não necessita do Class.forName é a 6.
Porém, o teu container pode não estar implementando a versão 6 do java de forma completa.
Aí, então, é preciso utilizar esta chamada…

Outro detalhe, acabei de testar, utilizando a versão 1.6 update 29 do java, uma conexão batch com o Oracle XE 10g e, sem o Class.forName, o erro foi o mesmo que está aparecendo para ti.
Colocando o bendito, sem erros.

[quote=drsmachado]Outro detalhe, acabei de testar, utilizando a versão 1.6 update 29 do java, uma conexão batch com o Oracle XE 10g e, sem o Class.forName, o erro foi o mesmo que está aparecendo para ti.
Colocando o bendito, sem erros.[/quote]

Se isso é verdade mesmo, entao a apostila tá furada e não dá pra confiar totalmente no que ela diz.
A versão do tomcat usada nos exemplos é a 5, e eu to usando a 7.
Bom, de qualquer forma, vou testar quando chegar em casa e posto o resultado depois.

Obrigado drsmachado e espiaoweb2011, que também deu a dica.

Reportando, o Class.ForName funcionou perfeitamente (Utilizei o bloco estatigo sugerido pelo espiaoweb2011) , contradizendo a afirmativa da apostila. O interessante é que só não funciona sem registrar o driver quando o Tomcat entra na jogada. Também nunca tive a necessidade de registrar, pois já comecei com java na versão 6. O importante agora é que posso prosseguir com os exercícios.

Agradeço pelas sugestões construtivas e pela paciência!

faça assim:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

eu tive o mesmo problema que vc quando li a apostila.

2 curtidas

E pra reforçar: não é só vocês que tem esse problema. Acabei de chegar nessa parte e também tive que registrar o driver quando uso servlet.
Por que no projeto jdbc da fj21 não precisei registrar o driver, mas no servlet sim?

caramba… demorei mas consegui graças a esse topico… valeu rapaziada! :smiley:

Valeu ai pela dica, passei horas atrás de uma solução e agora resolvi o problema.
De fato o Tomcat só reconhece o Driver quando o mesmo é registrado.

A classe de conexão fica da seguinte forma.

[code]public class ConexaoBanco {
public Connection criaConexao(){

	try{
		DriverManager.registerDriver(new com.mysql.jdbc.Driver());
		return DriverManager.getConnection("jdbc:mysql://localhost:3306/fj21","root","bruno");
		
	}catch(SQLException e){
		throw new RuntimeException(e);
	}
}

}[/code]

Também fiz o que os colegas orientaram a respeito de colocar o JAR dentro da lib do TOMCAT e tudo mais…
Abraço !

1 curtida

Mais um na Lista!

Estava passando pelo mesmo problema, e resolvi com a ajuda desse tópico.

Entretanto, gostaria de saber com mais detalhes porque precisamos registrar o driver do MYSQL antes de usá-lo.

Grato.

Para não apanhar em projetos assim,
é bom procurar sempre um exemplo no google ou preferencialmente no youtube,
pois dá para ver a coisa rodando.

Esse tópico foi preciso! Com o Driver registrado funcionou direito! Valeu…

Sofri com o mesmo problema, e as soluções dos amigos aí resolveram meu problema. Muito obrigado!