2013-06-21 2 views
1

Так вот мой вопрос:Не видя выхода при использовании другого загрузчика классов

У меня есть некоторый код, который вызывается, когда определенное событие происходит на сервере DocuShare. Я слушаю событие в своем собственном eventlistener. Пока все хорошо, это работает без проблем.

Этот прослушиватель вызывается другим кодом, который разработан отдельно и находится в собственном файле jar.

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

Итак, теперь я пытаюсь создать систему, которая копирует этот jarfile (не по пути classpath) в другое временное местоположение (так что не jarlock), загружает jarfile в свой собственный загрузчик классов и выполняет его. Таким образом, я могу просто перезаписать исходный jarfile при разработке новой версии. Затем код увидит, есть ли модификация jarfile и выполните те же действия, если это так.

Я сделал это успешно в более простой настройке (вызов сервлета), поэтому я знаю, что подход «горячего развертывания» работает с банками.

Однако в этом случае код работает до тех пор, пока я не начну использовать отдельный загрузчик классов. Я могу найти jarfile и проверить различия и загрузить jarfile соответственно, но когда я пытаюсь получить доступ к классу, я больше не получаю никаких данных в System.out или System.err. Код в банке не выполняется должным образом, но я не понимаю, почему.

Дополнительно: код выполняется в отдельном потоке

Обзор Что происходит:

  1. DocuShare Отправляет событие
  2. Мой слушатель подхватывает событие
  3. Слушатель (реализует java.util.concurrent.Executor) запускает новый поток (Runnable impl)
  4. Runnable impl создает новый загрузчик классов и затем проверяет, есть ли новая версия файла jar внутри папки, если он будет скопировать его в другой каталог, если он не использует существующую версию, загрузите его по пути класса нового загрузчика классов и выполните его.
  5. Fromt момент, когда я загружаю класс с помощью new ClassLoader Я не вижу ни одной строки, напечатанной в System.out/System.err.

пример кода (в методе Runnable.run()):

URLClassLoader hotCL = new URLClassLoader(((URLClassLoader) systemCL).getURLs()); //new URLclassloader with URLs from system CL 

//the following approach for putting the class on the classpath comes from another SO question from somebody else 
Method m = cl.getClass().getDeclaredMethod("addURL", new Class[]{URL.class}); 
m.setAccessible(true); 
m.invoke(cl, jar.toURI().toURL()); 
String cp = System.getProperty("java.class.path"); 
if (cp != null) { 
    cp += File.pathSeparatorChar + jar.getCanonicalPath(); 
} else { 
    cp = jar.toURI().getPath(); 
} 

Logger.log(">>>>>>>> instantiating impl"); //this is printed in the System.out 
Class<?> clsService = hotCL.loadClass(strService); //strService is the class inside the separate jar 
Object instance = clsService.newInstance(); 

Logger.log(">>>>>>>>>>>> class: " + clsService.getClass().toString()); //this is not printed in the System.out, neither is any log-statement after this or any error 
//after this a method of the class instance is called but the code doesn't do anything. Possibly an error but there's no error/stacktrace 

Есть ли что-то я пропускаю о загрузчики классов? Я просто не понимаю, почему я не вижу ошибок или кода.

+0

Я бы отметил его как «docushare», но он требует 1500 баллов. –

+0

Похоже, что ваша нить тихо умирает от исключения. Попробуйте поместить свой код в блок try-catch и распечатать исключение. Обратите внимание, что он не будет пузыриться до командной строки, как в основном потоке - см. Здесь для дальнейшего чтения http://www.ibm.com/developerworks/library/j-jtp0924/ – selig

+0

'newInstance' может генерировать исключения по множеству причин - у класса вашей загрузки есть пустой конструктор? – selig

ответ

0

Ваш загрузчик классов, вероятно, висит, когда он пытается загрузить классы JDK, на которые ссылаются ваши динамические классы, потому что ему нужен родительский загрузчик классов, способный загружать классы JDK. Вы можете взять функциональный родитель из текущего контекста, т.е .:

new URLClassLoader(urls, this.getClass().getClassLoader()) 

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

+0

Это решило проблему. Спасибо большое. –

+0

У меня была эта же проблема и я уже пробовал это же решение, но это не сработало. Единственное различие, насколько я могу судить, заключается в том, что вместо создания нового 'URLC lassLoader', мне пришлось создать свой собственный класс, который расширяет «URLClassLoader» и вместо этого создаст новый экземпляр этого. Тем не менее, я установил родительский элемент в « .class.getClassLoader()» и правильно настроил URL-адреса, и все, кажется, работает, кроме ведения журнала, включая 'System.out.println()'. Может ли кто-нибудь помочь? Должен ли я сделать это отдельным вопросом? – Variadicism