2012-01-02 5 views
10

sto usando EclipseLink su GlassFish 3.1.1 e sto cercando di capire questa eccezione:javax.ejb.EJBException: Illegal accesso metodo non-business on no-interfaccia 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) 

Si noti che il stack trace indica che il problema è stato attivato nel metodo AbstractFacade.getEntityManager generato da Netbeans.

Qualche idea su cosa diavolo sta succedendo o qualche consiglio da risolvere? Immagino che lo stato della transazione o della cache nell'EJB sia strano quando ciò accade perché a volte il metodo di modifica funziona correttamente. Sto chiamando i metodi EJB da un servlet. L'eccezione si verifica quando si tenta di salvare le modifiche in un'entità.

risposta

3

Penso di aver trovato una soluzione e probabilmente un bug nel software di terze parti. Sembra che GlassFish 3.1.1/EJB 3.1/EclipseLink non sia in grado di gestire correttamente l'overloading dei metodi. Ho un metodo definito nel mio EJB denominato edit che sovraccarica (non sovrascrive) il metodo dalla classe astratta genitore. Esiste un metodo denominato edit nel padre astratto dell'EJB che accetta un tipo generico e quindi ho un metodo denominato edit nell'EJB che accetta un elenco. Se rinominare il metodo in qualcos'altro in modo che non si stia sovraccaricando, allora l'eccezione scompare!

Codice:

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

e

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

Nota: ho notato che se faccio il metodo pubblico getEntityManager anziché protetto Prendo un TransactionRequiredException invece di un EDBException.

+0

In altre parole: sembra che EclipseLink non sia in grado di gestire i metodi ereditati di overload in un EJB – Ryan

+3

È correlato a questo problema? http://java.net/jira/browse/GLASSFISH-17235 –

+0

@ piotr-nowicki - Bingo, penso che tu abbia trovato un rapporto sul problema. Grazie. Divertente che qualcuno abbia svalutato questa risposta! – Ryan

27

L'errore più probabile indica che il codice sta tentando di chiamare comunque il metodo protetto. Questo non è consentito per le viste senza interfaccia su un EJB. È consentito chiamare solo i metodi pubblici.

C'è un piccolo disallineamento tra le normali regole di classe Java e le regole EJB. Per una vista senza interfaccia, viene creato un proxy in base al tipo di classe originale (in genere una sottoclasse dinamica). Ciò significa quindi che i metodi protetti e quelli privati ​​del pacchetto sono visibili per il codice nello stesso pacchetto e, per quanto riguarda il compilatore Java, è possibile che il codice li chiami.

Tuttavia, come detto, questo non è consentito dalle regole EJB e pertanto viene generata un'eccezione.

È possibile riprodurre questo facilmente mediante iniezione un fagiolo come la seguente:

@Stateless 
public class FooBean { 

    public void callMe() { 
    } 

    protected void doNotCallMe() { 
    } 
} 

Iniettare questo da qualche parte (ad esempio Servlet nel pacchetto stesso) e provare a chiamare doNotCallMe(). Vedrai la stessa eccezione. Chiama il numero callMe() e tutto andrà bene.

+0

Sì, ho capito che solo i metodi pubblici fanno parte dell'interfaccia EJB. Comunque in realtà sto chiamando un metodo pubblico chiamato edit dal servlet (codice fornito nella mia risposta). Sembra che ci sia un bug con determinati metodi sovraccaricati. – Ryan

+1

Ok, potrebbe essere il caso. Senza l'effettivo codice servlet che fa la chiamata, era difficile dirlo. La mia risposta quindi non si applica veramente al tuo problema, anche se spero che le persone che cercano l'eccezione nel tuo titolo trovino comunque la spiegazione utile. Preverterò la tua risposta;) –

+0

grazie per aver trovato il tempo di rispondere alla mia domanda. Penso che la tua risposta sia d'aiuto (lo hai upvoted ieri). Avrei dovuto fornire più codice. Penso che la tua risposta riguardi ciò che l'eccezione di solito significa. – Ryan

0

Ciò che è strano è che ho avuto lo stesso problema con la classe interna del mio EJB. Durante il tentativo di richiamare il metodo privato del genitore o l'accesso al bean iniettato, ho riscontrato alcuni problemi. Avevo visibilità sulla maggior parte delle cose, ma alla fine una cravatta, le cose vanno male.

Infine, ho deciso di recuperare la mia classe genitore attraverso JNDI, quindi potevo chiamare il metodo pubblico senza problemi. Nel frattempo potrei chiamare ancora metodi privati ​​nella mia classe di genitori, devo ancora ricordare che fallirà.

Problemi correlati