Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Общий инстанс класса для разных Applications


Автор: 3x3 1.10.2006, 14:30
Интересен универсальный (и концептуально правильный) подход к решению вопроса интеграции разных приложений.

Вопрос хоть и абстрактный, но приведу пример. Допустим у вас есть приложения CMS, форум и веб-галерея от разных производителей. Каждое из них работает со своей базой пользователей, со своими наборами шаблонов.

Вы создали несколько наборов своих шаблонов для всех трёх приложений -например цветной, черно-белый для устройств плохо отображающих ваш цветной шаблон и шаблон для клиентов не поддерживающих графику (для галереи, наверное, это особенно пикантный случай, но не суть).  Т.е. есть по три стиля оформления для каждого из трех приложений.

Короче дано: 
1. пользователь должен авторизоваться единожды для всех трех приложений
2. В каком бы из приложений пользователь ни выбрал шаблон, остальные должны два должны об этом узнать и тоже обеспечить свой вывод в выбранном стиле
3. Классы, непосредственно заведующие выводом и авторизацией должны бы существовать в единственном числе (синглетоны)
4. RMI и cookie решения не интересуют. Хочется иметь именно единственный экземпляр класса, разделяемый между тремя приложениями в одном контейнере и дергающие друг друга за методы напрямую.
5. Приложения могут знать про существование других приложений всё что угодно - через файлы конфигурации.
6. Конфигурация контейнера недоступна (Tomcatовы server.xml, web.xml) - это потому, что решение должно быть применимо к разделяемому хостингу.
7. К 6-му - соотв. недоступны и каталоги общих библиотек, по этому ресурс, даже размещенный в своём контекстве, видимо работать не будет - ODBC-шный же пут у Томката не работает, если либы лежат в контексте приложения.


Всё, решается, если у приложения есть возможность расшарить интерфейс созданного им экземпляра класса где-нить в общей области.. Только вот как.. Может JNDI позволяет? 


Автор: y3u 1.10.2006, 14:39
можно сделать через вебсервисы, ИМХО... Ну, может, еще получится воспользоваться CORBA... Вобщем в любом случае это достаточно не тривиально. Может проще завести общую БД для хранения конфигов? А перед тем как показывать нужный гуй, просто залезать в эту БД и доставать нужную настройку

Автор: 3x3 1.10.2006, 15:41
Цитата(y3u @ 1.10.2006,  14:39)
можно сделать через вебсервисы, ИМХО... Ну, может, еще получится воспользоваться CORBA... Вобщем в любом случае это достаточно не тривиально. Может проще завести общую БД для хранения конфигов? А перед тем как показывать нужный гуй, просто залезать в эту БД и доставать нужную настройку

Не, RMI, Corba, SOAP - это всё, конечно, красиво, но как-то попахивает оверхедом. Ну зачем нужно превращать каждый запрос в XML (или ещё во что-то), дёргать свой же сервер, на том конце декодировать запрос, и после обработки слать обратно - и это на каждый запрос вида "отрисуй мне эту строчку по шаблону", "оформи мне этот блочок по стилю", "проверь - разрешена ли эта опция клиенту" - их же тысячи на запрос могут быть.... 

А если схема посложнее, то несколько серверов, вовлеченных в распределенную обработку ещё и дидлок могут организовать - замучаешься пыль глотать, отыскивая что случилось. 

Общая БД - это само собой, а бизнес-логика - д/б в приложении. Есть объект "пользователь", чьи методы реализованы классом, а данные хранятся в базе, и который как-то используется разными приложениями - пусть один экземпляр пользователя для всех приложений и будет, при интеграции нужно будет только прописать интерфейсы понятные каждому отдельно взятому приложению. А если в каждом аппликейшне свой инстанс "пользователя" будет жить, то мало того, что расходы на ресурсы возрастут втрое, но и на каждое обращение его всё равно нужно будет из базы вытаскивать - что бы узнать, не изменил ли его сосед, а тут опять же - на каждый чих не наздравкаешься - проще кешировать такие объекты в своём кеше, уже созданными и не обращаться к серверу базы данных каждый раз - тот же оверхед, пусть она и кеширует данные. 

