Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.fds-net.ru/showflat.php?Number=8101850&src=arc&showlite=
Дата изменения: Unknown
Дата индексирования: Tue Apr 12 19:58:58 2016
Кодировка: Windows-1251
Вопрос по JavaSE classloading - Public forum of MSU united student networks
Root | Google | Yandex | Mail.ru | Kommersant | Afisha | LAN Support
  
Technical >> Development (Archive)

Страницы: 1
Minotaurus
addict

Рег.: 19.04.2007
Сообщений: 433
Рейтинг: 635
  Вопрос по JavaSE classloading
      25.11.2008 17:05
 

У меня есть закрытый проприетарный клиент для некоторого application сервера, который хранит настройки подключения в static полях некоторого класса. Из-за этого параллельная работа с разными серверами в несколько потоков становится невозможной. Я пытаюсь решить проблему, загружая копии всех классов отдельно для каждого сервера.
Общая схема примерно такая
code:
package classloading; public class Singleton { public static String name; }


code:
package classloading; public class SingletonUser{ public String getSingletonName(){ return Singleton.name; } public void setSingletonName(String name){ Singleton.name = name; } }

code:
package classloading; import java.net.URL; import java.net.URLClassLoader; public class Test { public static void main(String[] args) throws Exception { URL[] urlsToLoadFrom = new URL[] { new URL("file:subdir/") }; URLClassLoader loader1 = new URLClassLoader(urlsToLoadFrom); URLClassLoader loader2 = new URLClassLoader(urlsToLoadFrom); Class cls1 = Class.forName("classloading.SingletonUser", true, loader1); Class cls2 = Class.forName("classloading.SingletonUser", true, loader2); Object su1 = cls1.newInstance(); Object su2 = cls2.newInstance(); su1.getClass().getMethod("setSingletonName",new Class[]{String.class} ). invoke(su,"111111"); su2.getClass().getMethod("setSingletonName",new Class[]{String.class} ). invoke(su2,"222222"); } }

В результате мы имеем 2 разные копии Singleton, и, соответственно, Singleton.name
Проблема в том, что приходится работать через reflection, и вызовы методов становятся громоздкими. Как нибудь можно это исправить?


Yorik

Рег.: 01.09.2005
Сообщений: 2476
Из: Москва
Рейтинг: 633
  Re: Вопрос по JavaSE classloading [re: Minotaurus]
      25.11.2008 17:18
 

[хренасе заморочка /]
можно генерить при загрузке проксю (например, на Groovy) к классу настроек :)

Mike
Ызарг

Рег.: 02.11.2002
Сообщений: 8098
Рейтинг: 2147
  Re: Вопрос по JavaSE classloading [re: Minotaurus]
      25.11.2008 17:22
2

Quote:

Проблема в том, что приходится работать через reflection, и вызовы методов становятся громоздкими. Как нибудь можно это исправить?



Не понял только одного, почему ты Object потом не приводишь к Singleton? В твоем примере это будет работать.

Minotaurus
addict

Рег.: 19.04.2007
Сообщений: 433
Рейтинг: 635
  Re: Вопрос по JavaSE classloading [re: Mike]
      25.11.2008 20:48
1

Quote:


Не понял только одного, почему ты Object потом не приводишь к Singleton? В твоем примере это будет работать.




Я пробовал, не прокатывает. Singleton.name начинают перекрываться. Но я на всякий случай завтра еще раз проверю.
Quote:


хренасе заморочка




Вроде по другому никак не сделать. :confused:
Quote:


можно генерить при загрузке проксю (например, на Groovy) к классу настроек :)




Тогда же ведь придется декомпилировать и править код клиентской библиотеки? Я не буду этого делать, потому что имеющееся решение с рефлекшеном лучше.
Представь, что Singleton и SingletonUser (это как раз и есть аналог моей закрытой библиотеки) ты не можешь менять, а можешь менять только Test. И в Test тебе надо создать несколько потоков и SingletonUser в каждом и вызывать в них методы SingletonUser, чтобы они не мешали друг другу(а мешают они потому что все обращаются к static полю класса Singleton)



botWi

Рег.: 22.11.2003
Сообщений: 10160
Из: Moscow
Рейтинг: 1764
  Re: Вопрос по JavaSE classloading [re: Minotaurus]
      25.11.2008 21:24
