Nano Hash - криптовалюты, майнинг, программирование

GlassFish расширяет JAR-файлы, используемые обычным загрузчиком классов

Я переношу несколько приложений с JBoss 4 на GlassFish 3.1.x. Каждое из этих приложений использует один и тот же API, который предоставляет общие классы и интерфейсы, используемые каждым из приложений. Назовем его CoreAPI.jar.

CoreAPI.jar помещается в каталог <domain>/lib GlassFish и загружается обычным загрузчиком классов.

Теперь предположим, что каждое приложение расширяет класс (не абстрактный) из CoreAPI с именем Version:

public class Version {
    public String getVersion() { return null; }
}

Метод getVersion() вызывается из самого API в нескольких местах, и каждое приложение, использующее API, отвечает за расширение класса и предоставление такой версии:

public class MyAppVersion extends Version {
    private static final String VERSION = "1.0";

    @Override
    public String getVersion() { return VERSION; }
}

Когда я развертываю приложение в GlassFish, объединенное в WAR или EAR, каждый раз, когда API вызывает getVersion() из родительского класса, я получаю java.lang.NullPointerException — похоже, он не может найти подкласс.

Подкласс будет найден правильно, если CoreAPI.jar связан с WAR и удален из каталога <domain>/lib, но я не могу этого сделать, потому что многие приложения требуют его в качестве общей библиотеки.

Есть ли способ заставить общую библиотеку «видеть» подкласс в развернутом приложении?

Спасибо!

Пояснение: у меня НЕТ доступа для изменения CoreAPI


Ответы:


1

Есть ли способ заставить общую библиотеку «видеть» подкласс в развернутом приложении?

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

Обычно это обнаруживается, когда общий класс пытается сделать что-то вроде Class.forName("com.app.ImplementationClass") в коде, который на самом деле находится в общей библиотеке.

23.05.2012
  • Есть ли способ обойти это? У меня есть аналогичная настройка с сервером Websphere 7 (с использованием ссылок на общие библиотеки), и мой случай работает нормально. В чем разница в загрузчиках классов? 25.05.2012
  • В загрузчиках классов может быть много различий. Я недостаточно знаком с Websphere, чтобы комментировать. Но, например, в Glassfish EAR по умолчанию все классы и jar-файлы ВСЕХ модулей (EJB, WAR и т. д.) объединены в единое общее пространство. В частности, если EAR содержит 2 WAR, WAR A увидит классы и библиотеки в WAR B. Другие серверы приложений делают это по-другому (изолируя WAR), хотя оба способа соответствуют спецификации стандарта. Так что отличий может быть много. Вы должны посмотреть на docs.oracle.com/cd/E18930_01/ html/821-2418/beadf.html для получения подробной информации о GF. 25.05.2012
  • Спасибо! Я уже несколько раз читал иерархию загрузчика классов; и я поместил CoreAPI.jar в несколько разных мест загрузчика классов. Все равно не повезло. К сожалению, я думаю, что "Нет" - правильный ответ на мой вопрос. Я предполагаю, что API нужно будет переписать. 25.05.2012

  • 2

    Чтобы разделить библиотеки между всеми приложениями, вы должны использовать папку $GLASSFISH_HOME/glassfish/lib. Когда вы устанавливаете надстройки для GlassFish с помощью инструмента обновления, вы даже можете заметить, что он копирует сторонние файлы JAR в эту папку, чтобы они были доступны для всех приложений.

    Чтобы поделиться всеми приложениями в домене, вы можете поместить его в папку $GLASSFISH_HOME/glassfish/domains/your-domain/lib, как вы это сделали.

    Чтобы проверить то, что вы описали, я создал 2 проекта maven:

    • Java-проект под названием version (макет вашего CoreAPI)
    • Веб-проект под названием веб-версия (парень, который расширит CoreAPI)

    Проект Java содержит то, что будет вашим неабстрактным классом CoreAPI:

    package com.acme.version;
    
    public class Version
    {
        public String getVersion() { return null; }
    }
    

    В проекте веб-версии я добавляю предоставленную зависимость области к version-1.0.jar, чтобы ее можно было скомпилировать, но она не будет добавлена ​​в проект, как только она будет присутствовать в папке Glassfish/lib.

    Затем проект веб-версии имеет расширенную версию класса Version, которую я использовал для теста:

    package com.acme.web.controller;
    
    import com.acme.version.Version;
    
    public class ExtendedVersion extends Version
    {
        private static final String VERSION = "1.0";
    
        @Override
        public String getVersion ()
        {
            return VERSION;
        }
    
        @Override
        public String toString()
        {
            return getVersion();
        }
    }
    

    Затем я сделал это:

    • Создал проект версии и скопировал полученный файл jar в папку $GLASSFISH_HOME/glassfish/lib, как указано выше.

    • Создал контроллер, содержащий экземпляр ExtendedVersion, и развернул приложение. Он выводит 1.0 на веб-страницу.

    Есть ли способ заставить общую библиотеку «видеть» подкласс в развернутом приложении?

    Ну, это немного странно, потому что загружается общая библиотека. Кажется, что по какой-то причине вашего подкласса нет. (Есть ли какие-либо другие соответствующие исключения в журналах?)

    Я думаю, что по тому немногому, что вы описали, эта проблема может быть даже связана с другими зависимостями, которые у вас были с переходом JBoss x GlassFish, а не с вашим подходом к подклассам или загрузке классов.

    23.05.2012
  • Привет и спасибо за тестирование. Я думаю, что разница в том, что сам API вызывает getVersion() из родителя Version и ожидает, что он вернет переопределение подкласса. 25.05.2012
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..