You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by alltomee <an...@gmail.com> on 2016/12/17 23:45:51 UTC

EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Good night. I'm struggling with this problem forever, so I resolved to put
this question here. Any help will be welcome 

I'm migrating from Glassfish to TomEE. By now, all WARs has been moved and
working by default at TomEE, except one. I have two WARs, one called
EJBSERVER and another called EJBCLIENTS. The EJBSERVER has a EJB called
Hello, that has a method called sayHello, like below:

*package ejbs;

import java.io.*;
import javax.ejb.*;
import javax.annotation.*;

import interfaces.*;

@Stateless
@LocalBean
public class Hello implements HelloJNDI, Serializable{

  private String message = "Hello ";

  public String sayHello(String name) {

    return message + name + "!";
  }

}*

The class HelloJNDI is a interface inside the same WAR but at package
interfaces, like follow:

*package interfaces;

import javax.ejb.*;

@Remote
public interface HelloJNDI{
  String sayHello(String name);
}*

As you can see, it's very simple, like that examples we find at Internet. 

So, now I have another WAR called EJBCLIENTS, who will be client of Hello
class through it's interface HelloJNDI.

The class ClientJNDI is a servlet that does this:

*import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import javax.inject.*;
import javax.ejb.*;
import javax.naming.*;
import javax.rmi.*;

import interfaces.*;

@WebServlet("/clientjndi")
public class ClientJNDI extends HttpServlet{

  public void doGet(HttpServletRequest req, HttpServletResponse res) throws
IOException{

    res.setContentType("text/html; charset=UTF-8");

    PrintWriter writer = res.getWriter();

    try{    
      InitialContext ctx = new InitialContext();
      HelloJNDI hello = (HelloJNDI)
ctx.lookup("java:global/ejbserver/Hello!interfaces.HelloJNDI");
      writer.print(hello.sayHello("World"));
    }
    catch(NamingException e){
      System.out.println("JNDI error");
      e.printStackTrace();
    }

    res.flushBuffer();

  }

}*

So, before anything, let me say that this example works perfectly at
Glassfish. At TomEE and OpenEJB, the following error is shown at browser:

*java.lang.ClassCastException: com.sun.proxy.$Proxy182 cannot be cast to
interfaces.HelloJNDI
	clients.ClientJNDI.doGet(ClientJNDI.java:28)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)*

What's wrong?



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-cast--tp4680774.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Posted by alltomee <an...@gmail.com>.
I solved, just removed @LocalBean from Hello class. But now I can't access
the same EJB locally (inside EJBSERVER itself). 



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-cast--tp4680774p4680778.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Posted by Romain Manni-Bucau <rm...@gmail.com>.
2016-12-19 16:04 GMT+01:00 alltomee <an...@gmail.com>:

> This is not the point. Share or not HelloJNDI as a standalone JAR will not
> make it work, because the problem resides at @LocalBean annotation, that
> works differently at TomEE. As I've said, the same example works at
> Glassfish and Wildfly.
>
>
was just explaining you what you were allowed to expect respecting
tomcat/tomee/ee (all three) classloading.


> By definition for newest EJB annotations, if I do not define any
> interfaces,
> EJB can only be accessed locally (older versions of EJB would need and
> interface). But if I define the @Remote interface for example, the EJB will
> not be accessible locally if I don't define @Local interface. The
> workaround
> was to use the @LocalBean annotation, who let EJB be accessible locally
> without interface, but this is not working at TomEE. My question refers to
> that, why @LocalBean blocks the EJB to be accessible remotely.
>
>
>
@Remote == expose remotely based on the API (same rule as @Local for API
determination but based on remote interface instead of @Local)
@Local == the use passed as argument or if not the single interface as
contract
@LocalBean == skip interfaces and use the class API (public methods) as
contract - more or less fake an interface)

If you use @LocalBean then TomEE will create a proxy based on the class
which includes automatically interfaces. In a single container, by defaut,
tomee skips the serialization IIRC and therefore passes the direct instance
which means it will work if you share the API you request tomee to expose
in tomee/lib for inter apps communication.



>
> --
> View this message in context: http://tomee-openejb.979440.
> n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-
> lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-
> cast--tp4680774p4680791.html
> Sent from the TomEE Users mailing list archive at Nabble.com.
>

Re: EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Posted by alltomee <an...@gmail.com>.
This is not the point. Share or not HelloJNDI as a standalone JAR will not
make it work, because the problem resides at @LocalBean annotation, that
works differently at TomEE. As I've said, the same example works at
Glassfish and Wildfly.

By definition for newest EJB annotations, if I do not define any interfaces,
EJB can only be accessed locally (older versions of EJB would need and
interface). But if I define the @Remote interface for example, the EJB will
not be accessible locally if I don't define @Local interface. The workaround
was to use the @LocalBean annotation, who let EJB be accessible locally
without interface, but this is not working at TomEE. My question refers to
that, why @LocalBean blocks the EJB to be accessible remotely.



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-cast--tp4680774p4680791.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Local bean defines a class used as API in the webapp classloader so not
accessible to other apps. Local uses the interface and a potential
classloader copy between apps so not shocking it works. Sharing HelloJNDI
in tomee lib should make it naturally working.

Le 18 déc. 2016 16:50, "alltomee" <an...@gmail.com> a écrit :

I've created a local interface called HelloLocal, and added annotation
@Local(HelloLocal.class) to Hello class. Everithing is working now (local
and remote client). I don't needed to create the local interface at
Glassfish using the annotation @LocalBean, so anyone know why this happen?
Thank you.



--
View this message in context: http://tomee-openejb.979440.
n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-
lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-
cast--tp4680774p4680779.html
Sent from the TomEE Users mailing list archive at Nabble.com.

Re: EJB remote access (WAR to WAR) throws java.lang.ClassCastException: com.sun.proxy.$Proxy*** cannot be cast to ***

Posted by alltomee <an...@gmail.com>.
I've created a local interface called HelloLocal, and added annotation
@Local(HelloLocal.class) to Hello class. Everithing is working now (local
and remote client). I don't needed to create the local interface at
Glassfish using the annotation @LocalBean, so anyone know why this happen?
Thank you.



--
View this message in context: http://tomee-openejb.979440.n4.nabble.com/EJB-remote-access-WAR-to-WAR-throws-java-lang-ClassCastException-com-sun-proxy-Proxy-cannot-be-cast--tp4680774p4680779.html
Sent from the TomEE Users mailing list archive at Nabble.com.