Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
25. Jun 2008, 22:01 CET | Link

Is this even possible?

@Stateless
public class MyEjbBean implements MyEjb {
   . . . .
}

@Name("myComponent")
public class MyComponent {
   
   @EJB
   private MyEjb myEjb;
  
   . . . 

}

I tried using the @In annotation like the following but the bean never gets injected:

@Name("myComponent")
public class MyComponent {
   
   @In(create=true)
   private MyEjb myEjb;
  
   public String doSomething() {
       // myEjb is null
   }

}

Any ideas about how I get an EJB injected into a component?

Any help would be appreciated.

9 Replies:
25. Jun 2008, 22:10 CET | Link

Well I am getting into a similar problem. Do we have to implement @Factory for this or do we have to specify the component in Components.xml?

Something similar to this here

25. Jun 2008, 22:13 CET | Link

This is kinda like the blind leading the blind here but I think the component is registered fine. I can see in the logs that myComponent is registered.

The EJB is also registered as I have a simple servlet that uses it and the @EJB annotation works fine over there, so both objects do exist. It's a question of having Seam inject the EJBs into the components.

If anybody has a solution or a workaround, I'd be very happy to hear it. Thanks in advance.

26. Jun 2008, 12:56 CET | Link

Your session bean has no @Name tag so it cannot possibly work, since Seam doesn't know this class then.

So give it a name und use it in the @In tag.

Cheers Markus

26. Jun 2008, 16:09 CET | Link

Thanks for the reply Markus.

I tried that and put a @Name(myEjb) annotation on the SLSB and used @In instead of @EJB but got this error:

org.jboss.seam.RequiredException: @In attribute requires non-null value: myComponent.myEjb

If I try using @In(required=false), myEjb never gets injected.

If I try using @In(required=false, create=true), I get the following error:

javax.servlet.ServletException: #{myComponent.myComponentMethod}: org.jboss.seam.InstantiationException: Could not instantiate Seam component: myEjb

and the cause of the exception is:

javax.naming.NameNotFoundException

This doesn't make any sense because in the logs I see this:

Component: myEjb, scope: CONVERSATION, type: STATELESSSESSIONBEAN, class: com.mypackage.MyEjbBean, JNDI: MyEjbBean/local

For what its worth I've also tried this using the SeamInterceptor by annotating the component with @Stateless(SeamInterceptor.class) and by specifying the following property in web.xml:

    <context-param>
        <param-name>org.jboss.seam.core.init.jndiPattern</param-name>
        <param-value>#{ejbName}/local</param-value>
    </context-param>

I've also tried the following but with no success:

@In(required=false, value="myEjb")
@In(required=false, value="#{myEjb}")
@In(required=false, create=true, value="myEjb")
@In(required=false, create=true, value="#{myEjb}")

The only thing odd worth mentioning is that the EJB and the Seam component are in two different JARs but that shouldn't matter since I see both of them getting registered with Seam in the logs. Is this a JNDI issue because only the SLSB has a jndi name associated with it, not the plain old Seam components.

I've even consulted two books called Beginning JBoss Seam and Practical JBoss Seam and they have no mention of this seemingly simple scenario.

All I'm trying to do is separate my action layer which consists of Seam components from my DAO layer which consists of beans that are Seam components and EJBs.

Any help is greatly appreciated.

26. Jun 2008, 17:11 CET | Link

Well, I'm not sure whether this scenario is really supported by Seam, since EJB's normally are obtained via JNDI.

The simplest solution is clear: Make MyComponent a session bean. This is not costly as of EJB 3.0.

If that is not feasible you always can perform a JNDI lookup

new InitialContext().lookup(MyEJB.JNDI_NAME);

or use

@JndiInject

from jboss annotations:

@JndiInject(name="pathTo-MyEjbBean/local")
private MyEjb myEjb;

Cheers Markus

26. Jun 2008, 17:15 CET | Link

It is very possible this is a JNDI issue. Check components.xml for your configured jndi-pattern and make sure it matches how your EJB is being registered:

<core:init jndi-pattern="#{ejbName}/local"/>

Also, for what it is worth if you want the EJB created there is another option. Simply annotate the EJB with @AutoCreate and you can leave out the create=true in the @In.

Hope it helps.

 

--------------------------------------------------

Check my blog to find announcements on Seam Framework: Experience the Evolution of Java EE

26. Jun 2008, 18:53 CET | Link

Thanks for the suggestion. I have the JNDI pattern configured via a web.xml init parameter and its not the problem. I also tried putting it in the components.xml but that didn't work either.

26. Jun 2008, 18:57 CET | Link

Jacob, I'm using Glassfish so @JndiInject doesn't apply to me.

This problem is leading me to a deeper question:

How does one separate the action layer from the DAO layer in Seam? In my action layer (which I hoped to be purely Seam components) I wanted to redirect to views, provide success/fail messages and do some manual validation etc. and once done, I would make calls to my EJB layer (which I hoped to be EJB beans and Seam components).

Any recommendations on how to do this?

Thanks.

01. Jul 2008, 08:00 CET | Link

BTW, the problem with this whole setup was me not defining an <ejb-local-ref> element for the EJB in web.xml. That fixed everything:


<ejb-local-ref>
   <ejb-ref-name>MyEjbBean</ejb-ref-name>
   <ejb-ref-type>Session</ejb-ref-type>
   <local>MyEjb</local>
</ejb-local-ref>