2015-09-24 2 views
0

Я работаю над проектом, который требует динамический Загрузка класса из файловой системы, я googled и узнал, что мне нужно использовать пользовательские 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); 
} 

Я думаю, что принцип делегирования не работает, или, возможно, сервер должен иметь различную реализацию classloader.

+0

Вы действительно использовали свой собственный загрузчик классов? Скорее всего, вы можете просто использовать «URLClassLoader» для загрузки своего класса, и он должен делегировать родителям правильно. – Kayaman

+0

@ Kayaman yes Я реализовал свой собственный классLoader с помощью URLClassLoader и в конструкторе прошел родительский класс Loader – Ishada

+0

@Kayaman Я предоставил свой загрузчик классов – Ishada

ответ

1

Скорее всего, вы не делегируете правильного родителя. Я предполагаю, что получение Thread.currentThread().getContextClassLoader() приводит к использованию неправильного загрузчика классов на сервере приложений, в то время как это просто загрузчик системного класса (путь класса) при запуске из консольного приложения.

Таким образом, вы должны убедиться, что родительский элемент, который вы передаете своему пользовательскому загрузчику классов, способен видеть классы, которые вы намереваетесь загрузить им.

В заключение, реализация вашего собственного загрузчика классов - это сложный бизнес. Например, вы не учитывали поиск ресурсов или для определения пакетов. Оба могут потребоваться сторонними библиотеками, которые вы используете. Если вам действительно нужно только загружать файлы с диска, подумайте об использовании URLClassLoader.

Смежные вопросы