2012-05-16 38 views
5

Estoy tratando de agregar el archivo jar a classpath en tiempo de ejecución. Yo uso este códigoCargando jar en el tiempo de ejecución

public static void addURL(URL u) throws IOException { 

      URLClassLoader sysloader = (URLClassLoader) ClassLoader 
        .getSystemClassLoader(); 
      Class<URLClassLoader> sysclass = URLClassLoader.class; 

      try { 
       Method method = sysclass.getDeclaredMethod("addURL", parameters); 
       method.setAccessible(true); 
       method.invoke(sysloader, new Object[] { u }); 
       System.out.println(u); 
      } catch (Throwable t) { 
       t.printStackTrace(); 
       throw new IOException("Error"); 
      } 

     } 

Sistema cabo impresiones de esta url:

file:/B:/Java/Tools/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18-bin.jar 

que el de salida este camino con cuidado, existe este frasco. Incluso esta prueba muestra que com.mysql.jdbc. existe la clase de controlador.

javap -classpath "B:\Java\Tools\mysql-connector-java-5.1.18\ 
mysql-connector-java-5.1.18\mysql-connector-java-5.1.18-bin.jar" com.mysql.jdbc. 
Driver 
Compiled from "Driver.java" 
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver i 
mplements java.sql.Driver{ 
    public com.mysql.jdbc.Driver()  throws java.sql.SQLException; 
    static {}; 
} 

Pero sigo teniendo java.lang.ClassNotFoundException cuando utilizo este Class.forName (conductor). ¿Qué hay de malo con este código?

+0

¿Desea que haga una excepción? ¿Qué tipo de excepción? Cuando dices "¿qué pasa con este código?" Cuéntenos más sobre su resultado real y lo que espera – ControlAltDel

+0

posible duplicado de [Agregar archivos a classpath java en tiempo de ejecución] (http://stackoverflow.com/questions/1010919/adding-files-to-java-classpath-at- tiempo de ejecución) – NPE

+0

posible duplicado de [¿Cómo debo cargar los tarros dinámicamente en el tiempo de ejecución?] (http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime) –

Respuesta

5

La URL está bien, sin embargo, intenta cargar un jar desde classpath, por lo que significa que primero necesita tener el archivo en cp. En su caso desea cargar un frasco que no está en la ruta de clase así que hay que utilizar URLClassLoader y JAR puede utilizar también el JARClassLoader Si quieres un poco de lección de muestra en ella: http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html

Aquí una muestra Corrí yo solo a ver si te ayuda. Es buscar la clase Logger de Log4j que no está en mi ruta de clases, por supuesto que me dieron una excepción en la invocación del constructor desde que no pasó la params adecuadas para el constructor

package org.stackoverflow; 
import java.io.File; 
import java.net.URL; 
import java.net.URLClassLoader; 

public class URLClassLoaderSample 
{ 
    public static void main(String[] args) throws Exception 
    { 
    File f = new File("C:\\_programs\\apache\\log4j\\v1.1.16\\log4j-1.2.16.jar"); 
    URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL()},System.class.getClassLoader()); 
    Class log4jClass = urlCl.loadClass("org.apache.log4j.Logger"); 
    log4jClass.newInstance(); 
    } 
} 



Exception in thread "main" java.lang.InstantiationException: org.apache.log4j.Logger 
    at java.lang.Class.newInstance0(Class.java:357) 
    at java.lang.Class.newInstance(Class.java:325) 
    at org.stackoverflow.URLClassLoaderSample.main(URLClassLoaderSample.java:19) 

excepción debido a la invocación de mal, sin embargo, en esta etapa ya encontramos la clase

+0

He leído el tutorial Gracias. Pero no entendí cómo puede ayudarme a hacer accesible el archivo jar para mi aplicación. "tienes que usar URLClassLoader" - ¿cómo debo usarlo? Entendí que debería usar el cargador de clases de URL del sistema. La cita de los documentos de URLClassLoader: "ambos archivos JAR y directorios" – itun

+0

¿Es lo mismo que hice, no es así? – itun

+0

no, usaste un URLClassLoader para invocar el método addURL todo con reflexión. Usé un cargador URLClass para obtener la clase del objeto solicitado. simplemente use la misma muestra y cambie la URL de mi muestra con la url que necesita. – miks

1

Bien, intente el enfoque alternativo con DataSource y no directamente con el controlador A continuación se muestra el código (trabajando con el controlador oracle, no tengo mi sql db, pero las propiedades son las mismas) Generalmente, el uso de la interfaz DataSource es el enfoque preferido desde JDBC 2.0 El contenedor DataSource no estaba en el classpath tampoco para la prueba siguiente

public static void urlCLSample2() throws Exception 
{ 

    File f = new File("C:\\_programs\\jdbc_drivers\\oracle\\v11.2\\ojdbc6.jar"); 

    URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL() }, System.class.getClassLoader()); 
    // replace the data source class with MySQL data source class. 
    Class dsClass = urlCl.loadClass("oracle.jdbc.pool.OracleDataSource"); 
    DataSource ds = (DataSource) dsClass.newInstance(); 

    invokeProperty(dsClass, ds, "setServerName", String.class, "<put your server here>"); 
    invokeProperty(dsClass, ds, "setDatabaseName", String.class, "<put your db instance here>"); 
    invokeProperty(dsClass, ds, "setPortNumber", int.class, <put your port here>); 
    invokeProperty(dsClass, ds, "setDriverType",String.class, "thin"); 
    ds.getConnection("<put your username here>", "<put your username password here>"); 

    System.out.println("Got Connection"); 
    } 

    // Helper method to invoke properties 
    private static void invokeProperty(Class dsClass, DataSource ds, String propertyName, Class paramClass, 
     Object paramValue) throws Exception 
    { 
    try 
    { 
     Method method = dsClass.getDeclaredMethod(propertyName, paramClass); 
     method.setAccessible(true); 
     method.invoke(ds, paramValue); 
    } 
    catch (Exception e) 
    { 
     throw new Exception("Failed to invoke method"); 
    } 
    } 
Cuestiones relacionadas