5 Replies Latest reply on Feb 19, 2002 6:27 PM by Vincent Harcq

    Reference/link to local interface in different jar (Jboss 2.

    Oliver Henlich Newbie

      Hi.

      This looks long but please have a look, just trying to be thorough.

      Does anyone know whether jboss supports the feature described in the ejb2.0
      dtd whereby a bean can reference another bean packaged in a seperate jar file?

      Here is the bit i'm talking about (from http://java.sun.com/dtd/ejb-jar_2_0.dtd ):
      [pre]
      <!--
      The ejb-link element is used in the ejb-ref or ejb-local-ref
      elements to specify that an EJB reference is linked to an
      enterprise bean.

      The value of the ejb-link element must be the ejb-name of an
      enterprise bean in the same ejb-jar file or in another ejb-jar
      file in the same J2EE application unit.

      Alternatively, the name in the ejb-link element may be composed of a
      path name specifying the ejb-jar containing the referenced enterprise
      bean with the ejb-name of the target bean appended and separated from
      the path name by "#". The path name is relative to the ejb-jar file
      containing the enterprise bean that is referencing the enterprise bean.
      This allows multiple enterprise beans with the same ejb-name to be
      uniquely identified.

      Used in: ejb-local-ref, ejb-ref

      Examples:

      <ejb-link>EmployeeRecord</ejb-link>

      <ejb-link>../products/product.jar#ProductEJB</ejb-link>

      -->
      [/pre]


      I'm having problems getting this to work. When deploying beanA, jboss says

      "Cause:org.jboss.ejb.DeploymentException: Bean beanC.jar#ejb/bean_c not found within this application."


      What I'm doing:
      1. SFSB BeanA that wants to get a:
      - remote reference to BeanB
      - local reference to BeanC

      2. BeanB is deployed in its own jar (beanB.jar)
      3. BeanC is deployed in its own jar (beanC.jar)
      4. BeanA is deployed and then error happens....

      Files:
      [pre]
      == BeanA deployment descriptor ==
      =================================
      <ejb-jar>
      <enterprise-beans>

      <ejb-name>bean_a</ejb-name>
      BeanAHome
      BeanA
      <ejb-class>BeanAEJB</ejb-class>
      <session-type>Stateful</session-type>
      <transaction-type>Container</transaction-type>

      <!-- remote reference -->
      <ejb-ref>
      Reference to beanB through its remote interface
      <ejb-ref-name>ejb/refToBeanB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      BeanBHome
      BeanB
      </ejb-ref>


      <!-- local reference -->
      <ejb-local-ref>
      Reference to beanC through its local interface

      <!--The logical name used with the referencing bean's code to refer to this reference-->
      <ejb-ref-name>ejb/refToBeanC</ejb-ref-name>

      <!--The Java type expected by the enterprise bean-->
      <ejb-ref-type>Session</ejb-ref-type>

      <!--The fully qualified class name for the referenced bean's local home interface-->
      <local-home>BeanCHome</local-home>

      <!--The fully qualified class name for the referenced bean's local interface-->
      BeanC

      <!-- An optional (see notes)-->
      <!-- But in JBOSS: Local references currently require ejb-link -->
      <ejb-link>beanC.jar#ejb/bean_c</ejb-link>

      </ejb-local-ref>



      </enterprise-beans>
      </ejb-jar>

      == BeanA jboss.xml ==
      ======================

      <enterprise-beans>

      <ejb-name>bean_a</ejb-name>
      <jndi-name>ejb/bean_a</jndi-name>

      <ejb-ref>
      <ejb-ref-name>ejb/refToBeanB</ejb-ref-name>
      <jndi-name>ejb/bean_b</jndi-name>
      </ejb-ref>

      <ejb-local-ref>
      <ejb-ref-name>ejb/refToBeanC</ejb-ref-name>
      <jndi-name>ejb/bean_c</jndi-name>
      </ejb-local-ref>


      </enterprise-beans>


      == BeanC deployment descriptor ==
      =================================
      <ejb-jar>
      <enterprise-beans>



      <ejb-name>ejb/bean_c</ejb-name>

      <local-home>BeanCHome</local-home>
      BeanC
      <ejb-class>BeanCEJB</ejb-class>
      <session-type>Stateful</session-type>
      <transaction-type>Container</transaction-type>



      </enterprise-beans>
      </ejb-jar>

      [/pre]



        • 1. Re: Reference/link to local interface in different jar (Jbos
          Kelly Dolan Newbie

          Yes, JBoss supports the EJB 2.0 spec (at least in version 2.4.3). Unfortunately, your problems are arising from some misunderstanding of that spec which is not uncommon...my team has just resolved our understanding of EJB references and how they work after believing much of the same thing you are.

          I'm not going to speak about ejb-local-ref. I have not used this element so I could not be 100% sure of exactly what it's for and when it should be used. Therefore, my comments only apply to the ejb-ref element in the ejb-jar.xml file.

          (1) The ejb-link element only works if (a) the ejb to which it refers is in the same jar file, or (b) the ejb to which it refers is in same ear file (i.e. J2EE application unit) even if it resides in a different jar file (see the 2nd sentence in the spec comment).

          Since you are deploying your ejbs in separate jars but not in the same ear, ejb-link will not work for you. Instead, you have two options. First, deploy them in one ear file. Second, remove the ejb-link reference and resolve the reference in the JBoss specific deployment descriptor (jboss.xml).

          Example of jboss.xml snippet (taken from JBoss documentation):
          <enterprise-beans>

          <ejb-name>Bean A</ejb-name>
          <ejb-ref>
          <ejb-ref-name>ejb/myBean</ejb-ref-name>
          <jndi-name>jnp://otherserver/application/beanB</jndi-name>
          </ejb-ref>

          <enterprise-beans>


          The example value of the jndi-name seems complicated but in your case, since you are deploying both jars on the same server simply as jars, you can leave off "jnp://otherserver/application/" and just provide the name of the bean.

          My thoughts are that this still applies to ejb-local-ref. Again, I'm not 100% sure of what that element exactly is, my gut feeling is that you are telling the container that the ejb being references lives on the same machine running in the same J2EE container. As a result, it could optimize how it calls it and treat the calls locally as opposed to as RMI calls.

          Hope this helps!

          - Kelly

          • 2. Re: Reference/link to local interface in different jar (Jbos
            Oliver Henlich Newbie

            Hi Kelly.

            Cheers for your input. I think i follow you, it's quite clear. I did sort of understand that ejb-link is
            only intended to be used when referencing a bean in the same jar or application unit.

            This is why the following works (deployment descriptor of BeanA):

            [pre]
            <!-- remote reference -->
            <ejb-ref>
            <ejb-ref-name>ejb/refToBeanB</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            BeanBHome
            BeanB
            </ejb-ref>
            [/pre]
            where BeanB is deployed in a seperate jar and the remote reference is resolved in the jboss.xml.

            However if i try exactly the same approach with BeanC (that has a local interface only) and add a
            reference to it in the deployment descriptor of BeanA like:
            [pre]
            <!-- local reference -->
            <ejb-local-ref>
            <ejb-ref-name>ejb/refToBeanC</ejb-ref-name>
            <ejb-ref-type>Session</ejb-ref-type>
            <local-home>BeanCHome</local-home>
            BeanC
            </ejb-local-ref>
            [/pre]
            where BeanC is deployed in a seperate jar and the remote reference is resolved in the jboss.xml.

            Then finally deploy BeanA JBoss gives me a deploy error:
            Lookout for Local references currently require ejb-link

            [pre]
            [Container factory] Begin java:comp/env for EJB: bean_a
            [Container factory] TCL: java.net.URLClassLoader@56182f
            [Container factory] Binding an EJBReference ejb/refToBeanB
            [Container factory] Binding ejb/refToBeanB to external JNDI source: ejb/bean_b
            [Container factory] Binding an EJBLocalReference ejb/refToBeanC
            [Container factory] org.jboss.ejb.DeploymentException: Local references currently require ejb-link
            [Container factory] at org.jboss.ejb.Container.setupEnvironment(Container.java:528)
            [Container factory] at org.jboss.ejb.Container.init(Container.java:356)
            [Container factory] at org.jboss.ejb.StatefulSessionContainer.init(StatefulSessionContainer.java:182)
            [Container factory] at org.jboss.ejb.Application.init(Application.java:202)
            [Container factory] at org.jboss.ejb.ContainerFactory.deploy(ContainerFactory.java:372)
            [Container factory] at org.jboss.ejb.ContainerFactory.deploy(ContainerFactory.java:304)
            [Container factory] at java.lang.reflect.Method.invoke(Native Method)
            [Container factory] at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1628)
            [Container factory] at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1523)
            [Container factory] at org.jboss.deployment.J2eeDeployer.startModules(J2eeDeployer.java:494)
            [Container factory] at org.jboss.deployment.J2eeDeployer.startApplication(J2eeDeployer.java:468)
            [Container factory] at org.jboss.deployment.J2eeDeployer.deploy(J2eeDeployer.java:208)
            [Container factory] at java.lang.reflect.Method.invoke(Native Method)
            [Container factory] at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1628)
            [Container factory] at com.sun.management.jmx.MBeanServerImpl.invoke(MBeanServerImpl.java:1523)
            [Container factory] at org.jboss.ejb.AutoDeployer.deploy(AutoDeployer.java:379)
            [Container factory] at org.jboss.ejb.AutoDeployer.run(AutoDeployer.java:217)
            [Container factory] at java.lang.Thread.run(Thread.java:484)
            [J2EE Deployer Default] Starting beanA.jar failed!
            [/pre]

            So, does this mean that local references are only supported when the bean being referenced (BeanC) is in
            the same jar file as the referencing bean (BeanA)?

            Was this always how local interfaces where designed to be used (ie. in the same jar)?
            But then why does jboss say currently.

            Any ideas would be greatly appreciated.
            I think this discussion will clear things up for a few other people aswell.

            cheers
            oliver
            www.pogo-tech.com

            • 3. Re: Reference/link to local interface in different jar (Jbos
              Andreas Schouten Newbie

              Hi Oliver,

              I used local references only between beans within one jar.

              Maybe You will find the information You need in this discussion thread

              http://www.mail-archive.com/jboss-development@lists.sourceforge.net/msg06934.html//www.mail-archive.com/jboss-development@lists.sourceforge.net/msg06934.html

              Andreas

              • 4. Re: Reference/link to local interface in different jar (Jbos
                Marcus Brito Novice

                What's the current status for this problem? Does JBoss (2.4.x or 3.0-alpha) support the # notation in ejb-link? I'm currently developing an application where this feature would be very welcome.

                Here's why: An EJB-JAR can have only one data source. I need to develop a new entity bean that depends on legacy data. So the new bean will be persisted in a database but the legacy data is stored in another. So both beans (the one representing legacy data and the new one) can't be in the same JAR.

                • 5. Re: Reference/link to local interface in different jar (Jbos
                  Vincent Harcq Newbie

                  Oliver/Jardia (?)

                  I was asking myself the same question recently.
                  In Container.setupEnvironment the search for ejb-link is made in the Application (the ejb jar) by name lookup on all deployed beans.
                  So no lookup outside the ejb-jar. No "#" tokenizer,...
                  You should post a bug report on sourceforge