1

В ответ на:

Я пробовал, не прокатывает. Singleton.name начинают перекрываться. Но я на всякий случай завтра еще раз проверю.




типа кастинг приводит к конкретизации класслоадера :(



Хватит дрочить на рейтинги
Mike
Ызарг

Рег.: 02.11.2002
Сообщений: 8098
Рейтинг: 2147
  Re: Вопрос по JavaSE classloading [re: Minotaurus]
      25.11.2008 21:40
 

Quote:

Я пробовал, не прокатывает. Singleton.name начинают перекрываться. Но я на всякий случай завтра еще раз проверю.


Понятно. Сначала я не заметил static. Обычно singleton содержит только одно статическое поле (себя) и имеет private конструктор. Как раз для рефакторинга под нужды, подобные твоим.

Я собрал твой пример, и вызвал getSingletonName() через reflection. У меня получилось, что строка общая для обоих классов.

adiss
новичог

Рег.: 20.04.2004
Сообщений: 13
Из: Пушкино
Рейтинг: 48
  Re: Вопрос по JavaSE classloading [re: Mike]
      25.11.2008 23:06
1

видимо, URL неверный указал и классы дефолтным (parent) класс-лоадером загрузились
добавь assert cls1 != cls2



Не ходи туда, куда ведет дорога, иди туда, где нет пути, и оставь свой след. (Р.У.Эмерсон)
Mike
Ызарг

Рег.: 02.11.2002
Сообщений: 8098
Рейтинг: 2147
  Re: Вопрос по JavaSE classloading [re: adiss]
      25.11.2008 23:28
 

Quote:

видимо, URL неверный указал и классы дефолтным (parent) класс-лоадером загрузились


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

maxkar
enthusiast

Рег.: 19.10.2003
Сообщений: 291
Рейтинг: 15
  Re: Вопрос по JavaSE classloading [re: Minotaurus]
      25.11.2008 23:55
4

В ответ на:


Проблема в том, что приходится работать через reflection, и вызовы методов становятся громоздкими. Как нибудь можно это исправить?




Подобная проблема часто решается при поддержке различных плагинов, которые загружаются внутри с использованием своих ClassLoader's. И решение там - базовый интерфейс, реализуемый соответствующими плагинами (сущностями). После создания объекта, его тип приводится к интерфейсу плагина и вся дальнейшая работа выполняется уже с этим интерфейсом.
code:
package classloading; public interface SingletonInterface { public String getSingletonName(); public void setSingletonName(String name); }

code:
public class SingletonUser implements SingletonInterface { // implementation skipped }

code:
package classloading; import java.net.URL; import java.net.URLClassLoader; public class Test { public static void main(String[] args) throws Exception { URL[] urlsToLoadFrom = new URL[] { new URL("file:subdir/") }; URLClassLoader loader1 = new URLClassLoader(urlsToLoadFrom); URLClassLoader loader2 = new URLClassLoader(urlsToLoadFrom); Class cls1 = Class.forName("classloading.SingletonUser", true, loader1); Class cls2 = Class.forName("classloading.SingletonUser", true, loader2); SingletonInterface su1 = (SingletonInterface) cls1.newInstance(); SingletonInterface su2 = (SingletonInterface) cls2.newInstance(); su1.setSingletonName("111111"); su2.setSingletonName("222222"); System.out.println(su1.getSingletonName()); System.out.println(su2.getSingletonName()); } }

В данном случае SingletonInterface должен грузиться тем же classloader'ом, что и Test (например, быть в classpath). SingletonUser и Singleton - наоборот, должны грузиться отдельными classloader'ами (точно так же, как в исходном примере).
code:
maxkar@*** ~/jtest/loading $ ls classloading/*.class classloading/SingletonInterface.class classloading/Test.class maxkar@*** ~/jtest/loading $ ls subdir/classloading/*.class subdir/classloading/Singleton.class subdir/classloading/SingletonUser.class


Страницы: 1

Technical >> Development (Archive)

Дополнительная информация
1 зарегистрированных и 1 анонимных пользователей просматривают этот форум.

Модераторы:  DarkGray 

Печать темы

Права
      Вы можете создавать новые темы
      Вы можете отвечать на сообщения
      HTML отключен
      UBBCode включен

Рейтинг:
Просмотров темы:

Переход в