2015-09-24 28 views
0

我正在從事一個項目,這需要動態從文件系統加載類,我谷歌搜索,發現我需要使用自定義ClassLoader。我已經實現了我自己的類加載器,當我在控制檯上運行它時工作正常,當我嘗試在服務器上部署應用程序時出現問題,結果爲ClassNotFoundException在java中的自定義類加載器的不同行爲

問題是我嘗試加載的類包含對已由應用程序加載的另一個類的一些引用,但它試圖從同一位置加載引用。

public class HandlerClassLoader extends ClassLoader { 

static Logger log = Logger.getLogger(HandlerClassLoader.class.getName()); 
URLClassLoader ucl; 
private ProcessDefinition processDefinition = null; 
boolean flag = false; 

public URL[] loadJars() throws MalformedURLException { 

    PropertiesFiles propFiles = new PropertiesFiles(); 

    File f = new File(propFiles.getValue("jarslocation")); 

    log.debug("Loading JARS files from " + f.getAbsolutePath()); 

    List<URL> urls = new ArrayList<URL>(); 

    String filesName[] = f.list(); 

    for (String jars : filesName) 
     if (jars.endsWith("jar")) { 
      urls.add(new URL("file:///" 
        + propFiles.getValue("jarslocation") + "/" + jars)); 
     } 

    URL[] array = urls.toArray(new URL[urls.size()]); 

    return array; 
} 

public HandlerClassLoader() { 
    super(Thread.currentThread().getContextClassLoader()); 
    log.debug("Called to the " + this.getClass().getName() 
      + " No Parameter Constructor"); 
    try { 
     ucl = new URLClassLoader(loadJars()); 

    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } 
} 

public HandlerClassLoader(ClassLoader parent, 
     ProcessDefinition processDefinition) { 
    super(parent); 
    log.debug("Called to the " + this.getClass().getName() 
      + " Parameterized Constructor"); 
    try { 
     ucl = new URLClassLoader(loadJars()); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } 
    this.processDefinition = processDefinition; 
} 

public Class<?> findClass(String className) throws ClassNotFoundException { 
    log.debug("findClass method of " + this.getClass().getName() 
      + " is called with className : " + className); 

    return ucl.loadClass(className); 
} 

我認爲委託原則不起作用或者該服務器必須有不同的類加載器的實現。

+0

你真的實現了你自己的類加載器嗎?最有可能的是,你可以使用'URLClassLoader'來加載你的類,並且它會正確地委託給父類。 – Kayaman

+0

@Kayaman是的我使用URLClassLoader實現了我自己的classLoader,並且在構造函數中已經通過了父類Loader – Ishada

+0

@Kayaman我已經提供了我的類加載器 – Ishada

回答

1

最有可能的是,您不會委託給正確的家長。我認爲選擇Thread.currentThread().getContextClassLoader()會導致在應用程序服務器上使用錯誤的類加載器,而這僅僅是從控制檯應用程序運行時的系統類加載器(類路徑)。

因此,您需要確保您交給自定義類加載器的父代能夠看到您打算加載的類。

最後一點,實現自己的類加載器是一件棘手的事情。例如,您沒有考慮定位資源或定義軟件包。這兩個可能都需要您使用的第三方庫。如果您真的只需要從磁盤加載文件,請考慮使用URLClassLoader

相關問題