2012-05-16 27 views
5

Tôi đang cố gắng thêm tệp jar vào classpath khi chạy. Tôi sử dụng mã nàyNạp bình khi chạy

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"); 
      } 

     } 

Hệ thống ra bản in url này:

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

Tôi đã kiểm tra con đường này một cách cẩn thận, jar này tồn tại. Ngay cả thử nghiệm này cho thấy com.mysql.jdbc. Lớp trình điều khiển tồn tại.

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 {}; 
} 

Nhưng tôi vẫn nhận được java.lang.ClassNotFoundException khi tôi sử dụng Class.forName này (trình điều khiển). Điều gì sai với mã này?

+0

Bạn có muốn ném một ngoại lệ không? Loại ngoại lệ nào? Khi bạn nói "có gì sai với mã này?" Vui lòng cho chúng tôi biết thêm về kết quả thực tế của bạn và những gì bạn mong đợi – ControlAltDel

+0

có thể trùng lặp của [Thêm tệp vào classpath java lúc chạy] (http://stackoverflow.com/questions/1010919/adding-files-to-java-classpath-at- thời gian chạy) – NPE

+0

có thể trùng lặp của [Làm thế nào tôi nên tải Jars động trong thời gian chạy?] (http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime) –

Trả lời

5

URL là ok, tuy nhiên bạn cố gắng tải một lọ từ classpath, do đó, nó có nghĩa là yo cần phải có các tập tin trong cp đầu tiên. Trong trường hợp của bạn, bạn muốn tải một jar đó không phải là trong classpath vì vậy bạn phải sử dụng URLClassLoader và cho JAR bạn có thể sử dụng cũng là JarClassLoader Nếu bạn muốn có một số bài học mẫu trên đó: http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html

Dưới đây là một mẫu Tôi chạy một mình xem có giúp gì không. Nó tìm kiếm các lớp Logger của Log4j đó không phải là trong classpath của tôi, tất nhiên tôi đã nhận ngoại lệ trên gọi của các nhà xây dựng kể từ khi tôi đã không vượt qua params quyền các nhà xây dựng

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) 

ngoại lệ do gọi sai, tuy nhiên ở giai đoạn này, chúng tôi đã tìm thấy lớp

+0

Tôi đã đọc hướng dẫn. Cám ơn. Nhưng tôi không hiểu làm thế nào nó có thể giúp tôi làm cho tập tin jar có thể truy cập cho ứng dụng của tôi? "bạn phải sử dụng URLClassLoader" - làm thế nào tôi nên sử dụng nó? Tôi hiểu tôi nên sử dụng bộ nạp lớp url hệ thống. Trích dẫn từ tài liệu URLClassLoader: "cả tệp và thư mục JAR" – itun

+0

Có giống như những gì tôi đã làm không? – itun

+0

không, bạn đã sử dụng một URLClassLoader để gọi phương thức addURL tất cả với sự phản ánh. Tôi đã sử dụng trình tải URLClass để lấy lớp của đối tượng được yêu cầu. chỉ cần sử dụng cùng một mẫu và thay đổi url từ mẫu của tôi bằng url bạn cần. – miks

1

Ok thử phương pháp thay thế với DataSource và không trực tiếp điều khiển Dưới đây là mã (làm việc với trình điều khiển oracle, tôi không có db sql của tôi, nhưng các thuộc tính giống nhau) Thường sử dụng giao diện DataSource là cách tiếp cận ưa thích từ JDBC 2.0 Bình DataSource không có trong classpath không cho thử nghiệm bên dưới

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"); 
    } 
    } 
Các vấn đề liên quan