Carregar driver JDBC em tempo de execução

12 respostas
venomtotal

Estou fazendo uma aplicação swing para conectar-se numa base de dados. Nela o usuário passará as informações de conexão como: ip, usuario, senha e etc…

Também haverá a opção de através de um filechooser, ele possa apontar onde está o arquivo jar do driver jdbc. A minha dúvida é como fazer para carregar este arquivo jar em tempo de execução.

Num projeto normalzinho, onde sei qual o banco e versao do driver que o usuário usará, é muito fácil, pois basta vincular o arquivo jar através da IDE.

Mas em tempo de execução?

Agradeço qualquer ajuda.

venom

12 Respostas

rafaelglauber

Provalmente terá que limitar a alguns banco de dados, por exemplo, a url do oracle é diferente a montagem para o banco firebird por exemplo, terá que além de carregar o jar ainda perguntar a qual banco se destina para montar a url. Com relação a esse “carregamento”, acredito que se vc sempre copiar os arquivos para o seu ClassPath não terá problemas em fazer o Load dinamicamente.

venomtotal

hmm. Tinha esquecido de dizer, o usuário irá passar a string do banco correspondente, mas referente ao carregamento e classpath.

Se eu estiver falando besteira me corrija(sou novato), mas como vou alterar o classpath enquanto a aplicação tiver rodando? Tem algum comando ou variavel interna do java que faça isso? Pergunto, porque pesquisei a sua sugestao e so vi configuração do classpath manualmente: http://www.guj.com.br/java.artigo.108.1.guj

Na teoria o bom seria neste projeto ter algo assim:

//variavel que aponta o local do arquivo jar. O valor será obtido através do JFileChooser
String localDoArquivo;

ClassPath = localDoArquivo;


Agradeço qualquer ajuda

VENOM

venomtotal

Ah, desculpa, a resposta saiu incompleta:

Na verdade, eu percebi as duas maneiras de fazer isso:
01-Alterar o ClassPath, adicionando o caminho do arquivo jar nele.
02-o que você sugeriu, copiar o arquivo jar pra algum dos diretórios contidos no ClassPath.

De qualquer forma, eu precisso ler e escrever o conteudo no ClassPAth. Como fazer isso?

kaique

Cara, não sei se minha dica irá te ajudar muito para resolver seu problema, mas dá uma pesquisada sobre ClassLoaders em Java…
Aqui no GUJ tem um artigo que fala sobre isso. Acho que ele pode te dar uma noção da sua funcionalidade. Aí você vê se ajuda…
Aqui vai o link para a classe na API do Java:
http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html

[]'s.

falvesti

Cara quando fiz meu TCC passei pelo mesmo probelma. Pelo que entendi vc precisa instanciar um jar no classpath em tempo de execução, correto?

Não lembro de kbça como faz mas tenho em casa no código fonte do meu TCC. Hoje anoite te passo.

Abraço

falvesti

Boa notícia!!! Achei o código aki no trampo. Segue:

public static void main(String[] args) {
		URL jarUrl = getJarUrl(caminhoDoJar);
		addJarToClassPath(jarUrl);
	}
	
	/**
	 * Método que adiciona o jar com o driver jdbc no classpath da aplicação
	 * @param url a url resolvendo o arquivo jar
	 * @throws Exception caso de algum erro inesperado
	 */
	@SuppressWarnings("unchecked")
	private void addJarToClassPath(URL url) throws Exception{
		URLClassLoader sysloader = (URLClassLoader) ClassLoader
				.getSystemClassLoader(); // pega o class loader do sistema
		Class sysclass = URLClassLoader.class;
		Method method = sysclass.getDeclaredMethod("addURL", PARAMETERS_TYPES);
		method.setAccessible(true);
		method.invoke(sysloader, new Object[] { url });
	}

	/**
	 * Método de fabrica para uma transformar o caminho de um jar em uma url validada
	 * @param jarPath
	 * @return o caminho do jar abstraido em um objeto do tipo URL
	 * @throws MalformedURLException
	 */
	private URL getJarUrl(String jarPath) throws MalformedURLException {
		return new URL("jar", "", "file:" + jarPath + "!/");
	}

Abraço!

P

isso resolve seu problema

package updateclasspath;

public class UpdateClasspath {
    