А что бы дать соседям возможность оповестить всех потенциальных держателей инстансов с измененного им пользователя - опять же либо удаленно инвочить некие методы всех потенциально заинтересованных приложений, либо дергать напрямую - замкнутый круг.


Автор: tux 1.10.2006, 17:07
Цитата(3x3 @  1.10.2006,  19:30 Найти цитируемый пост)
Может JNDI позволяет? 

JNDI позволяет, почему нет. Только не понятно чем обращение к некоторому узлу в JNDI и получение оттуда экземпляра класса будет отличаться от вызова вебсервиса. Хотя, возможно, и проще. Хотя здесь, конечно, никаких удаленных вызовов методов не будет. Главное чтобы класс реализовывал интерфейс Serializable.

Автор: 3x3 1.10.2006, 18:24
Цитата(tux @ 1.10.2006,  17:07)
Цитата(3x3 @  1.10.2006,  19:30 Найти цитируемый пост)
Может JNDI позволяет? 

JNDI позволяет, почему нет. Только не понятно чем обращение к некоторому узлу в JNDI и получение оттуда экземпляра класса будет отличаться от вызова вебсервиса. Хотя, возможно, и проще. Хотя здесь, конечно, никаких удаленных вызовов методов не будет. Главное чтобы класс реализовывал интерфейс Serializable.

Зачем Serializable?
Живёт в JVM некий инстанс "пользователь". Другой инстанс другого класса в этой же JVM испытывает настойчивое желание поговрить с этим "пользователем", не беда, что они из разных аппликейшенов. Второму инстансу просто надо как-то получить ссылку на интересующий его интерфейс первого. Совершенно не обязательно для этого его сериализовать, даже, наверное, вредно - потому что я чувствую, что тут попахивает тем, что в результате в сервере поселятся два клона исходного "пользователя" и станут друг с другом потенциально конфликтовать: один аппликейшн будет говорить своему клону "пользователя" одно, другой - своему другое, и постепенно у клонов "пользователя" сформируются совершенно разные взгляды на жизнь ;)

Автор: Stampede 1.10.2006, 18:42
Очень похожий вопрос обсуждался вот тут: http://forum.vingrad.ru/index.php?showtopic=83074&st=0.

Задача стояла практически такая же, разве что отсутствовали ограничения пп. 6 и 7. В общем, там можно кое-чего полезного поДчерпнуть.

Добавлено @ 18:51 
Цитата(3x3 @  1.10.2006,  09:24 Найти цитируемый пост)
Второму инстансу просто надо как-то получить ссылку на интересующий его интерфейс первого.


Тут, ИМХО, выходит практически неразрешимое противоречие с п. 7 (отсутствие доступа к общим библиотекам). Даже если привести классы из разных приложений к общему знаменателю (интерфейсу), то экземпляры, созданные одним ClassLoader'ом, будучи переданные в другое приложение, там не поймутся. Если только не продублировать jar'ы всех приложений во всех контекстах.

Добавлено @ 18:55 
Цитата(3x3 @  1.10.2006,  09:24 Найти цитируемый пост)
Совершенно не обязательно для этого его сериализовать, даже, наверное, вредно - потому что я чувствую, что тут попахивает тем, что в результате в сервере поселятся два клона исходного "пользователя" и станут друг с другом потенциально конфликтовать: один аппликейшн будет говорить своему клону "пользователя" одно, другой - своему другое, и постепенно у клонов "пользователя" сформируются совершенно разные взгляды на жизнь ;)


Абсолютно согласен. Ремоутинг и сериализация - это очень хлюпкие абстракции (leaky abstractions, как говорит Джол Сполски), именно в отношении иллющии работы как с локальными объектами smile

Автор: 3x3 1.10.2006, 19:25
Цитата(Stampede @ 1.10.2006,  18:42)
Очень похожий вопрос обсуждался вот тут: http://forum.vingrad.ru/index.php?showtopic=83074&st=0.

Задача стояла практически такая же, разве что отсутствовали ограничения пп. 6 и 7. В общем, там можно кое-чего полезного поДчерпнуть.

