490 likes | 651 Views
OSGi and Spring Dynamic Module. وحید شیخعلی زاده فرشاد زینالی استاد راهنما:مهندس امیرسام بهادر بهار۹۲. SpringDm. SpringDm یک فریم ورک جدید است که در واقع استفاده از مدل برنامه نویسی قدرتمندِ Spring در بستر فریم ورک OSGi میباشد .
E N D
OSGi and Spring Dynamic Module وحید شیخعلی زاده فرشاد زینالی استاد راهنما:مهندس امیرسام بهادر بهار۹۲
SpringDm • SpringDmیک فریم ورک جدید است که در واقع استفاده از مدل برنامه نویسی قدرتمندِ Springدر بستر فریم ورک OSGiمیباشد. • همانطور که از تعریف هم بر میاید برای شناخت هرچه بهتره این فریم ورک ابتدا نیاز است بدانیم OSGi چیست. • به همین منظور در ادامه با فریم ورک OSGi آشنا میشویم و علل ظهور این فریم ورک را برسی میکنیم.
OSGi • فریم ورک OSGi توسط شرکت OSGi Alliance پایه گذاری شد تا بتواند علاوه بر پشتیبانی از مدل برنامه نویسی سرویس گرا (SOP) ،قابلیت برنامه نویسی ماژوله را به زبان جاوا اضافه کند. • علی رغم موفقیت چشم گیرِ زبان برنامه نویسی جاوا ،از برنامه برای تلفنهای همراه گرفته تا سازمانهای بسیار بزرگ،این زبان به صورت خاص از مدل برنامه نویسی ماژوله پشتیبانی نمیکند. • OSGi پلتفرم استانداردی است که ارائه شده است تا بتواند این خلأ را در زبان برنامه نویسی جاوا پوشش دهد.
Java limitation • جاوا نوع محدودی از modularityرا پشتیبانی میکند که همان object-oriented است که این مدل ایرادهای زیر را دارد: • ۱.محدودیت در کنترلِ دسترسی(code visibility): اگرچه جاوا قابلیت دسترسی رابرای ما فراهم میکند(public,private,protected) اما این قابلیت تنها capsulationسطح پایین OOرا پاسخگو است. • ۲.مشکل دیگر مفهومی به نام classloader میباشد:برنامهها به یک سری library نیاز دارند ولی classloader توجهی به ویژگیهای این لایبرریها از جمله ورژنِ آنها نمیکند.در این شرایط راه حل آزمون و خطا میباشد که تا با انتخاب ورژنِ درست،JVM دیگر پیغام خطا به ما ندهد.
OSGi Solution • OSGi میتواند در موارد زیر این مشکلات را حل کند: • ۱.Class Not Found Exception: • OSGi این اطمینان را به شما میدهد که تا زمانی که وابستگی کدها برطرف نشده برنامه اجرا نشود. • ۲.Execution-Time Error: • به دلیلِ ورژنِ اشتباه library در classpath • ۳.قابلیت اعمال تغییرات در برنامه به صورت Dynamic • ۴.امکان توسعه برنامه به صورت موازی • ۵.استفاده مجدد از کدهای نوشته شده(reusability) • ۶.Real-time developement
Container • برای پیاده سازی برنامههای مبتنی بر ,OSGi ۳ container معروف وجود دارد: • ۱.equinox(Eclipse) • ۲.Apache Felix • ۳.Knopflerfish
Bundle • -واحد سازند در OSGi: • واحد سازند درOSGi bundle , میباشد.bundle در واقع همان jar فایلهای ما هستند که علاوه بر محتویات jar فایل استاندارد دارای پوشهٔ META-INFمیباشند که محتویات این پوشه فایل MANIFEST.MF است و اطلاعات مربوط بهآن jar فایل را دارا میباشد.
Bundle اجزای سازنده : .class Resources MANIFEST.MF
OSGiLayers • OSGi و معماری لایه ی: • OSGi از ۳ لایه مفهومی تشکیل شده است و هر کدام از این لایهها قابلیتی را به برنامهٔ ما اضافه میکنند. • نکته:مانند سایر مدلهای لایه لایه اینجا نیز • هر لایه به لایه زیرین خود وابسته است.
Module • Module: وظیفه ی بستهبندی (packaging) و همچنین به اشتراک گذاری کدها مربوط به این لایه میباشد(code visibility)
MANIFEST.MF به ۳ دسته تقسیم میشود: manifest.mf اطلاعات فایل .human-readable information.1 . bundle identification.2 .code visibility.3
Import and Export • هایی دیده شوند؟ package چه • هایی مورد نیاز است؟package چه • پاسخ بهینه به این ۲ سال
Lifecycle • Lifecycle: این لایه در واقع همان چرخه حیاط bundle میباشد و مدیریت bundle را در زمان اجرا بر عهد دارد (internal to application) • وعملیات شامل نصب bundle در OSGi ،start، stop ،update و uninstall آن (external to application).
Lifecycle • install: bundle درون container OSGi با استفاده از دستور • Install file :< directory> نصب میشود و یک Id واحد به آن اختصاص دادهمیشود. • Resolve: پس از نصب bundle ، هنگامی که همهٔ وابستگیهای آن رفع شد باندل به صورت خودکار در وضعیت resolve قرار میگیرد. • start: پس از اینکه وابستگیهای bundle برطرف شد میتوان آن را با دستور start <id>راهاندازی کرد. • Active: bundle شروع به کار کرده و هم اکنون در حال اجرا است. • Stop: دستوری است که صادر میشود و باندل مورد نظر را متوقف میکنیم.
Lifecycle API • -۳interface که در واقع روح اصلی لایه lifecycle را تشکیل میدهند: • ۱.BundleActivator: • با implement کردن این interface میتوان با osgi framework تعامل کرد.در واقع وقتی bundle نصب شده و متد start() این اینترفیس فراخوانی میشود ،فریم ورک ۱ instance از این کلاس میسازد.در واقع متدهای start() و()stop روی یک instance یکسان از آن کلاس اجرا میشوند. public void start(BundleContext context) throws Exception; public void stop(BundleContext context) throws Exception;
Lifecycle API • ۲.BundleContext: • متدهای این interface به ۲ دست تقسیم میشوند: • ۱.مدیریت چرخه حیاط bundle ها(lifecycle management) • ۲.تعامل با سرویس ها. • در واقع object ,BundleContext جاری bundle است. از طریق این اینترفیس میتوان به سرویس رجیستری دسترسی پیدا کرد. void addBundleListener(BundleListener listener); void removeBundleListener(BundleListener listener); void addFrameworkListener(FrameworkListener listener); void removeFrameworkListener(FrameworkListener listener);
Lifecycle API • ۳.Bundle: • برای هر bundle نصب شده framework یک bundle Object ایجاد میکند تا از لحاظ logical آنbundle را بیان کند.در واقع framework هر bundle را بر اساس bundle Object ایجاد شده میشناسد. • نکته جالب این است کهOSGi در زمان اجرا خود به صورت bundle است. (system bundle) long getBundleId(); Dictionary getHeaders(); Dictionary getHeaders(String locale); String getLocation(); int getState(); String getSymbolicName();
services • کاری که برای دیگری انجام میشود. • وظیفه این لایه تامل و ارتباط میان bundleها است،اینگونه که A سرویس X را رجیستر میکند و B سرویس X را مصرف میکند • با استفاده از مدل برنامه نویسی بر پایهٔ interface ها،وابستگی میان سرویس دهنده و سرویس گیرنده از بین میرود
services • مزایای برنامه نویسی سرویس گرا: ۱.وابستگی کمتر قطعه کد ها ۲.برنامه نویسی با interface ها. ۳.metadata اضافه(Filter) ۴.چند پیاده سازی
Listening for Services • osgi از یک ListenerAPI برای مدیریت Eventها استفاده میکند. • ۳ مدل Event داریم: • ۱.registered: سرویس رجیستر شده و میتوان از آن استفاده کرد • ۲.modified : سرویس metaData تغییر کرده است. • ۳.unregistering: سرویس در حال unregister شدن است.
Details • هر کلاس listener باید interface serviceListener را implement کند. • هر interface میتواند چند پیاده سازی داشتهباشد.نکتهٔ جالب در این بارهاین است که بر اساس metaData بدست آماده میتوان روی پیاده سازیها عمل filtering انجام داد.چنین قابلیتی در فریم ورک های وجود ندارد و صرفا از روی پیاده سازی می توان فیلتر کرد نه عملکرد! • ServiceRegistration registration = bundleContext.registerService(serviceName, newIMP(), metadata); Dictionary metadata =new Properties(); Metadata.setProperties(key,value);
Enterprise OSGi • مزایایی که E-OSGiمیتواند بهweb application بیاورد: • لایهٔ module ساختار بندی physicalو logicalبهتری برایweb app ها میاورد. • لایهٔ lifecycleاین قابلیت را ایجاد میکند که بتوان مدیریت دینامیک روی web appداشته باشیم. • لایهٔ serviceوابستگی کمتر بین بخشهای مختلف و امکان استفاده آنها در سایر پروژه هافراهم میکند.
WAB • warفایلی است که از metadata osgi پشتیبانی میکند و به لایهٔ lifecycle فریم ورک osgi برای دسترسی به منابعش نیازمند است.
Apache Aries • یکی از Application Server هایی است که از EO پشتیبانی میکند و هم یک web server است و هم یک servlet containerو این قابلیت را دارد که به سادگی با سایر فریم ورکها آمیخته شود. (websocket،osgi،JMX،JNDI،Clustering،...) • روند کار اینگونه است که WebContainer درون پوشهٔ WEB-INF/web.xml را میگردد تا ببیند چه سرولتهایی توسط باندل فراهم شده و OSGiContainer درون پوشهٔ META-INF/MANIFEST.MF به دنبال اطلاعات مربوط به خود باندل میگردد.
معرفی Spring dynamic module • Spring DM ترکیبی از Spring و OSGI است • Spring DM مدل برنامه نویسی Spring در برنامه های تحت OSGI می باشد • Spring DM یک راه حل بر مبنای ماژول بندی کردن برنامه پیشنهاد می دهد که به وسیله آن می توانیم از تمام ویژگی های OSGI در قالب Spring استفاده کنیم . • در واقع هدف اصلی Spring DM این است که OSGI و Spring بتوانند به ساده ترین شکل با هم در تعامل باشند تا به این شکل بتوانند ضعف های همدیگر را پوشش دهند. • Spring DM دارای یک extender می باشد که وظیفه ی extender این است که با بررسی شرایط OSGI Bundle ها به آنها به صورت اختصاصی یک Spring application context بدهد که با این کار OSGI Bundleها به Spring powered bundle تغییر نوع می هند ( در این رابطه به صورت مفصل تر در قسمت های آتی صحبت خواهد شد )
چرا Spring dynamic module • با تمام فواید و مزایایی که Spring Framework به همراه دارد از جمله IOC و AOP بودن ، اما Spring مشکلاتی هم دارد از جمله : • زمانی بر روی پروژه های بزرگ و پیچیده کار می کنیم به تعداد خیلی زیادی Bean نیاز داریم که config و مدیریت کردن آنها بسیار مشکل است. • Spring توانایی module بندی کردن برنامه را ندارد . برای مثال هیچ روشی برای اینکه Visiility ، Beanها را کنترل کرد وجود ندارد و هر Bean توانایی مشاهده ی سایر beanها را دارد . حتی اگر به صورت مستقیم هم از beanها استفاده نکنیم با استفاده از Spring application context می توانیم به دنبال bean مورد نظر باشیم.
ادامه • configure کردن مجدد dependency graph برای وابستگی های اعمال شده (dependency injection) : مشکل سوم به وابستگی هایی که بین beanها وجود دارد بر می گردد برای مثال : فرض کنید bean A از bean B استفاده می کند در این صورت A به B وابستگی پیدا می کند . حال زمانی را فرض کنید که برنامه ما دارای چند صد bean باشد و بین آنها وابستگی وجود داشته باشد که در dependency graph مشخص شده باشد ، حال اگر برنامه در حال اجرا باشد و ما بین beanها وابستگی های جدیدی به وجود آوریم ، این وابستگی ها تا زمانی که تمام برنامه یک بار restart نشود اعمال نخواهد شد و دلیل آن این است که مشخص شدن وابستگی بین beanها فقط یکبار صورت می گیرد و آن هم در زمان start up شدن spring container است و امکان update وابستگی ها در حین اجرا وجود ندارد . و مدیریت dependencyها تماما به وسیله ی Spring انجام می شود و developer نمی تواند مدیریت را خود کنترل نمایید .
ادامه • در این حال OSGI هم دارای کمبود هایی بود ، از جمله : • دارای قابلیت IOC و AOP نمی باشد • به خاطر همین کمبود ها تکنولوژی جدیدی به نام Spring DM به وجود آمد • با استفاده از spring dm شما می توانید از تمام ویژگی ها و قدرت فریم ورک spring در برنامه های تحت استفاده ی osgi بهره ببرید. • Spring dm توانایی این را دارد که تمام bundleها را شناسایی کند و به صورت کاملا مدیریت شده برای هر کدام از آنها یک spring application context اختصاصی ایجاد کند
ادامه • spring dm یک نوع خاصی از bundleها را معرفی می کند به نام : Spring powered bundles • Spring powered bundle: این نوع از bundleها توانایی این را دارند که به صورت اتوماتیک یک spring application context اختصاصی داشته باشند که تماما توسط spring dm مدیریت می شوند و می توانند از تمام ویژگی های spring استفاده کنند • Spring powered bundleها همانند osgi bundleها می توانند packageهای مورد نیاز خود را import و export کنند • Spring powered bundleها از spring container و توانایی های spring dm استفاده می کند تا با osgi container در ارتباط باشند ، و این تعامل می تواند به دو روش باشد : 1) xml base 2) annotation base
ادامه • در مبحث osgi با استفاده از یک ActivatorBundle، باندل خود را تعریف ، مقدار دهی اولیه و service ثبت کرده و یا از service ها استفاده کنیم. • Spring powered bundle درون خود شامل یک instance از spring container می باشد ، که با استفاده از این container می توانیم از ویژگی های IOC و AOP استفاده کنیم و دیگر نیازی به Bundle Activator نمی باشد زیرا spring container به صورت اتوماتیک توسط spring dm فراخوانی می شود.
Spring DM’s extender mechanisms • Spring DM یک extender bundle به وجود می آورد که وظیفه آن گوش دادن به bundleهایی است که می خواهند بر روی osgi container نصب شوند ، اگر این bundleها دارای شرایط لازم بودند ، extender آنها را به spring powered bundle تبدیل می کند . و برای هر کدام به صورت اختصاصی یک spring application context ایجاد می کند. • سوال : spring extender چگونه تصمیم می گیرد که کدام bundle باید به spring powered bundle تبدیل شود ؟ برای اینکه یک bundle بتواند به spring powered bundle تبدیل شود باید شامل 2 ویژگی باشد : • باید دارای دایرکتوری META-INF/spring باشد که داخل دایرکتوری spring باید یک فایل xml برای configure کردن spring داشته باشد • در داخل فایل MANIFEST.MF واقع در دایرکتوری META-INF دارای یک header به نام Spring-Context باشد ، که در واقع مقدار این header مشخص کننده محل فایلی است که spring را configure خواهد کرد
Kinds of supported bundles • Spring DM 2 نوع bundle را ساپورت می کند : • standard Spring-powered bundles • web bundles • در اسلایدهای قبلی ما با یک نوع از spring extender bundle آشنا شدیم که در واقع تنها برای standard Spring-powered bundles مورد استفاده قرار می گیرد ، اما نوع دیگری از extender ها وجود دارند که از آنها برای web bundleها استفاده می شوند که اصطلاحا به آنها می گویند web extender ، که از web extender برای پیاده سازی bundleها در سمت web applicationها استفاده می شود.
Kinds of supported bundles • Spring DM 2 نوع bundle را ساپورت می کند : • standard Spring-powered bundles • web bundles • در اسلایدهای قبلی ما با یک نوع از spring extender bundle آشنا شدیم که در واقع تنها برای standard Spring-powered bundles مورد استفاده قرار می گیرد ، اما نوع دیگری از extender ها وجود دارند که از آنها برای web bundleها استفاده می شوند که اصطلاحا به آنها می گویند web extender ، که از web extender برای پیاده سازی bundleها در سمت web applicationها استفاده می شود.
Equinox container for web • Spring DM از version 1.1 به بعد ، پیاده سازی web applicationها بر روی محیط OSGI را ساپورت می کند. • پیاده سازی web applicationها نسبت به desktop applicationها تا حدودی متفاوت است و نیازمند یک web container می باشد. • در واقع spring dm مشابه پلی عمل می کند میان osgi container و web container • در سمت web ، spring dm از web extender استفاده می کند تا به وسیله ی آن web bundleها را شناسایی و نصب کند • Spring DM در سمت web از 2 ، web container ساپورت می کند : • Apache Tomcat از ورژن 5.5 به بعد • Jetty • Tomcat is the default container in Spring DM
Packaging a web bundle • در سمت web applicationها برای استفاده از web bundle بر روی web container نیازمند 2 مرحله هستیم : • Deploy کردن web bundle بر روی osgi container همانند یک bundle معمولی • واسط قرار گرفتن spring dm web extender برای توانایی برقراری ارتباط بین osgi container و web container • برای اینکه spring dm web extender بتواند bundle را بر روی web container ، deploy کند ، bundle مورد نظر باید دارای 2 ویژگی باشد : • پسوند فایل.war باشد • فایل شامل دایرکتوری WEB-INF باشد • که در این مقاله bundleهای ما دارای شرط دوم می باشند
Spring DM standard extendermechanisms • یکی از وظایف اصلی Spring dm standard extender گوش دادن به bundleهایی است که می خواهند بر روی osgi container قرار بگیرند تا در صورت داشتن شرایط لازم extender آنها را به powered bundle تبدیل کند • Extender علاوه بر bundleهایی که می خواهند بر روی container نصب شوند به spring powered bundleهایی که بر روی osgi container نصب هستند و یا حتی در حالت active نیز می باشند گوش می دهد و شرایط آنها را مرتبا بررسی می کند • از دیدگاه osgi container هیچ تفاوتی میان osgi bundle و standard powered bundle وجود ندارد زیرا هر دو از packageهای یکسانی استفاده می کنند و هر دو jar فایل هایی هستند که دارای دایرکتوری META-INF/MANIFEST.MF می باشند .
ادامه • از ویژگی های powered bundle داشتن 2 چیز است : • META-INF/spring که شامل یک فایل xml است • Spring-Context manifest header • Spring extender ابتدا META-INF/spring را چک می کند اگر شامل فایل xml بود از آن فایل برای configure کردن spring استفاده می کند ، اما اگر فایل xml مربوط به configure کردن spring نباشد extender از آن نمی تواند استفاده بکند و exception خواهد داد . • اولویت با Spring-Context manifest header است
HOW SPRING DM CREATES APPLICATION CONTEXTS • Spring powered bundle هیچگونه نگرانی در رابطه با create و یا destroy کردن spring application context ندارد و این کار جزو وظایف spring extender می باشد • Spring dm extender جزو اولین bundleهایی است که به حالت active می رود ، به این دلیل که باید در حالت active باشد تا بتواند سایر bundleها را شناسایی کند و به آنها spring application context اختصاص دهد • Spring dm extender توانایی این را دارد که bundleهایی که قبل خودش در container نصب شده اند را شناسایی کند و به آنها در صورت لزوم spring application context اختصاص دهد
ادامه • Usually, Spring-powered bundles are deployed after the Spring extender. • Spring extender تلاش می کند تا spring application context را به bundleهایی اختصاص دهد که در حالت active هستند • پس روال کار به این ترتیب است : • Spring extender در حالت active • Osgi bundle در حالت active • اختصاص spring application context به bundle • تمام مراحل بالا Tread base انجام می شوند