Доступ к EJB без сохранения состояния из другого экземпляра Glassfish

есть проблема, которая меня беспокоит, и я не могу найти единого способа ее решения в Интернете. Я разрабатываю корпоративное приложение с использованием Java EE, Glassfish и Netbeans.

У меня установлено два экземпляра Glassfish, и я создаю корпоративное приложение, разделенное на два. У меня есть веб-страница (с парой JSP и парочкой HttpServlets), работающая на одном экземпляре Glassfish. С другой стороны, я хочу реализовать бизнес-логику приложения. То есть у меня есть несколько Java Entity Beans, а также EJB с удаленным интерфейсом, который использует эти Entity Beans.

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

В одном экземпляре Glassfish удаленный интерфейс EJB:

@Remote
public interface MyEjbRemote {
     //... 
}

и bean-компонент без состояния:

@Stateless(name="ejb/MyEjb")
public class MyEjb implements MyEjbRemote { 
     //... 
}

В другом случае:

public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        MyEjbRemote = lookupEjb();
        //...
    }

    private MyEjbRemote lookupEjb() {
        Properties props = new Properties();
        props.setProperty("java.naming.factory.initial",
            "com.sun.enterprise.naming.SerialInitContextFactory");
        props.setProperty("java.naming.factory.url.pkgs",
            "com.sun.enterprise.naming");
        props.setProperty("java.naming.factory.state",
            "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

        //default: localhost
        props.setProperty("org.omg.CORBA.ORBInitialHost",
            "localhost");
        //default: 3700
        props.setProperty("org.omg.CORBA.ORBInitialPort", "2037");

        InitialContext ic = new InitialContext(props);
        return (MyEjbRemote) ic.lookup("ejb/MyEjb");
    }
}

К сожалению, когда я запускаю свой веб-сайт и пытаюсь найти удаленный ejb, я получаю следующее исключение:

WARNING: Internal error flushing the buffer in release()
WARNING: StandardWrapperValve[jsp]: PWC1406: Servlet.service() for servlet jsp threw exception
java.io.IOException: Stream closed
    at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:277)
    at org.apache.jasper.runtime.JspWriterImpl.clearBuffer(JspWriterImpl.java:222)
    at org.apache.jsp.home_jsp._jspService(home_jsp.java from :76)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:406)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:483)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:373)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:662)

Чего не хватает в моей реализации? Есть предложения / идеи? Пожалуйста, спросите, если что-то не хватает в описании моей проблемы, это моя первая публикация на этом сайте. Ценю ваше время!

Илиас


person Ilias    schedule 21.01.2011    source источник
comment
Я изменил свою реализацию, чтобы следовать инструкциям здесь, но с не повезло вообще. Ошибка внедрения состояния исключений, а также неверный параметр CORBA (org.omg.CORBA.BAD_PARAM) ...   -  person Ilias    schedule 22.01.2011


Ответы (4)


Я вижу здесь несколько ошибок.

Наиболее практичным является то, что исключение, вероятно, исходит от страницы JSP и, по-видимому, не имеет ничего общего ни с сервлетом, ни с доступом к EJB. Оба они не отображаются в трассировке стека. Вероятно, у вас есть JSP с именем home.jsp. Он пытается написать в ответ, но поток, который его представляет, уже закрыт. Где-то вы делаете что-то неприятное, но, скорее всего, это не связано с EJB.

Более теоретическая ошибка состоит в том, что ваш дизайн выглядит как большой антипаттерн. Использование удаленных вызовов EJB исключительно ради «разделения бизнес-логики» - КРАЙНЕ плохая идея. Если вы хотите разделить свою бизнес-логику, просто поместите свои EJB в модуль EJB, сервлеты и JSP в модуль WEB (war) и объедините их вместе в EAR. Используйте локальные интерфейсы. Создание проекта, поддерживающего это, обычно занимает всего несколько щелчков мышью в IDE, таких как Netbeans или Eclipse, и производительность и разумность вашего дизайна намного, намного лучше.

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

