2012-01-02 9 views
10

estoy usando EclipseLink en GlassFish 3.1.1 y estoy tratando de entender esta excepción:javax.ejb.EJBException: Acceso ilegal método no-negocio en ninguna interfaz de vista

javax.ejb.EJBException: Illegal non-business method access on no-interface view 
    at org.mycompany.myproject.session.__EJB31_Generated__MyBeanFacade__Intf____Bean__.getEntityManager(Unknown Source) 
    at org.mycompany.myproject.session.AbstractFacade.edit(AbstractFacade.java:28) 
    at org.mycompany.myproject.controller.EditMyBeanServlet.doPost(EditMyBeanServlet.java:199) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 

en cuenta que la El seguimiento de pila indica que el problema se desencadena en el método AbstractFacade.getEntityManager generado por Netbeans.

¿Alguna idea de qué diablos está pasando o algún consejo para solucionar? Supongo que el estado de la transacción o el almacenamiento en caché en el EJB es extraño cuando esto sucede porque a veces llamar al método de edición funciona bien. Estoy llamando a los métodos EJB desde un Servlet. La excepción se produce al intentar guardar cambios en una entidad.

Respuesta

3

Creo que he encontrado una solución y posiblemente un error en el software de terceros. Parece que GlassFish 3.1.1/EJB 3.1/EclipseLink no puede manejar la sobrecarga de métodos correctamente. Tengo un método definido en mi edición llamada EJB que sobrecarga (no anula) el método de la clase abstracta principal. Hay un método llamado editar en el padre abstracto del EJB que toma un tipo genérico y luego tengo un método llamado editar en el EJB que toma una lista. ¡Si cambio el nombre del método a otra cosa para que ya no se sobrecargue, la excepción desaparece!

Código:

public abstract class AbstractFacade<T> { 
protected abstract EntityManager getEntityManager(); 
public void edit(T entity) { 
... 

y

@Stateless 
public class MyEntityFacade extends AbstractFacade<MyEntity> { 
protected EntityManager getEntityManager() { return em;) 
public void edit(List<MyEntity> entities) { 
... 

Nota: Me di cuenta si hago el método público en lugar de getEntityManager protegido Voy a buscar un TransactionRequiredException en lugar de un error EJBException.

+0

En otras palabras: parece que EclipseLink no puede manejar la sobrecarga de métodos heredados en un EJB – Ryan

+3

¿Está relacionado con este problema? http://java.net/jira/browse/GLASSFISH-17235 –

+0

@ piotr-nowicki - Bingo, creo que encontraste un informe de problema del problema. Gracias. ¡Es gracioso que alguien haya votado negativamente esta respuesta! – Ryan

27

El error más probable es que indica que su código intenta llamar al método protegido de todos modos. Esto no está permitido para vistas sin interfaz en un EJB. Solo se le permite llamar al public métodos.

Aquí hay una pequeña falta de coincidencia entre las reglas normales de la clase Java y las reglas EJB. Para una vista sin interfaz, se crea un proxy en función del tipo de clase original (generalmente una subclase dinámica de la misma). Esto significa que los métodos privados protegidos y de paquetes son visibles para el código en el mismo paquete, y en lo que respecta al compilador de Java, su código puede llamarlos.

Pero como se mencionó, esto no está permitido por las reglas de EJB, y por lo tanto se lanza una excepción.

Puede reproducir este fácilmente por inyección un grano como el siguiente:

@Stateless 
public class FooBean { 

    public void callMe() { 
    } 

    protected void doNotCallMe() { 
    } 
} 

inyectar este lugar (por ejemplo, en Servlet mismo paquete) y tratar de llamar doNotCallMe(). Verás la misma excepción. Llame al callMe() y todo estará bien.

+0

Sí, entiendo que solo los métodos públicos son parte de la interfaz EJB. Sin embargo, estoy llamando a un método público llamado edit desde el servlet (código provisto en mi respuesta). Parece que hay un error con ciertos métodos sobrecargados. – Ryan

+1

Bien, ese podría ser el caso. Sin el código de servlet real que hace la llamada, esto es difícil de decir. Por lo tanto, mi respuesta no se aplica realmente a su problema, aunque espero que las personas que busquen la excepción en su título encuentren útil la explicación de todos modos. Votaré tu respuesta;) –

+0

gracias por tomarte el tiempo para responder a mi pregunta. Creo que tu respuesta es útil (lo votaste ayer). Debería haber proporcionado más código. Creo que su respuesta cubre lo que la excepción generalmente significa. – Ryan

0

Lo que es extraño es que tuve el mismo problema con la clase interna de mi EJB. Al intentar llamar al método privado de parent o acceder al EJB inyectado, tuve algunos problemas. Tuve visibilidad en la mayoría de las cosas, pero finalmente una runtie, las cosas van mal.

Finalmente, decidí recuperar mi clase padre a través de JNDI, así podría llamar al método público sin problemas. Mientras tanto podría llamar a métodos privados en mi clase de padres, aún tengo que recordar que fallará.

Cuestiones relacionadas