این عذابی که داری می کشی برای من یادآور خاطرات چند سال پیشم می شه که داستانی بس دراز دارد. اما دیگه منو مجبور کردی که دست به کد بشم و یک مثال خیلی کوچیک برات درست کنم که در آخر کار یک jar فایل به تو می دم که باید اینو بندازیش توی ejb container ت یعنی اینکه deploy کنیش تا واقعا ببینی داستان در عمل چیه.
اما چند نکته که من توی خونه و روی laptopم متاسفانه JBOSS نداشتم ولی با glassfish تست کردم و چون نتیجه کار اساندارد هست پس باید روی هر ejb containerی deploy بشه.
اما در قسمت client باید اینو بهت بگم که داستان jndi properties فرق می کنه یعنی برای jboss یک چیز و برای glassfish چیزه دیگه تعریف شده. ولی اینها مهم نیست مهم اینه که تو بتونی درست deploy کنی همین.
قبل از هر چیز می رم سراغ چند concept مهم توی ejb که می دونم تو بلدی و استاد هستی توش ولی می گم که بدونی دارم درسم رو به تو پس می دم و یک یادآوری بشه برای بقیه استاتید این فروم که بد نیست.
EJB container یک ظرف هست که فقط ejb ها رو می شناسه که کارشون چیه business های خیلی پیچیده رو یا نه ممکنه پیچده هم نباش رو مدیریت می کنه. مثل servlet container که فقط کارش اینه که از servlet ها مراقبت و مدیریت کنه. حالا ما وقتی می خواهیم با servlet صحبت کنیم بایک protocol به نام Http صداشون می کنیم یعنی مثل اینکه می خواهیم توی windows بگیم مثلا c:\myfolder\runme.exe در قسمت آدرس بار یک browser با این ترتیب عمل می کنیم که با protocol ی که Http هست برو به فلان سرور با یک آدرس port و بعد برو فلان servlet یا فرقی نداره فلان jsp که منظور همان servlet هست برو برام بیار.
خوب الان همه کاربرها چه با سواد چه بی سواد این کارهارو انجام می دن اما در اصل پشت ماجرا داستان چیزه دیگست.
داستان در حالت کلی به دوقسمت یا دو concept اصلی تبدیل شده
یک remote
دو address naming
اولی یعنی اینکه با توی windows تو فایل اجرایی رو داری توی کامپیوترت آدرس می دی مثلا و تو وب که داستان این نیست داری از یک کامپیوتر دیگه تقاضا می کنی اینجا به این عمل می کن داری remote می زنی. RMI در جاوا یعنی اینکه از یک JVM با یک JVM دیگه رابطه داشته باشی و بتونی از او JVM هر object ی که بخوای بر داری بیاری توی jvm خودت.
خوب object ها که بدون اسم نمی شن اینجاست که باید بری سراغ اسم object و تقاضا کنی بگی بیا بابا اینجا مثل وب پس بحث JNDI یا java name and directory بوجود می آیاد.
بر گردیم سراغ ejb حالا دقیق این داستانها در ejb هم همینه. اما چه جوری. تو می ری اون object هایی که قرار بقیه از بیرون بیان صداشون کنن رو درست می کنی یکی یک اسمم بهشون می دی می ندازیش توی ejb container یعنی deploy می کنی این container گوش بزنگه کی چی می خواد کی کی می خواد و و و و.
داستان اینه که یک interface درست می کنی که هم باید client و هم server داشته باشه.
بعد توی قسمت server هر کی هر جور که دوست داره می یاد اون interface رو implement می کنه بعد یک اسم هم بهش می ده یکی اسمشو می زاره عنقذی یکی دیگه می زاره babakHelloBeanImpl اما چون همه اون interface اصله کاری رو implement کردن و server مطمعن هست که در قسمت client هم هست پس کافی که چی، به clientها بگه من این interface رو دارم که توام داری تازه این چندتا implement شده هشم داره. حالا client فقط کافی هست که چی کار کنه ؟؟ رفتیم سراغ javaSE بیاد از کلاس دلخواه implement شده به interface موجود در کلاینت چی cast کنه و نتیجه رو بگیره. مام همین کار رو می کنیم.
package myejb;
import javax.ejb.Remote;
/**
*
* @author root
*/
@Remote
public interface HelloRemote {
public String sayHello();
}
package myejb;
import javax.ejb.Stateless;
/**
*
* @author root
*/
@Stateless(mappedName="babakHelloBeanImpl")
public class HelloBean implements HelloRemote {
public String sayHello() {
return "Hello";
}
}
دقت کن یک interface هست که من اومدم implemntش کردم و یک نام بهش دادم که از بیرون هرکی این نام رو صدا کنه به این object دسترسی داره یعنی babaHelloBeanImpl و کسی دیکه می تونه طور دیگه implement کنه ویک نامه دیگه بزاره براش.
داستان به همین راحتی بود . یک jar فایل می دی بیرون و می ندازیش توی container
وقتی میندازیش یعنی deploy می کنی اگر مشکلی نباشه خودت توی console می بینی یک همچین پیعامی برات می نویسه
CORE5024: EJB module [MyEJB] unloaded successfully!
PWC4011: Unable to set request character encoding to UTF-8 from context , because request parameters have already been read, or ServletRequest.getReader() has already been called
deployed with moduleid = MyEJB
**RemoteBusinessJndiName: babakHelloBeanImpl; remoteBusIntf: myejb.HelloRemote
LDR5010: All ejb(s) of [MyEJB] loaded successfully!
خوب حالا jboss بالاست و jar فایلت deploy شده توش و منتظر جواب دادن. می ریم سراغ client که می خواد از این object یا بهتر بگم interface ی که باید یک نسخشم در client باشه ولی نیاز به classهای implement شده نیست وجود داشته باشه.
یک پروژه دیگه در client به این صورت
package clientside;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import myejb.HelloRemote;
/**
*
* @author root
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
Properties properties = new Properties();
System.out.println("befor");
properties.setProperty("java.naming.factory.initia l", "com.sun.enterprise.naming.SerialInitContextFactor y");
properties.setProperty("java.naming.factory.url.pk gs", "com.sun.enterprise.naming");
properties.setProperty("java.naming.factory.state" , "com.sun.corba.ee.impl.presentation.rmi.JNDIStateF actoryImpl");
properties.setProperty("org.omg.CORBA.ORBInitialHo st", "192.168.1.3");
properties.setProperty("org.omg.CORBA.ORBInitialPo rt", "3700");
Context context = new InitialContext(properties);
HelloRemote helloRemote = (HelloRemote) context.lookup("BabakHelloBeanImpl");
String s = helloRemote.sayHello();
System.out.println("Babak says = " + s);
} catch(Exception e) {
e.printStackTrace();
}
}
}
کار تمام.
نکات : در قسمت client تمام propertyی ها مخصوص glassfishهست نه jboss یا web app دیگری
دوم برای اینکه جا نبود من از lib فایلهایی که به classpath در دو پروژه یعنی server side و client side افزوده شده برای نمایش صرفه نظر کردم.
تنظیمات jboss رو از اینترنت بدست بیار
هنگام صدا زدن object باید joboss یا هر web app دیگر حتما run باشه اگر ببندیش یعنی اینکه ejb containerx رو بستی پس ۱۰۰٪ در قسمت client هم جوابی نمی گیری
فقط قسمت ejb بصورت یک jar فایل هست و قابل deploy
قسمت client رو به عهده خودت می زارم با این مثال کد