Добавлено @ 18:51 
Цитата(3x3 @  1.10.2006,  09:24 Найти цитируемый пост)
Второму инстансу просто надо как-то получить ссылку на интересующий его интерфейс первого.


Тут, ИМХО, выходит практически неразрешимое противоречие с п. 7 (отсутствие доступа к общим библиотекам). Даже если привести классы из разных приложений к общему знаменателю (интерфейсу), то экземпляры, созданные одним ClassLoader'ом, будучи переданные в другое приложение, там не поймутся. Если только не продублировать jar'ы всех приложений во всех контекстах.

Добавлено @ 18:55 
Цитата(3x3 @  1.10.2006,  09:24 Найти цитируемый пост)
Совершенно не обязательно для этого его сериализовать, даже, наверное, вредно - потому что я чувствую, что тут попахивает тем, что в результате в сервере поселятся два клона исходного "пользователя" и станут друг с другом потенциально конфликтовать: один аппликейшн будет говорить своему клону "пользователя" одно, другой - своему другое, и постепенно у клонов "пользователя" сформируются совершенно разные взгляды на жизнь ;)


Абсолютно согласен. Ремоутинг и сериализация - это очень хлюпкие абстракции (leaky abstractions, как говорит Джол Сполски), именно в отношении иллющии работы как с локальными объектами smile

Хм, вот это было бы самое красивое и отлично масштабируемое решение, идеальное наверное:

Цитата(chief39)
Кстати, вчера поведали, что удалённые интерфейсы расцениваются контейнером как локальные, если могут быть поюзаны как таковые. То есть контейнер сам определяет если интерфейс МОГ БЫ БЫТЬ локальным - то он его как локальный и использует. Правда не знаю какие контейнера это поддерживают. И не проверял ещё.


Тут и безопасность на уровне конфигурации попробовать задать можно - ведь вообще всем приложениям давать потенциальную возможность подёргать инстансы за методы - тоже не хорошо, надо иметь возможность контролировать доступ.

Жаль что chief39 тему не продолжил.. Подниму-ка я ту веточку.

Автор: tux 2.10.2006, 02:12
Цитата(3x3 @  1.10.2006,  23:24 Найти цитируемый пост)
Зачем Serializable?

Иначе просто не понятно каким образом будет храниться объект в JNDI если этот самый сервис JNDI - удаленный. Для того, чтобы передать объект по сети нужно его сериализовать. Собственно, вот. В рамках одной JVM - там да, необходимости нет. Хотя, возможно, я просто чего-то недопонимаю.

Автор: 3x3 2.10.2006, 03:49
Цитата(tux @ 2.10.2006,  02:12)
Цитата(3x3 @  1.10.2006,  23:24 Найти цитируемый пост)
Зачем Serializable?

Иначе просто не понятно каким образом будет храниться объект в JNDI если этот самый сервис JNDI - удаленный. Для того, чтобы передать объект по сети нужно его сериализовать. Собственно, вот. 

Видимо JNDI не годится. Объект нужно не хранить, а расшарить интерфейс конкретного экземпляра конкретным аппликейшенам. С хранением разбирается тот апликейшен, который создал инстанс.


Цитата

В рамках одной JVM - там да, необходимости нет. Хотя, возможно, я просто чего-то недопонимаю.


Или я недопонимаю. Ещё раз:
1. Есть независимое приложение "А". Оно содержит сервлет, бин или что угодно, что заведует созданием пользователей, сохранением их в какой-то там базе и извлечением оттуда, отправкой почты этим юзерам, другой приватной информацией. Оно само предоставляет интерфейс к своим функциям - по управлению юзерами, плюс может вернуть интерфейс конкретного инстанса класса юзера.
2. Есть другое независимое приложение "Б", которое знает про все эти интерфейсы и хотело бы пользоваться объектами, размещенными в приложении "А".

Спрашивается - как код из приложения "Б" может получить указатель на интерфейс объекта, живущего в коллекции одного из классов приложения "А". Как вообще разные приложения могут общаться между собой, минуя уровень контейнера, который может быть недоступен для конфигурации.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)