    public UpdateClasspath() {
    }
    
    private static final Class[] parameters = new Class[]{URL.class};

    public static void addFile(String s) throws IOException {
        File f = new File(s);
        addFile(f);
    }//end method

    public static void addFile(File f) throws IOException {
        addURL(f.toURL());
    }//end method


    public static void addURL(URL u) throws IOException {

        URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
        //URLClassLoader sysloader = (URLClassLoader)Thread.currentThread().getContextClassLoader();
        Class sysclass = URLClassLoader.class;

        try {
                Method method = sysclass.getDeclaredMethod("addURL",parameters);
                method.setAccessible(true);
                method.invoke(sysloader,new Object[]{ u });
        } catch (Throwable t) {
                t.printStackTrace();
                throw new IOException("Error, could not add URL to system classloader");
        }//end try catch

    }//end method

}
Gobain

Então, eu fiz um programinha na faculdade pra mexer com BD q carregava o jar em tempo de execução.
Tem um porém na hr de carregar o driver q eu não consegui encontrar explicação alguma, mas funcionou… Talvez alguém possa explicar o porque disso.

Aqui carrega o jar e retorna uma instância do Driver

private Driver carregarDriverJar(String caminho, String driverClass) {
	try {
		URL caminhoDr = new URL("file",null,"/"+caminho);
		URL[] urls = {caminhoDr};

		URLClassLoader loader = new URLClassLoader(urls);
		Driver driver = (Driver)Class.forName(driverClass,true,loader).newInstance();

		return driver;
	} catch (MalformedURLException ep) {
		ep.printStackTrace();
		return null;
	} catch(ClassNotFoundException ep) {
		ep.printStackTrace();
		return null;
	} catch(IllegalAccessException ep) {
		ep.printStackTrace();
		return null;
	} catch(InstantiationException ep) {
		ep.printStackTrace();
		return null;
	}
}

Aqui usa o driver carregado para conexão

public void conectar(Driver conDriver, String url, String login, String senha) {
	try {
		DriverManager.registerDriver(new DriverMid(conDriver)); // Atenção para o uso da classe DriverMid
		con = DriverManager.getConnection(url,login,senha);
	} catch(SQLException ep) {
		ep.printStackTrace();
	}
}

Agora vem o porém… se vc passar o driver direto pra registrar com o DriverManager não passa… não sei pq. Daí eu achei num paper muito do além q o cara tinha feito essa implementação da classe Driver, e com isso o DriverManager aceita o driver em tempo de execução.

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;

public class DriverMid implements Driver {
	private Driver driver;

	public DriverMid(Driver d) {
		this.driver = d;
	}

	public boolean acceptsURL(String u) throws SQLException {
		return this.driver.acceptsURL(u);
	}

	public Connection connect(String u, Properties p) throws SQLException {
		return this.driver.connect(u, p);
	}

	public int getMajorVersion() {
		return this.driver.getMajorVersion();
	}

	public int getMinorVersion() {
		return this.driver.getMinorVersion();
	}

	public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException {
		return this.driver.getPropertyInfo(u, p);
	}

	public boolean jdbcCompliant() {
		return this.driver.jdbcCompliant();
	}
}

Não tem nada de mais a implementação, mas funciona, e isso é o q as vezes é o mais importante :smiley:

venomtotal

Agradeço a todos pela disposição de ajudar e pelas respostas.

Amanhã vou testar e depois posto no que deu

venom

Zeed01

Boa noite Colegas !

Estou com o mesmo problema…

Gobain:

No seu código o que deve ser passado no parametro driverClass no método:

private Driver carregarDriverJar(String caminho, String driverClass) {

??

Obrigado.

Um abraço.

maquiavelbona

Será que dar uma olhada nos sources de softwares como o SquirrelSql, ISQL e sql workbench não ajuda mais? Creio que os desenvolvedores tiveram esses mesmos problemas e ainda outros que vocês poderão ter.

Até!

Zeed01

Boa madrugada Colegas !

maquiavelbona:

Confesso que baixei os fontes do SquirrelSql… mas não consegui encontrar a resposta.

Você tem a solução para me ajudar ?

Obrigado.

Um abraço.

Criado 10 de janeiro de 2008
Ultima resposta 6 de jan. de 2009
Respostas 12
Participantes 8