Судя по описанию вашей проблемы, я понял, что вы хотите использовать этот второй экземпляр Glassfish для «обычной» мелкозернистой бизнес-логики. Если вы не на 100% уверены в том, что делаете, и не на 100% уверены, что ваша конкретная проблема абсолютно требует удаленного общения, я настоятельно рекомендую вам отказаться от этой идеи.

person Arjan Tijms    schedule 21.01.2011
comment
Спасибо за познавательный ответ, арджан! Я должен согласиться со всем, что вы говорите, но я хочу кое-что добавить. Изначально мое приложение было именно таким, как вы его описываете, с ejbs и jsps / сервлетами в одном EAR. и он отлично работает :) Дело в том, что мне нужно преобразовать свою реализацию несколько распределенным образом, и то, что я пытаюсь сделать в этом посте, направлено именно в этом направлении. Итак, я пытаюсь реализовать удаленную службу для доступа к моему приложению, и я подумал о том, чтобы создать ejb, который что-то делает на другом сервере! Вы правы насчет исключений, но поиск по-прежнему не работает .. - person Ilias; 22.01.2011

Полный пример Glassfish 3.1 + Eclipse Helios + EJB 3.1

Simple Main.java (ПРОСТОЙ клиентский проект НЕ ТРЕБУЕТСЯ В РАЗВЕРТЫВАНИИ)

Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

// optional.  Defaults to localhost.  Only needed if web server is running
// on a different host than the appserver   
props.setProperty("org.omg.CORBA.ORBInitialHost", "127.0.0.1");
// optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

InitialContext ic = new InitialContext(props);
GlassfishSessionBeanRemote gRemote = (GlassfishSessionBeanRemote)ic.lookup("java:global/EJBGFish/GlassfishSessionBean!com.example.GlassfishSessionBeanRemote");
gRemote.sayHello();

Модуль EJB - ВЫ ДОЛЖНЫ РАЗВЕРТАТЬ ВСЕ НИЖЕ ТРИ КАК ФАЙЛ JAR (просто запустить как сервер в Eclipse) - РАЗВЕРТЫВАЕТСЯ

@Stateless
public class GlassfishSessionBean implements GlassfishSessionBeanRemote, GlassfishSessionBeanLocal {

    @Override
    public void sayHello() {
        System.out.println("First Glassfish App!");
    }

УДАЛЕННЫЕ И ЛОКАЛЬНЫЕ ИНТЕРФЕЙСЫ УКАЗАНЫ НИЖЕ.

@Remote
public interface GlassfishSessionBeanRemote {

    public void sayHello();
}

@Local
public interface GlassfishSessionBeanLocal {

    public void sayHello();
}

САМЫЕ ВАЖНЫЕ ЧТО СДЕЛАТЬ:

  1. НЕОБХОДИМО ДОБАВИТЬ gf-client.jar из ПАПКИ GLASSFISH 3.1 LIB в главную. Путь к классу java. (первый)
  2. ДОБАВИТЬ ПРОЕКТ EJB в путь класса Main.java.
person nihar    schedule 17.04.2012
comment
Чтобы IIOP работал, разве вам не нужно настраивать прослушиватель на ORB? - person Thufir; 12.03.2015

Я думаю, вам нужно развернуть проект EJB; После этого вставьте в клиентский проект такой код:

try {
    Context c = new InitialContext();
    HelloRemote z = (HelloRemote) c.lookup("java:global/Pro_EJBModule1/Hello!newpackage.HelloRemote");
    System.out.println(z.sayHello("NGA"));
} catch (NamingException ne) {
    System.out.println(ne);
    throw new RuntimeException(ne);
}

Pro_EJBModule1 - это имя проекта EJB.

person nga    schedule 29.05.2012

Соответствующий ответ, который учитывает автономный клиент, а не развернутый, можно найти в и этот ответ.

person Sym-Sym    schedule 01.10.2013