У меня есть приложение, состоящее из войн, основного ejb с большим количеством сервисов в банке и удаленных интерфейсах в другой банке. Все упаковано в ухо и работает на Glassfish 4.1.Плагин Java EE с использованием CDI Instance Iterator
Теперь я хочу добавить дополнительные точки или плагиновую поддержку ядра ejb.
Цель состоит в том, чтобы иметь разные услуги импорта данных с возможностью горячей замены, которые все используют один и тот же интерфейс, потому что они извлекают и нормализуют финансовые данные от таких поставщиков, как Reuters и Bloomberg.
Эти плагины должны быть обнаружены и управляться компонентом «Менеджер плагинов» в ядре ejb ядра. Плагины должны поддерживать загрузку, загрузку и замену во время выполнения.
В идеале интерфейсы плагина находятся в отдельном пакете, так что кто-то другой может разработать против них без необходимости моего приложения или Glassfish и даже без стека Java EE. Я также хочу развернуть плагины по требованию, а не всегда все приложение.
В настоящее время я пытаюсь использовать итератор экземпляра CDI, который отлично работает с двумя реализациями импортных сервисов, если они находятся в ядре ejb. Если я поместил одну реализацию в отдельную банку ejb, то она просто не найдена CDI. Я думаю, проблема в том, что Glassfish загружает каждый ejb jar в качестве приложения в отдельный загрузчик классов.
Теперь наступает мой текущий упрощенный код!
плагин интерфейс в отдельном банке пакет:
package com.photon.extensions;
import java.io.Serializable;
public interface ImportServiceExtension extends Serializable {
String getImportServiceName();
}
Реализация плагина в отдельном пакете EJB банку, который не найден:
package com.photon.services.extensions.vitrex.services;
import com.photon.extensions.ImportServiceExtension;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Remote(ImportServiceExtension.class)
@Stateless
public class ReutersImportService implements ImportServiceExtension {
@Override
public String getImportServiceName() {
return "Reuters";
}
}
Реализация плагин в основной EJB баночке пакет, который находится:
package com.photon.services.extensions;
import com.photon.extensions.ImportServiceExtension;
import javax.ejb.Stateless;
@Stateless
public class BloombergImportService implements ImportServiceExtension {
@Override
public String getImportServiceName() {
return "Bloomberg";
}
}
Пульт дистанционного управления лицо для «Plugin Manager» в удаленных интерфейсов баночке:
package com.photon.services.extensions;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface ImportServiceExtensionsRemote {
List<String> getImportServiceNames();
}
Реализация боб «Менеджер плагинов» в ядро EJB баночке:
package com.photon.services.extensions;
import com.photon.extensions.ImportServiceExtension;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.ejb.Stateless;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
@Stateless
public class ImportersService implements ImportServiceExtensionsRemote {
@Inject private Instance<ImportServiceExtension> importServiceExtensions;
@Override
public List<String> getImportServiceNames() {
Iterator<ImportServiceExtension> iter = importServiceExtensions.iterator();
List<String> names = new ArrayList<>();
while (iter.hasNext()) {
ImportServiceExtension extension = iter.next();
names.add(extension.getImportServiceName());
}
return names;
}
}
И, наконец, контроллер, который делает имена к сайт в войнах:
package com.photon.website;
import com.photon.services.extensions.ImportServiceExtensionsRemote;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
@RequestScoped
@Named
public class ImportController implements Serializable {
@EJB private ImportServiceExtensionsRemote importServiceExtensions;
public String getImportServiceNames() {
String names = "";
for (String name : importServiceExtensions.getImportServiceNames()) {
names += name;
}
return names;
}
}
В конце отображается только «Bloomberg».
Теперь мои вопросы:
я на правильном пути?
Если да, то что мне не хватает в коде?
Есть ли лучшие решения этой проблемы (OSGI, custom clazz.forName, ...)?
Хорошо, спасибо! Я посмотрю на этот WildFly. – IUnknown