2010-08-27 33 views
10

Tôi đang cố tải các lớp động vào một thành phần. Tôi đang sử dụng trình chọn tệp để chọn tệp .JAR sẽ được tải và sau đó là ngăn tùy chọn để lấy tên của lớp.Java động Nạp một lớp

Tôi đã trawled internet tìm kiếm làm thế nào để chuyển đổi một tập tin java đến một URL để tải nó trong URLClassLoader và tôi đã đưa ra:

File myFile = filechooser.getSelectedFile(); 
String className = JOptionPane.showInputDialog(
    this, "Class Name:", "Class Name", JOptionPane.QUESTION_MESSAGE); 

URL myUrl= null; 
try { 
    myUrl = myFile.toURL(); 
} catch (MalformedURLException e) { 
} 

URLClassLoader loader = new URLClassLoader(myUrl); 
loader.loadClass(className); 

Tôi bây giờ nhận được một 'không thể tìm thấy biểu tượng 'lỗi khi tải URL vào URLClassLoader

+1

Là 'bị mất' một từ? Điều duy nhất mà Google gợi ý là 'trolled' :-) http://www.urbandictionary.com/define.php?term=trolled –

+0

@seanizer: "được rà soát" —kết qua, như là một phần của tìm kiếm. – trashgod

+1

@trashgod có vẻ tốt hơn rất nhiều ... –

Trả lời

5

ClassPathHacker.java tìm thấy trong this forum thread, là một lựa chọn để tải các lớp năng động.

import java.lang.reflect.*; 
import java.io.*; 
import java.net.*; 


public class ClassPathHacker { 

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(); 
    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 

}//end class 
8

Tôi thích lớp ClassPathHacker nêu tại the answer by Zellus, nhưng nó đầy đủ các cuộc gọi bị phản đối và thông lệ xấu, vì vậy đây là một phiên bản viết lại mà cũng lưu trữ các Classloader và phương pháp addUrl:

import java.lang.reflect.Method; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.io.IOException; 
import java.io.File; 

public class ClassPathHacker{ 

    private static final Class<URLClassLoader> URLCLASSLOADER = 
     URLClassLoader.class; 
    private static final Class<?>[] PARAMS = new Class[] { URL.class }; 

    public static void addFile(final String s) throws IOException{ 
     addFile(new File(s)); 
    } 

    public static void addFile(final File f) throws IOException{ 
     addURL(f.toURI().toURL()); 
    } 

    public static void addURL(final URL u) throws IOException{ 

     final URLClassLoader urlClassLoader = getUrlClassLoader(); 

     try{ 
      final Method method = getAddUrlMethod(); 
      method.setAccessible(true); 
      method.invoke(urlClassLoader, new Object[] { u }); 
     } catch(final Exception e){ 
      throw new IOException(
       "Error, could not add URL to system classloader"); 
     } 

    } 

    private static Method getAddUrlMethod() 
     throws NoSuchMethodException{ 
     if(addUrlMethod == null){ 
      addUrlMethod = 
       URLCLASSLOADER.getDeclaredMethod("addURL", PARAMS); 
     } 
     return addUrlMethod; 
    } 

    private static URLClassLoader urlClassLoader; 
    private static Method addUrlMethod; 

    private static URLClassLoader getUrlClassLoader(){ 
     if(urlClassLoader == null){ 
      final ClassLoader sysloader = 
       ClassLoader.getSystemClassLoader(); 
      if(sysloader instanceof URLClassLoader){ 
       urlClassLoader = (URLClassLoader) sysloader; 
      } else{ 
       throw new IllegalStateException(
        "Not an UrlClassLoader: " 
        + sysloader); 
      } 
     } 
     return urlClassLoader; 
    } 

} 
+0

+ để tính lại tiền! – trashgod

0

Tôi viết lại điều này trong scala trong trường hợp bất cứ ai cần vì nó không phải là 100% tầm thường :)

/* 
* Class which allows URLS to be "dynamically" added to system class loader 
*/ 
object class_path_updater { 
    val URLCLASSLOADER = classOf[URLClassLoader] 

    var urlClassLoader = getUrlClassLoader 
    var addUrlMethod = getAddUrlMethod 

    /* 
    * addFile - have to use reflection to retrieve and call class loader addURL method as it is protected 
    */ 
    def addFile(s: String) = { 
    val urlClassLoader = getUrlClassLoader 
    try { 
     val method = getAddUrlMethod 
     method.setAccessible(true) 
     val v = (new File(s)).toURI.toURL 
     invoke(urlClassLoader, method, Array[AnyRef](v)) 
     def invoke(proxy: AnyRef, m: Method, args: Array[AnyRef]) = m.invoke(proxy, args: _*) 
    } 

    } 

    private def getAddUrlMethod: Method = { 
    if (addUrlMethod == null) addUrlMethod = URLCLASSLOADER.getDeclaredMethod("addURL", classOf[URL]) 
    addUrlMethod 
    } 

    private def getUrlClassLoader: URLClassLoader = { 
    if (urlClassLoader == null) { 
     val sysLoader = ClassLoader.getSystemClassLoader 
     sysLoader match { 
     case x: URLClassLoader => urlClassLoader = sysLoader.asInstanceOf[URLClassLoader] 
     case _ => throw new IllegalStateException("Not a UrlClassLoader: " + sysLoader) 
     } 
    } 
    urlClassLoader 
    } 
} 
Các vấn đề liên quan