Banshun - OSGi-less modularity for Spring
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Banshun - OSGi-less modularity for Spring

on

  • 537 views

If you build modular app with Spring by importing children contexts into the parent ones, you face the limitations quite soon. The next step obviously, is approaching overweight OSGi. Isn't there ...

If you build modular app with Spring by importing children contexts into the parent ones, you face the limitations quite soon. The next step obviously, is approaching overweight OSGi. Isn't there something between these two extremes, which powerful enough and still light yet? Sure! Meet Banshun! Easy modularity for Spring.
Banshun allows to instantiate children contexts in a proper order considering declared references between singletons across the contexts.

Statistics

Views

Total Views
537
Views on SlideShare
537
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Banshun - OSGi-less modularity for Spring Presentation Transcript

  • 1. Yet Another One.... Banshun a tiny based Modular Framework http://flic.kr/p/EWNYh
  • 2. Agenda ●Enterprise Applications ●Banshun vs OSGi, EJB ●1, 2, 3 - BOOM! ●Features ...
  • 3. Agenda - Features ●buildtime & runtime app customization ●developer friendliness ○references validation ○cycles resolution ○root cause logging ○fault-tolerance ○dependencies graph ●Spring AOP support
  • 4. Is it your app? :TheService + doBusiness(param) : Result
  • 5. Is it your app? :TheService + doBusiness(param) : Result RDBMS
  • 6. Is it your app? :TheService + doBusiness(param) : Result
  • 7. Is it your app? <bean id="theService" class="com.foo.TheService"> ... </bean> <bean name="/web-service" class="org.spring...HessianServiceExporter"> <property name="service" ref="theService"/> .... </bean> <bean id="/form" class="com....Controller"> </bean>
  • 8. Don't you need to deploy it? :TheService + doBusiness(param) : Result
  • 9. Don't you need to deploy it? :TheService + doBusiness(param) : Result <<EAR>> <<container>>
  • 10. Don't you need to deploy it? :TheService + doBusiness(param) : Result <<WAR>> <<container>>
  • 11. The app becomes big :FooService :ZooService :MooService :FooService :BarService :BazService <<WAR>>
  • 12. The app becomes big <<WAR>> :FooService :BarService :BazService :FooService :BarService :BazService
  • 13. it have to be modular :FooService :BarService :BazService :MooService :ZooService <<component>> :AService :BService :CService :DService :EService <<component>>
  • 14. :FooService :BarService :BazService :MooService :ZooService <<component>> :FooService :BarService :BazService :MooService :ZooService <<component>> <<WAR>> / <<EAR>>
  • 15. is not modular out-of-the-box
  • 16. even is not modular
  • 17. <import resource="..."> is not modular because of ●bean name clashes ●global scopes of settings and aspects ●zero tolerance for module failure
  • 18. Glue code should allow to forge modules in isolation
  • 19. and then work altogether
  • 20. II. Banshun vs OSGi, EJB
  • 21. http://docs.jboss. org/jbossas/docs/Server_Configuration_Guide/4/html/Inside_the_JBoss_Class_Loading_ rchitecture-The_Complete_Class_Loading_Model.html
  • 22. are about multiple classloaders OSGi EJB http://docs.jboss. org/jbossas/docs/Server_Configuration_Guide/4/html/Inside_the_JBoss_Class_Loading_ rchitecture-The_Complete_Class_Loading_Model.html
  • 23. OSGi, EJB is about multiple classloaders Single classloader is enough! Banshun resolves versions at build time
  • 24. OSGi, EJB is about hot partial redeploy
  • 25. Never do that at prod it's not possible to assure that it works http://www.newpig.com/us/caution-hot-sign/SGN550
  • 26. MANIFEST.MF Manifest-Version: 1.0 Bundle-Name: Simple Service Bundle Bundle-Description: Simple Service Bundle-ManifestVersion: 2 Bundle-SymbolicName: ....sdms.message.messageService Bundle-Version: 1.1.0 Import-Library: org.aspectj, org.springframework.spring Import-Bundle: com....commons.lang;version="[2.4.0,2.4.0]" Export-Package: ....sdms.message.service;version="1.1.0" What is the value for your app? YAGNI <ejb-jar xmlns="./ns/javaee" xmlns:xsi="http://www" version="3.0" xsi:schemaLocation=""> <enterprise-beans> <session> <ejb-name>TestBean</ejb-name> <env-entry> <description>admin email</description> <env-entry-name>mail</env-entry-name> <env-entry-value>admin@</env-entry> </env-entry> </session> </enterprise-beans>
  • 27. Banshun ●don't need any build facility ●a few row artefacts
  • 28. OSGi, EJB has weak runtime facilities launch and pray
  • 29. http://www.lilycli.com/lart.html Banshun has full-fledged runtime ●and for everyday development ●for production
  • 30. III How does it work? http://blog.rinajakubowicz.com/about-boom/
  • 31. 1. instantiate children contexts <bean id="root" class="..banshun.ContextParentBean"> <property name="configLocation" value="authenticator-context.xml datasource-context.xml ..."/> ... </bean> <<WAR>> ...
  • 32. 2. export singleton <nested:export ref="sampleServie" interface="com.gd.sn..SampleService"/>
  • 33. 3. import singleton <nested:import id="sampleServie" interface="com.gd.sn..SampleService"/>
  • 34. IV Features
  • 35. Legend
  • 36. References Checks ●wrong interface/name ●no exports ●lack of import
  • 37. Handling Cycles ●detect ●prohibit ●resolve
  • 38. 12:30:55,098|**WARN**| com.macys.platform.util.caching.repository.impl.CachingDistributedOverTransactionalNamedCacheRepository | Stored object 'MAIN_IndexedCatalogIndex' is not loaded at the moment of first usage. Repository will try to perform lazy loading. |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| pageMediaDistributedCacheWorker:0 12:30:55,099|**INFO**| com.macys.platform.util.caching.repository.impl.CachingDistributedOverTransactionalNamedCacheRepository | Loading stored object: 'MAIN_IndexedCatalogIndex'. Current version is null. |Client Details{sdpGrid:,ClientName: ClientInstanceName: , ClientThreadName: }| pageMediaDistributedCacheWorker:0 12:30:55,100|**WARN**| com.macys.platform.util.caching.repository.impl.CachingDistributedOverTransactionalNamedCacheRepository | Object were not loaded because object 'MAIN_IndexedCatalogIndex' is null. Current version is null. |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| pageMediaDistributedCacheWorker:0 12:30:55,100|**WARN**| com.macys.platform.navigation.providers.catalog.domain.impl.IndexedCatalogRepositoryImpl | Failed to initialize indexed catalog. |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| pageMediaDistributedCacheWorker: 0 12:30:55,100|**ERROR**| com.tangosol.coherence.component.util.logOutput.Log4j | 2012-05-01 12:30:55.100/1208.996 Oracle Coherence EE 3.5.3/465 <Error> (thread=pageMediaDistributedCacheWorker:0, member=1): Failed to load key="PageMediaKey [pageId=519728, pageRegion=PDP_CUSTOMER_REASSURANCE, pageDomain=PRODUCT, channelMode=SITE, mediaSourceType=PRODUCT]": |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| Logger@9271941 3.5.3/465 12:30:55,101|**ERROR**| com.tangosol.coherence.component.util.logOutput.Log4j | 2012-05-01 12:30:55.100/1208.996 Oracle Coherence EE 3.5.3/465 <Error> (thread=pageMediaDistributedCacheWorker:0, member=1): com.macys.platform.navigation.providers.catalog. index.exceptions.CatalogNotReadyException: Failed to initialize indexed catalog. at com.macys.platform.navigation.providers.catalog.domain.impl.IndexedCatalogRepositoryImpl.getIndexedCatalog(IndexedCatalogRepositoryImpl.java:56) at com.macys.platform.navigation.providers.catalog.domain.impl.IndexedCatalogRepositoryImpl.getIndexedCatalogClient(IndexedCatalogRepositoryImpl.java:31) at com.macys.platform.navigation.providers.catalog.businesslogic.assembler.ProductAssembler.assemble(ProductAssembler.java:424) at com.macys.platform.navigation.providers.catalog.componentmgr.CatalogServiceComponentManager.getProducts(CatalogServiceComponentManager.java:183) at com.macys.platform.navigation.providers.catalog.componentmgr.CatalogServiceComponentManager.getProduct(CatalogServiceComponentManager.java:163) at com.macys.platform.navigation.providers.catalog.componentmgr.CatalogServiceComponentManager.getProduct(CatalogServiceComponentManager.java:159) at sun.reflect.GeneratedMethodAccessor133.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196) at $Proxy233.getProduct(Unknown Source) at com.macys.platform.navigation.providers.catalog.da.componentmgr.CatalogServiceDAComponentMgr.getAttribute(CatalogServiceDAComponentMgr.java:295) at sun.reflect.GeneratedMethodAccessor132.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196) at $Proxy247.getAttribute(Unknown Source) at com.macys.platform.providers.media.businesslogic.mediafinder.ProductMediaFinder.getMediaKey(ProductMediaFinder.java:212) at com.macys.platform.providers.media.componentmgr.PageMediaFinderComponent.getMediaKeysForRegion(PageMediaFinderComponent.java:54) at com.macys.platform.providers.media.cache.PageMediaCacheLoader.load(PageMediaCacheLoader.java:47) at com.macys.platform.util.caching.transactional.impl.factory.util.TransactionalCacheLoader$1.call(TransactionalCacheLoader.java:59) at com.macys.platform.util.caching.transactional.impl.manager.TransactionalNamedCachesManagerImpl.invokeAs(TransactionalNamedCachesManagerImpl.java:150) at com.macys.platform.util.caching.transactional.impl.factory.util.TransactionalCacheLoader.load(TransactionalCacheLoader.java:57) at com.macys.platform.util.caching.transactional.impl.factory.util.CountingCacheLoaderWrapper.load(CountingCacheLoaderWrapper.java:22) at com.macys.platform.util.caching.factory.NamedCacheFactoryBean$Loader.load(NamedCacheFactoryBean.java:318) at com.tangosol.net.cache.ReadWriteBackingMap$CacheLoaderCacheStore.load(ReadWriteBackingMap.java:5166) at com.tangosol.net.cache.ReadWriteBackingMap$CacheStoreWrapper.load(ReadWriteBackingMap.java:4314) at com.tangosol.net.cache.ReadWriteBackingMap$CacheStoreWrapper.loadInternal(ReadWriteBackingMap.java:3987) at com.tangosol.net.cache.ReadWriteBackingMap.get(ReadWriteBackingMap.java:754) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.DistributedCache.onGetRequest(DistributedCache.CDB:25) at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.DistributedCache$GetRequest.run(DistributedCache.CDB:1) at com.tangosol.coherence.component.util.DaemonPool$WrapperTask.run(DaemonPool.CDB:1) at com.tangosol.coherence.component.util.DaemonPool$WrapperTask.run(DaemonPool.CDB:32) at com.tangosol.coherence.component.util.DaemonPool$Daemon.onNotify(DaemonPool.CDB:63) at com.tangosol.coherence.component.util.Daemon.run(Daemon.CDB:42) at java.lang.Thread.run(Thread.java:662) |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| Logger@9271941 3.5.3/465 12:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.coordinator.RefreshCoordinator | Retrieving product and reference data |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.coordinator.RefreshCoordinator | loadProduct(...) is started |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductLoader | Querying for products |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,329|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductLoader | Loading product attributes, search attributes, loading relations |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,330|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading unary attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,344|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading multi-valued attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,369|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading attributes: Loading unary completed Loading multi-valued comleted Loading attributes completed, total loaded: [1] in [39] ms |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,370|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading unary attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,370|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading multi-valued attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,428|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading attributes: Loading unary completed Loading multi-valued comleted Loading attributes completed, total loaded: [0] in [58] ms |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:57,428|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductToCategoryLoader | loadData(...) started |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:58,116|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductToCategoryLoader$1 | Product-to-category load subtask completed. Retrieved data for [1] products. |Client Details{sdpGrid:,ClientName: ClientInstanceName: , ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:58,116|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductToCategoryLoader | Product-to-category load data completed in [688] ms |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:8 12:30:58,229|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductLoader | Load Attributes: Loading product attributes completed with [1] loaded Loading product-to-category completed with [1] loaded Loading product-to-product completed with [0] loaded logs root-cause at the bottom
  • 39. Fault-tolerance mode failure causes skipping
  • 40. BA A B
  • 41. Build time Customization <bean id="root" class="..banshun.ContextParentBean"> <property name="configLocation" value=" -context.xml ..."/> ... </bean> * B A
  • 42. Run time Customization <bean id="root" class="..banshun.ContextParentBean"> ... <property name="runOnlyServices" value="basketService profileService"> .. ... </bean> BA BA
  • 43. skipped as not needed runOnlyServices
  • 44. Spring AOP support <bean id="proxyCreator" class="org.springframework..... BeanNameAutoProxyCreator"> <property name="customTargetSourceCreators" > <bean class="com.....LookupTargetSourceCreator"/> </property> <property name="beanNames"> <list> <value>*_beanDef</value> </list> </property> <property name="interceptorNames"> <list> <idref bean="jamonPerformanceMonitorInterceptor" /> </list> </property> </bean>
  • 45. http://blog.griddynamics.com/search/label/Spring http://github.com/griddynamics/banshun mkhludnev@griddynamics.com banshun@googlegroups.com http://goo.gl/RZays Whodunit Artem Kirichkov Oleg Malakhov Eugeny Morozov Alexey Olenev Vladimir Polyakov Mikhail Khludnev 2K LOC