EJB. Getting an instance via context. lookup()

There is an EJB component, a servlet, and one library. All of this runs on a single GlassFish server.

The library implements only one interface common to the ejb component and the client:

Datable.java

package ru.jcup.api;
import javax.ejb.Remote;

@Remote
public interface Datable {
  public String getData(String request);
}

In the EJB application, there is also only 1 class:
DatableImpl.java

package ru.jcup;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import ru.jcup.api.Datable;

@Stateless
@EJB(beanInterface=Datable.class)
Public class DatableImpl implements Datable{

    @Override
    public String getData(String request) {
        return request + " Hell world!";
    }

}

Well, the servlet itself:
MyServlet.java

package ru.jcup.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ru.jcup.api.Datable;

@WebServlet("/getdata")
public class MyServlet extends HttpServlet {

      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          response.setContentType("text/html");

          try {
              Context context = new InitialContext();
                  Object proxy =  (Object)context.lookup("java:global/EjbServer/DatableImpl");

              System.out.println("!!!"+proxy); //<- тут выводится !!!ru.jcup.Datable_294616051
              Datable datable = (Datable)proxy; //<- исключение тут

              PrintWriter out = response.getWriter();
              out.println("<h1>" + datable.getData("What is it?") + "</h1>");
          } catch (NamingException e) {
              e.printStackTrace();
          }

          PrintWriter out = response.getWriter();
          out.println("<h1>Bad!</h1>");
      }
}

When I start the servlet, I get this exception:

2016-01-12T14:41:20.250+0300|Warning: StandardWrapperValve[ru.jcup.servlet.MyServlet]: Servlet.service() for servlet ru.jcup.servlet.MyServlet threw exception
java.lang.ClassCastException: com.sun.proxy.$Proxy222 cannot be cast to ru.jcup.api.Datable
    at ru.jcup.servlet.MyServlet.doGet(MyServlet.java:46)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:745)

Note that in the serlet, the line:

System.out.println("!!!"+proxy); 

Outputs to the console "!!! ru. jcup.Datable_294616051", In theory, the cast should work normally, but this does not happen. That is the question.

Author: aleksandr barakin, 2016-01-12

2 answers

After looking carefully at the logs again, I noticed. The jndi alias was like this:

java:global/EjbServer/DatableImpl!ru.jcup.Datable

And it should be:

java:global/EjbServer/DatableImpl!ru.jcup.api.Datable

Carefully checked the entire project, no mention of ru. jcup.There is no Datable, it is written everywhere ru. jcup. api. Datable The strangest thing is that Glassfish generated it independently (or Eclipse).

It only helped:

  1. renaming the interface
  2. renaming the interface project
  3. renaming the project EJB

A little un-scientific, but it works.

The specified example is fully working. Under circumstances other than mine, it does not generate exceptions.

 1
Author: Александр Сутыркин, 2016-01-12 13:31:23

There was a similar problem. It turned out that the address of the lookup() method at the end specified the interface, and the class itself was needed. That is, in my case, the class HelloWorldbean implements HelloWorldbeanLocal in the sessionbeans package in the ServlelEJB project. In the log file, I found that JNDI gave 2 addresses: "java: global/ServletEJB/HelloWorldbean!sessionbeans.HelloWorldbeanLocal " and " java:global/ServletEJB/HelloWorldbean!sessionbeans.HelloWorldbean". So, the working address was the second one.

 0
Author: Артем, 2020-05-01 16:49:37