-
1. Re: EJB local refs and links
vashistvishal Jul 8, 2003 7:49 PM (in response to mkerry)My understanding is you will need this tag to refer to other jar in same JVM.
@ejb.ejb-external-ref (0..*)
Please have a look at the the following lonk on Xdoclet as this will generate DD for you.
http://xdoclet.sourceforge.net/tags/ejb-tags.html#@ejb.ejb-external-ref%20(0..*)
Also on Xdoclet you might want to look at @jboss tags as well.
But this should solve yr problem of referencing in two jars.
Cheers.........
Vishal -
2. Re: EJB local refs and links
jonlee Jul 8, 2003 8:16 PM (in response to mkerry)If you are not using XDoclet, or just need to understand the referencing, try this as an example where we have a stateless session bean trying to access another EJB for logging:
<display-name>Cards</display-name>
Cards
<ejb-name>Cards</ejb-name>
com.amity.cards.CardsHome
com.amity.cards.Cards
<local-home>com.amity.cards.CardsLocalHome</local-home>
com.amity.cards.CardsLocal
<ejb-class>com.amity.cards.CardsBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<ejb-local-ref>
<ejb-ref-name>LocalEventLogger</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>com.amity.eventlogger.EventLoggerLocalHome</local-home>
com.amity.eventlogger.EventLoggerLocal
<ejb-link>EventLogger</ejb-link>
</ejb-local-ref>
Your corresponding jboss.xml would contain the resource definition and the res-name map back to the ejb-link.
<?xml version="1.0"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS//EN" "http://www.jboss.org/j2ee/dtd/jboss.dtd">
<resource-managers>
<resource-manager>
<res-name>EventLogger</res-name>
<res-jndi-name>EventLogger</res-jndi-name>
</resource-manager>
</resource-managers>
<enterprise-beans>
<ejb-name>Cards</ejb-name>
<jndi-name>Cards</jndi-name>
<local-jndi-name>CardsLocal</local-jndi-name>
<configuration-name>Standard Stateless SessionBean</configuration-name>
<ejb-local-ref>
<ejb-ref-name>EventLogger</ejb-ref-name>
<local-jndi-name>EventLoggerLocal</local-jndi-name>
</ejb-local-ref>
false
</enterprise-beans>
You can use the local-jndi-name as your lookup point. You should be able to follow the XDoclet generation from this I hope. -
3. Re: EJB local refs and links
mkerry Jul 8, 2003 11:36 PM (in response to mkerry)Thanks for the replies.
Unfortunately, I am no longer using XDoclet (I was originally, but changed to JBuilder to conform to the dev environment...).
Here are some followup questions:
For Vishal's response (using the @ejb-external-ref XDoclet tag), the XDoclet docs explicitly say that this tag will work for referencing beans across jar files. Will it work if the bean that is being referenced only has local interfaces? Will it generate a DD similar to jonlee's?
For jonlee's response, were your two beans in different jar files (Cards in one, LocalEventLogger in the other)?
If so, then I can conclude that I need to have these tags in order to make the reference work; however, it works (somewhat) when I don't have them. Am I "getting lucky" somehow? Why would it sometimes work and sometimes not? (Mostly, I just want to understand what is happening here...)
Finally, does anyone know JBuilder9 well enough to tell me how to generate the <ejb-local-ref> with the <ejb-link> tags when the beans are in different jars? (it works fine to check the isLink box when they are in the same jar, but I don't see a way to point it to look for beans in other jars that will be deployed in the same App Server). I have asked the question on a JBuilder newsgroup but have yet to get a response.
Thanks again for the help! -
4. Re: EJB local refs and links
vashistvishal Jul 9, 2003 1:25 AM (in response to mkerry)Yes you can get thta both for local and remote interfaces, as it specifies in tag options.
@ejb.ejb-external-ref
view-type="local"
link="XXXXXXXXXXXX"
type="XXXX/Session/Entity/"
ref-name="XXXXXXXXXXXXXX"
home="XXXXXX"
local="XXXXXXXXXX"
thes are the options specified under this tag at Xdoclet doc's.
This will work and this is a class level tag.
I hope this clarifies it. -
5. Re: EJB local refs and links
jonlee Jul 10, 2003 4:18 PM (in response to mkerry)Yes they are separately packaged jars. You are probably getting lucky with the calls. However, being explicit with the definition allows the container to easily determine the reference to the local interface - particularly if you have a remote interface available as well on the EJB.
We build this way as single EJBs during development as it gives us a bit more flexibility to chop and change individual EJBs. We repackage for production when the sub-systems are stable.
Hope that answers my part. -
6. Re: EJB local refs and links
mkerry Jul 10, 2003 10:25 PM (in response to mkerry)OK, thanks again. But I fear I am still struggling...
I wrote a little toy to try this out, using XDoclet so that we can speak the same language; and it didn't work.
I have three beans, all stateless session beans. One (CallerBean) has methods that call the other two beans (Bean1 and Bean2). Both Bean1 and Bean2 are written with only local interfaces. Bean1 is packaged in the same jarfile as CallerBean (jar1), whereas Bean2 is packaged in a different jar by itself (jar2). I should also note that Bean2 is in a different java package from Bean1 and CallerBean. Does that matter? (Bean1 and CallerBean are in testLocal.ejb, whereas Bean2 is in testLocal2.ejb).
When I try to deploy jar1 (containing CallerBean's attempted local-refs to Bean1 and Bean2) I get a deployment error from JBoss:
org.jboss.deployment.DeploymentException: Bean Bean2 not found within this application.
When I comment out all references to Bean2 in CallerBean (leaving in the local refs and calls to Bean1), it deploys and runs fine.
The XDoclet I used in the CallerBean is as follows:
/**
* @ejb.bean
* name="CallerBean"
* type="Stateless"
* jndi-name="ejb/CallerBean"
* display-name="CallerBean"
*
* @ejb.interface
* remote-class="testLocal.interfaces.CallerBean"
*
* @ejb.home
* remote-class="testLocal.interfaces.CallerBeanHome"
*
* @ejb.ejb-external-ref
* view-type="local"
* link="Bean1"
* ref-name="ejb/Bean1Local"
* type="Stateless"
* home="testLocal.Bean1LocalHome"
* business="testLocal.Bean1Local"
*
* @ejb.ejb-external-ref
* view-type="local"
* link="Bean2"
* ref-name="ejb/Bean2Local"
* type="Stateless"
* home="testLocal2.Bean2LocalHome"
* business="testLocal2.Bean2Local"
*/
What am I missing? -
7. Re: EJB local refs and links
vashistvishal Jul 11, 2003 1:08 AM (in response to mkerry)First of all what i understand is this
Yr CallerBean and Bean1 are in same jar file say jar-1.
And Bena2 is in different jar file say jar-2.
Now @ejb. @ejb.ejb-external-ref is used to look for beans in different jars.
That means in order to invoke methods on Bean2 (which is in jar-2) by CallerBean you use this tag.
Now in case of CallerBean invoking methods on Bean 1 which are in same jar that is jar-1 you dont use this tag.
You have to use this tag.
@ejb.ejb-ref ejb-name="Bean1"
view-type="local"
ref-name="Bean1Local"
Assuming yr lookup string bean is
"java:comp/env/ejb/Bean1Local"
Now in addition to that you need tags for jboss.
@jboss.ejb-ref-jndi ref-name="Bean1Local"
jndi-name="Bean1Local"
And in case of bean 2.
@jboss.ejb-ref-jndi
ref-name="Bean2Local"
jndi-name="Bean2Local"
Now, This tag for bean2, (I am not sure about that, but my understanding is you need that as in case of Bean1), but do check Xdoclet doc for this tag.
Now, a tricky bit, which I am glad somebody raised it, when you use
@jboss.ejb-ref-jndi, it raises
wrong descriptors in jboss.xml file in case of bean with local interface not with remote one.
<ejb-name>CallrBean</ejb-name>
<jndi-name>CallerBean</jndi-name>
<local-jndi-name>CallerBeanLocal</local-jndi-name>
<ejb-ref> --------------------------
<ejb-ref-name>ejb/Bean1Local</ejb-ref-name>
<jndi-name>Bean1Local</jndi-name>
</ejb-ref>-------------------------------
this is where it gets wrong.
it should be
<ejb-local-ref> -------
<ejb-ref-name>ejb/Bean1Local</ejb-ref-name>
<jndi-name>Bean1Local</jndi-name>
</ejb-local-ref> -------------------
So you have to change it manually.
I hope all this will help you, if you still cant' do that just post yr whole project I wil have a look at it. -
8. Re: EJB local refs and links
mkerry Jul 11, 2003 3:19 PM (in response to mkerry)OK, I have attached my code, since I am still unable to make your suggestion work.
A couple of things:
1) Thanks for pointing out the @ejb-ref vs @ejb-external-ref problem; although, I noticed that they in fact seem to generate the same deployment descriptor in this case.
2) Also, thanks for the @jboss tags point; I had missed that. Oddly, it was working even without those tags in the Bean1 case, and it is still failing for me in the Bean2 case with them.
3) I never would have noticed that XDoclet was not creating the @jboss tags correctly...thanks.
I have cut-n-pasted (Attach Files didn't work for me) 4 java files (CallerBean.java, Bean1.java, Bean2.java and Driver.java) and the resulting deployment descriptors for jar1.jar.
As noted before, CallerBean and Bean1 are packaged into one jar file (jar1.jar), whereas Bean2 is packaged separately (jar2.jar). Driver is the main program that excercises the beans.
The problem is, jar1.jar fails to deploy. If I comment out all references to Bean2 in CallerBean, it deploys and runs fine. I have tried this on RedHat 7.3 with jboss 3.0.6 (tomcat bundle) as well as on Win2000 with jboss 3.0.7 (also tomcat bundle), and jdk1.4 in both cases.
Thanks for taking the time to have a look!
CallerBean.java
--------------------
package testLocal.ejb;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import testLocal.interfaces.*;
/**
* CallerBean.java
*
* @ejb.bean
* name="CallerBean"
* type="Stateless"
* jndi-name="ejb/CallerBean"
* display-name="CallerBean"
*
* @ejb.interface
* remote-class="testLocal.interfaces.CallerBean"
*
* @ejb.home
* remote-class="testLocal.interfaces.CallerBeanHome"
*
* @ejb.ejb-ref
* view-type="local"
* ejb-name="Bean1"
* ref-name="Bean1Local"
*
* @jboss.ejb-ref-jndi
* ref-name="Bean1Local"
* jndi-name="Bean1Local"
*
* @ejb.ejb-external-ref
* view-type="local"
* link="Bean2"
* ref-name="Bean2Local"
* type="Session"
* home="testLocal2.interfaces.Bean2LocalHome"
* local="testLocal2.interfaces.Bean2Local"
*
* @jboss.ejb-ref-jndi
* ref-name="Bean2Local"
* jndi-name="Bean2Local"
*
* @version 1.0
*/
public class CallerBean implements SessionBean {
private SessionContext ctx;
private Bean1LocalHome bean1LocalHome;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbActivate() throws RemoteException {
}
public void ejbPassivate() throws RemoteException {
}
public void ejbRemove() throws RemoteException {
}
/**
* @ejb.create-method
*/
public void ejbCreate() {
System.out.println("CallerBean.ejbCreat()");
try {
InitialContext initCtx = new InitialContext();
Object o = initCtx.lookup("java:comp/env/ejb/Bean1Local");
this.bean1LocalHome =
(Bean1LocalHome)PortableRemoteObject.narrow(o, Bean1LocalHome.class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* @ejb.interface-method view-type="remote"
*/
public void callBean1() {
System.out.println("CallerBean.callBean1");
try {
Bean1Local bean1 = this.bean1LocalHome.create();
bean1.showMessage("Local call to Bean1 from CallerBean...");
bean1.remove();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Bean1.java
--------------
package testLocal.ejb;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
/**
* Bean1.java
*
* @ejb.bean
* name="Bean1"
* type="Stateless"
* view-type="local"
* local-jndi-name="Bean1Local"
* display-name="Test Bean 1"
*
* @ejb.interface
* local-class="testLocal.interfaces.Bean1Local"
*
* @ejb.home
* local-class="testLocal.interfaces.Bean1LocalHome"
*
* @version 1.0
*/
public class Bean1 implements SessionBean {
private SessionContext ctx;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbActivate() throws RemoteException {
}
public void ejbPassivate() throws RemoteException {
}
public void ejbRemove() throws RemoteException {
}
/**
* @ejb.create-method
*/
public void ejbCreate() {
System.out.println("Bean1.ejbCreat()");
}
/**
* @ejb.interface-method view-type="local"
*/
public void showMessage(String msg) {
System.out.println("Bean1.showMessage: msg = " + msg);
}
}
Bean2.java
--------------
package testLocal2.ejb;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
/**
* Bean2.java
*
* @ejb.bean
* name="Bean2"
* type="Stateless"
* view-type="local"
* local-jndi-name="Bean2Local"
* display-name="Test Bean 1"
*
* @ejb.interface
* local-class="testLocal2.interfaces.Bean2Local"
*
* @ejb.home
* local-class="testLocal2.interfaces.Bean2LocalHome"
*
* @version 1.0
*/
public class Bean2 implements SessionBean {
private SessionContext ctx;
public void setSessionContext(SessionContext ctx) {
this.ctx = ctx;
}
public void ejbActivate() throws RemoteException {
}
public void ejbPassivate() throws RemoteException {
}
public void ejbRemove() throws RemoteException {
}
/**
* @ejb.create-method
*/
public void ejbCreate() {
System.out.println("Bean2.ejbCreat()");
}
/**
* @ejb.interface-method view-type="local"
*/
public void showMessage(String msg) {
System.out.println("Bean2.showMessage: msg = " + msg);
}
}
Driver.java
--------------
package testLocal;
import javax.naming.*;
import javax.ejb.*;
import javax.rmi.*;
import testLocal.interfaces.*;
public class Driver {
public Driver() {
}
public static void main(String [] args) {
InitialContext ctx;
try {
ctx = new InitialContext();
CallerBeanHome callerHome = (CallerBeanHome)PortableRemoteObject.narrow(ctx.lookup("ejb/CallerBean"), CallerBeanHome.class);
CallerBean callerBean = callerHome.create();
System.out.println("Calling bean1 method...");
callerBean.callBean1();
callerBean.remove();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
ejb-jar.xml
------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar >
<![CDATA[No Description.]]>
<display-name>Generated by XDoclet</display-name>
<enterprise-beans>
<!-- Session Beans -->
<![CDATA[Bean1.java]]>
<display-name>Test Bean 1</display-name>
<ejb-name>Bean1</ejb-name>
<local-home>testLocal.interfaces.Bean1LocalHome</local-home>
testLocal.interfaces.Bean1Local
<ejb-class>testLocal.ejb.Bean1</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<![CDATA[CallerBean.java]]>
<display-name>CallerBean</display-name>
<ejb-name>CallerBean</ejb-name>
testLocal.interfaces.CallerBeanHome
testLocal.interfaces.CallerBean
<local-home>testLocal.interfaces.CallerBeanLocalHome</local-home>
testLocal.interfaces.CallerBeanLocal
<ejb-class>testLocal.ejb.CallerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-local-ref >
<ejb-ref-name>ejb/Bean2Local</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>testLocal2.interfaces.Bean2LocalHome</local-home>
<ejb-link>Bean2</ejb-link>
</ejb-local-ref>
<ejb-local-ref >
<ejb-ref-name>ejb/Bean1Local</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home>testLocal.interfaces.Bean1LocalHome</local-home>
testLocal.interfaces.Bean1Local
<ejb-link>Bean1</ejb-link>
</ejb-local-ref>
<!--
To add session beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called session-beans.xml that contains
the markup for those beans.
-->
<!-- Entity Beans -->
<!--
To add entity beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called entity-beans.xml that contains
the markup for those beans.
-->
<!-- Message Driven Beans -->
<!--
To add message driven beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called message-driven-beans.xml that contains
the <message-driven></message-driven> markup for those beans.
-->
</enterprise-beans>
<!-- Relationships -->
<!-- Assembly Descriptor -->
<assembly-descriptor >
<!--
To add additional assembly descriptor info here, add a file to your
XDoclet merge directory called assembly-descriptor.xml that contains
the <assembly-descriptor></assembly-descriptor> markup.
-->
<!-- finder permissions -->
<!-- finder permissions -->
<!-- transactions -->
<!-- finder transactions -->
</assembly-descriptor>
<ejb-client-jar>blah.jar</ejb-client-jar>
</ejb-jar>
jboss.xml
---------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd">
<unauthenticated-principal>nobody</unauthenticated-principal>
<enterprise-beans>
<!--
To add beans that you have deployment descriptor info for, add
a file to your XDoclet merge directory called jboss-beans.xml that contains
the , and <message-driven></message-driven>
markup for those beans.
-->
<ejb-name>Bean1</ejb-name>
<local-jndi-name>Bean1Local</local-jndi-name>
<ejb-name>CallerBean</ejb-name>
<jndi-name>ejb/CallerBean</jndi-name>
<local-jndi-name>CallerBeanLocal</local-jndi-name>
<ejb-local-ref>
<ejb-ref-name>ejb/Bean1Local</ejb-ref-name>
<jndi-name>Bean1Local</jndi-name>
</ejb-local-ref>
<ejb-local-ref>
<ejb-ref-name>ejb/Bean2Local</ejb-ref-name>
<jndi-name>Bean2Local</jndi-name>
</ejb-local-ref>
</enterprise-beans>
<resource-managers>
</resource-managers> -
9. Re: EJB local refs and links
mkerry Jul 11, 2003 3:28 PM (in response to mkerry)I just noticed that the version of CallerBean and Driver that I posted don't actually have any java code refering to Bean2; I have another method called callBean2(), analagous to callBean1(), that is used to excercise it (from Driver, just like for Bean1). And, I am doing the Home lookup for Bean2 in the same place as I do for Bean1 (in ejbCreate()).
I can post the real version if you want, but it still has the same deployment error. As long as that @ejb.ejb-external-ref XDoclet is present, the jar file won't deploy for me, whether or not the java code uses Bean2. -
10. Re: EJB local refs and links
imdkidd Jul 14, 2003 5:29 PM (in response to mkerry)My understanding is that when you are referencing beans across different jars they must be packaged together in a EAR in order for it to work. Otherwise, you have to include copies of the stubs of the bean you are referencing.
-
11. Re: EJB local refs and links
mkerry Jul 14, 2003 6:16 PM (in response to mkerry)Yes, indeed, I just discovered that...you beat me to the answer by 30 minutes!
Thanks for replying, though!
My problem, then, is with JBuilder, I think, because it won't generate the same deployment descriptor that XDoclet does (it leaves out the <ejb-link> tag for the bean in the "other" jar file). The strange thing is, the JBuilder descriptor works fine for Weblogic. That is, you don't need the <ejb-link> element for the second bean.
I think I am going to open a new thread to ask about this. -
12. Re: EJB local refs and links
mkerry Jul 14, 2003 6:19 PM (in response to mkerry)Just to be clear, even though I stated in the original question that I had tried packaging the two jars into a single ear, at that time I did not have the correct XDoclet that the others pointed out to me (ejb-external-ref, etc.) to make it all work. The solution was in the combination.
Thanks again for all of the help! -
13. Re: EJB local refs and links
pauster007 Jul 17, 2003 3:21 AM (in response to mkerry)can i take a look at the final composition of your ejb-jar.xml and jboss.xml?
-
14. Re: EJB local refs and links
mkerry Jul 18, 2003 7:51 AM (in response to mkerry)I believe the xml files I posted above were in fact the final versions, just that the two jar files were packaged into a single ear file. I'll check though and re-post if I am wrong.