Хранение Синглтон Бина в JNDI с GlassFi sh 5 - PullRequest
0 голосов
/ 19 января 2020

У меня есть рабочая установка Glassfi sh 5 внутри Eclipse.

У меня есть модули, настроенные так:

common

  • содержит удаленный интерфейс для одноэлементного компонента с аннотацией @remote и @local
  • во всех других модулях в виде зависимости pom

core

  • содержит одноэлементный компонент, реализующий общий интерфейс
  • , предназначенный для хранения классов обслуживания, хранящихся в JNDI, который позволяет любому количеству клиентов искать и хранить данные и / или получать доступ к другим сервисным логам c
  • , создает файл войны, который развертывается на GlassFi sh

десктоп

  • выполняет поиск InitialContext одиночного компонента. (Я намерен абстрагировать это в шаблон проектирования Service Lookup).
  • предназначен для настольного клиента, который удаленно обращается к бинам, хранящимся на сервере.
  • Прямо сейчас, я просто пытаюсь заставить его получить удаленный доступ к сервису в ядре и распечатать некоторый текст на консоли, доказав, что он работает.

Я думаю, что моя проблема связана с неправильным пониманием того, как в первую очередь хранить пользовательский компонент в JNDI , Я посмотрел в Google, но я в основном нахожу статьи и ответы на вопросы, в которых говорится, что я должен добавить name и mappedName к аннотации Singleton, или они показывают только то, как добавить предопределенный bean-компонент в JDNI, такой как Boolean или String, а не что-то определяемое пользователем.

Мой компонент определяется следующим образом:

@Singleton(name = "BookService", mappedName = "ejb/BookService")
public class BookServiceImpl implements BookService {

    private static final long serialVersionUID = 1L;

, что приводит к этому на сервере Glassfi sh: Скриншот основного сервера

, но в JNDI ничего не отображается: Снимок экрана JNDI

Клиент выполняет поиск InitialContext следующим образом (я пробовал несколько способов написания имени JNDI):

BookService bookService = (BookService) initialContext.lookup("java:global/core/BookService");

используя эти конфигурации (я определил свой домен с базовым портом 8000, поэтому каждый порт равен 8000 + что-то):

glashfishEnvironmentTable = new Hashtable<String, String>();
glashfishEnvironmentTable.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.enterprise.naming.impl.SerialInitContextFactory");
glashfishEnvironmentTable.put(Context.STATE_FACTORIES,
            "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
glashfishEnvironmentTable.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
//glashfishEnvironmentTable.put(Context.PROVIDER_URL, "ejbd://localhost:8080/");
// on a different host than the appserver   
glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialHost", "localhost");
// optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialPort", "8037");

При запуске я получаю такую ​​ошибку:

Exception in thread "main" javax.naming.CommunicationException: Communication exception for SerialContext[myEnv={org.omg.CORBA.ORBInitialPort=8037, java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, org.omg.CORBA.ORBInitialHost=localhost, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is java.rmi.MarshalException: CORBA MARSHAL 1330446343 No; nested exception is: 
org.omg.CORBA.MARSHAL: FINE: 00810007: Underflow in BufferManagerReadStream after last fragment in message  vmcid: OMG  minor code: 7  completed: No]

Я думаю, что мой InitialContext настроен правильно, потому что, когда я вручную определяю bean-компонент в JNDI, как это (ServiceFactory ничего не делает, потому что я не знаю, как правильно расширить ObjectFac tory):

Бин, определенный в JNDI

Я получаю это:

Exception in thread "main" java.lang.ClassCastException: javax.naming.Reference cannot be cast to common.service.BookService

Есть ли простое исправление, которого я пропускаю, или я Я смешиваю масло и воду, пытаясь включить EJB Singleton в JNDI? Или мне не хватает чего-то большого, например EJBHome или Servlet?

Нужно ли расширять фабричный класс, чтобы добавить свои классы обслуживания в JDNI, или должен работать ObjectFactory? Если я должен расширить фабричный класс, как бы я go об этом?

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

1 Ответ

1 голос
/ 20 января 2020

Я понял это. Я сделал две вещи, которые не должен был делать.

  1. Я забыл maven установить мой общий модуль перед созданием моего файла военных действий ... дох!
  2. Кажется, что @Remote и аннотации @Local не могут находиться в одном и том же интерфейсе, иначе произойдет сбой (что обидно, потому что я пытался настроить его, поэтому у меня не было двух почти идентичных интерфейсов).

Вот еще некоторые подробности на тот случай, если у кого-то еще есть похожая проблема, и ему нужно увидеть что-то, что работает (я не делал здесь @Local, потому что я еще не пробовал. Хотя добавить это будет тривиально):

  1. Для удаленного выполнения вам необходим интерфейс с аннотацией @Remote, расширяющий Serializable (для интерфейса клиент / сервер требуется сериализация).
import java.io.Serializable;

public interface Remote extends Serializable{

}
import javax.ejb.Remote;

@Remote
public interface BookServiceRemote extends Remote {

    public String readBook();

}
Ваш файл войны должен содержать BookServiceImpl
import javax.ejb.Singleton;

import us.boggs.template.common.service.BookServiceRemote;

@Singleton(name = "BookService")
public class BookServiceImpl implements BookServiceRemote {

    private static final long serialVersionUID = 1L;

    @Override
    public String readBook() {
        return "Read the book.";
    }
}
Ваш клиент pom. xml должен включать общий модуль, а это:
<dependency>
 <groupId>org.glassfish.main.appclient</groupId>
 <artifactId>gf-client</artifactId>
 <version>5.1.0</version>
</dependency>
Ваш основной метод клиента может использовать это, создав InitialContext и выполнив поиск (Мой базовый порт был 8000, поэтому мой ORBInitialPort равен 8000 + 37 = 8037):
private static Hashtable<String, String> glashfishEnvironmentTable;

static {
    glashfishEnvironmentTable = new Hashtable<String, String>();
    glashfishEnvironmentTable.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.enterprise.naming.impl.SerialInitContextFactory");
    glashfishEnvironmentTable.put(Context.STATE_FACTORIES,
                "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
    glashfishEnvironmentTable.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming"); 
    glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialHost", "localhost");
    // optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
    glashfishEnvironmentTable.put("org.omg.CORBA.ORBInitialPort", "8037");
}
InitialContext initialContext = new InitialContext(glashfishEnvironmentTable);
        BookServiceRemote bookService = (BookServiceRemote) initialContext.lookup("java:global/core/BookService");
System.out.println(bookService.readBook());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...