Unresolved <ejb-link>
Solution 1
I had the same issue when trying to deploy my application, NetBeans generated this code in my web.xml on its own.
Check your web.xml and see if you see this:
<ejb-local-ref>
<ejb-ref-name>appName</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<ejb-link>AppName#SomeClass</ejb-link>
</ejb-local-ref>
if so just remove it comepletely, it should deploy after.
Solution 2
What is the name of your EJB module? Unless the jar file is named literally "TaskTool-ejb.jar", then you need to use either:
<ejb-link>TaskTool-ejb.jar#ContextFacade</ejb-link>
or:
<ejb-link>TaskTool-ejb/ContextFacade</ejb-link>
The latter assumes you haven't overridden the module-name in ejb-jar.xml.
Update: Based on your own comment, perhaps you need to use "com.oracle.eas_TaskTool-ejb_ejb_1.0-SNAPSHOT.jar#ContextFacade" or "com.oracle.eas_TaskTool-ejb_ejb_1.0-SNAPSHOT/ContextFacade".
retrodev
Updated on June 30, 2022Comments
-
retrodev almost 2 years
I'm developing in NetBeans 7, with EJB3.1 and Glassfish 3.1. I am trying to reference the Local Interface of a Session Bean in a JAR from a POJO in a WAR. When I deploy to Glassfish I receive:
SEVERE: Unresolved <ejb-link>: TaskTool-ejb#ContextFacade SEVERE: Exception while deploying the app [com.oracle.eas_TaskTool-ear_ear_1.0-SNAPSHOT] SEVERE: Error: Unresolved <ejb-link>: TaskTool-ejb#ContextFacade
I used the NetBeans helper to generate the code to reference the Session Bean's Local Interface and it generated the
<ejb-local-ref>
section in web.xml for me.@Local public interface ContextFacadeLocal { void create(Context context); void edit(Context context); void remove(Context context); Context find(Object id); List<Context> findAll(); List<Context> findRange(int[] range); int count(); List<Context> findRootContexts(); } @Stateless public class ContextFacade extends AbstractFacade<Context> implements ContextFacadeLocal { @PersistenceContext(unitName = "TaskToolPU") private EntityManager em; protected EntityManager getEntityManager() { return em; } public ContextFacade() { super(Context.class); } @Override public List<Context> findRootContexts() { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Context> query = builder.createQuery(Context.class); Root<Context> c = query.from(Context.class); query.select(c).where(builder.isNull(c.get("parent"))); query.orderBy(builder.asc(c.get("id"))); TypedQuery<Context> q = em.createQuery(query); return q.getResultList(); } } @FacesConverter(value = "contextConverter") public class contextConverter implements Converter { ContextFacadeLocal contextFacade = lookupContextFacadeLocal(); @Override public Object getAsObject(FacesContext fc, UIComponent uic, String string) { return contextFacade.find(string); } @Override public String getAsString(FacesContext fc, UIComponent uic, Object o) {ntityManager() { return em; } public ContextFacade() { super(Context.class); } @Override public List<Context> findRootContexts() { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Context> query = builder.createQuery(Context.class); Root<Context> c = query.from(Context.class); query.select(c).where(builder.isNull(c.get("parent"))); query.orderBy(builder.asc(c.get("id"))); TypedQuery<Context> q = em.createQuery(query); return q.getResultList(); } } @FacesConverter(value = "contextConverter") public class contextConverter implements Converter { ContextFacadeLocal contextFacade = lookupContextFacadeLocal(); @Override public Object getAsObject(FacesContext fc, UIComponent uic, String string) { return contextFacade.find(string); } @Override public String getAsString(FacesContext fc, UIComponent uic, Object o) { return ((Context) o).getId().toString(); } private ContextFacadeLocal lookupContextFacadeLocal() { try { javax.naming.Context c = new InitialContext(); //return (ContextFacadeLocal) c.lookup("java:global/com.oracle.eas_TaskTool-ear_ear_1.0-SNAPSHOT/com.oracle.eas_TaskTool-ejb_ejb_1.0-SNAPSHOT/ContextFacade!com.oracle.eas.ejbs.ContextFacadeLocal"); return (ContextFacadeLocal) c.lookup("java:comp/env/TaskTool-ejb#ContextFacade"); } catch (NamingException ne) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne); throw new RuntimeException(ne); } } } <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> <ejb-local-ref> <ejb-ref-name>ContextFacade</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local>com.oracle.eas.ejbs.ContextFacadeLocal</local> <ejb-link>TaskTool-ejb#ContextFacade</ejb-link> </ejb-local-ref> </web-app>
UPDATE
For clarity:
I don't have an ejb-jar.xml at all.
Using either
<ejb-link>TaskTool-ejb/ContextFacade</ejb-link>
or<ejb-link>com.oracle.eas_TaskTool-ejb_ejb_1.0-SNAPSHOT/ContextFacade</ejb-link>
works.Please see bkail answers below for explanation. Many thanks!
-
retrodev almost 13 yearsbkail, I don't have an ejb-jar.xml at all. Using either <ejb-link>TaskTool-ejb/ContextFacade</ejb-link> or <ejb-link>com.oracle.eas_TaskTool-ejb_ejb_1.0-SNAPSHOT/ContextFacade</ejb-link> works. Could you explain the difference between using # or / and why I need this section in web.xml at all?
-
Brett Kail almost 13 yearsThe # syntax is <uri>#<ejb-name>, where uri is the physical JAR name in the EAR, and ejb-name is the bean name (default is the short class name of the annotated EJB). The / syntax is <module-name>/<ejb-name>, where the module-name is specified in ejb-jar.xml (default is the URI without the extension). Can you elaborate on what you mean by "why I need this section in web.xml at all"? Do you mean the whole ejb-local-ref or the ejb-link?
-
retrodev almost 13 yearsI mean the ejb-local-ref. Glassfish 3.1 doesn't seem to need it.
-
Brett Kail almost 13 yearsThe ejb-local-ref is declaring a reference to allow lookup("java:comp/env/ContextFacade"). If nothing in your code is using that (or you have an @EJB(name="ContextFacade") elsewhere), then you don't need the ejb-local-ref.
-
Twimnox over 7 yearsWorked for me, I don't know what triggers netbeans to do this, it was the first time it happened when developing webservices...