Доступ к EJB без сохранения состояния из другого экземпляра Glassfish - PullRequest
3 голосов
/ 22 января 2011

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

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

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

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

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

и компонента без сохранения состояния:

@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)

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

Илиас

Ответы [ 4 ]

2 голосов
/ 17 апреля 2012

Полная версия 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 FOLDER в Main.Путь к классу Java. (Первый)
  2. ДОБАВИТЬ EJB PROJECT в путь к классу Main.java.
2 голосов
/ 22 января 2011

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

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

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

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

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

0 голосов
/ 01 октября 2013

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

0 голосов
/ 29 мая 2012

Я думаю, вам нужно развернуть проект 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.

...