Transcript
Page 1: Banshun - OSGi-less modularity for Spring

Yet Another One....

Banshun

a tiny based Modular Framework

http://flic.kr/p/EWNYh

Page 2: Banshun - OSGi-less modularity for Spring

Agenda

●Enterprise Applications

●Banshun vs OSGi, EJB

●1, 2, 3 - BOOM!

●Features ...

Page 3: Banshun - OSGi-less modularity for Spring

Agenda - Features

● buildtime & runtime app customization

● developer friendliness

○ references validation

○ cycles resolution

○ root cause logging

○ fault-tolerance

○ dependencies graph

● Spring AOP support

Page 4: Banshun - OSGi-less modularity for Spring

Is it your app?

:TheService

+ doBusiness(param) : Result

Page 5: Banshun - OSGi-less modularity for Spring

Is it your app?

:TheService

+ doBusiness(param) : Result

RDBMS

Page 6: Banshun - OSGi-less modularity for Spring

Is it your app?

:TheService

+ doBusiness(param) : Result

Page 7: Banshun - OSGi-less modularity for Spring

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>

Page 8: Banshun - OSGi-less modularity for Spring

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

Page 9: Banshun - OSGi-less modularity for Spring

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

<<EAR>>

<<container>>

Page 10: Banshun - OSGi-less modularity for Spring

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

<<WAR>>

<<container>>

Page 11: Banshun - OSGi-less modularity for Spring

The app becomes big

:FooService

:ZooService

:MooService

:FooService

:BarService

:BazService

<<WAR>>

Page 12: Banshun - OSGi-less modularity for Spring

The app becomes big

<<WAR>>:FooService

:BarService

:BazService

:FooService

:BarService

:BazService

Page 13: Banshun - OSGi-less modularity for Spring

it have to be modular

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

:AService

:BService

:CService

:DService

:EService

<<component>>

Page 14: Banshun - OSGi-less modularity for Spring

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

<<WAR>> / <<EAR>>

Page 15: Banshun - OSGi-less modularity for Spring

is not modular out-of-the-box

Page 16: Banshun - OSGi-less modularity for Spring

even

is not modular

Page 17: Banshun - OSGi-less modularity for Spring

<import resource="..."> is not modular because of

●bean name clashes ●global scopes of settings and aspects ●zero tolerance for module failure

Page 18: Banshun - OSGi-less modularity for Spring

Glue code should allow

to forge modules in isolation

Page 19: Banshun - OSGi-less modularity for Spring

and then work altogether

Page 20: Banshun - OSGi-less modularity for Spring

II. Banshun vs

OSGi, EJB

Page 23: Banshun - OSGi-less modularity for Spring

OSGi, EJBis about multiple

classloaders Single classloader

is enough!

Banshun resolves versions at build time

Page 24: Banshun - OSGi-less modularity for Spring

OSGi, EJBis about

hot partial redeploy

Page 25: Banshun - OSGi-less modularity for Spring

Never do thatat prod

it's not possible to assure that it works

http://www.newpig.com/us/caution-hot-sign/SGN550

Page 26: Banshun - OSGi-less modularity for Spring

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>

Page 27: Banshun - OSGi-less modularity for Spring

Banshun

●don't need any build facility

●a few row artefacts

Page 28: Banshun - OSGi-less modularity for Spring

OSGi, EJBhas weak runtime facilities

launch and pray

Page 29: Banshun - OSGi-less modularity for Spring

http://www.lilycli.com/lart.html

Banshunhas full-fledged runtime

●and for everyday development

●for production

Page 30: Banshun - OSGi-less modularity for Spring
Page 31: Banshun - OSGi-less modularity for Spring

III How does it work?

http://blog.rinajakubowicz.com/about-boom/

Page 32: Banshun - OSGi-less modularity for Spring

1. instantiate children contexts

<bean id="root" class="..banshun.ContextParentBean"> <property name="configLocation" value="authenticator-context.xml datasource-context.xml ..."/> ... </bean>

<<WAR>>

...

Page 33: Banshun - OSGi-less modularity for Spring

2. export singleton

<nested:export ref="sampleServie" interface="com.gd.sn..SampleService"/>

Page 34: Banshun - OSGi-less modularity for Spring

3. import singleton

<nested:import id="sampleServie" interface="com.gd.sn..SampleService"/>

Page 35: Banshun - OSGi-less modularity for Spring
Page 36: Banshun - OSGi-less modularity for Spring

IV Features

Page 37: Banshun - OSGi-less modularity for Spring

Legend

Page 38: Banshun - OSGi-less modularity for Spring
Page 39: Banshun - OSGi-less modularity for Spring
Page 40: Banshun - OSGi-less modularity for Spring
Page 41: Banshun - OSGi-less modularity for Spring
Page 42: Banshun - OSGi-less modularity for Spring

References Checks

●wrong interface/name

●no exports

● lack of import

Page 43: Banshun - OSGi-less modularity for Spring

Handling Cycles●detect ●prohibit ●resolve

Page 44: Banshun - OSGi-less modularity for Spring

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:012: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:012: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:012: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:012: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/46512: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/46512:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.coordinator.RefreshCoordinator | Retrieving product and reference data |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.coordinator.RefreshCoordinator | loadProduct(...) is started |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812:30:57,153|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductLoader | Querying for products |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812: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:812:30:57,330|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading unary attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812:30:57,344|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading multi-valued attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812: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:812:30:57,370|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading unary attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812:30:57,370|**INFO**| com.macys.platform.navigation.providers.preloader.loader.attribute.AttributeLoader | Loading multi-valued attributes |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812: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:812:30:57,428|**INFO**| com.macys.platform.navigation.providers.preloader.loader.product.ProductToCategoryLoader | loadData(...) started |Client Details{sdpGrid:,ClientName: ClientInstanceName: ,ClientThreadName: }| ProductDistributedCacheWorker:812: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:812: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:812: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

Page 45: Banshun - OSGi-less modularity for Spring

Fault-tolerance mode

failurecauses skipping

Page 46: Banshun - OSGi-less modularity for Spring

BA

A

B

Page 47: Banshun - OSGi-less modularity for Spring

Build time Customization

<bean id="root" class="..banshun.ContextParentBean"> <property name="configLocation"

value=" -context.xml ..."/> ... </bean>

*

B A

Page 48: Banshun - OSGi-less modularity for Spring

Run time Customization

<bean id="root" class="..banshun.ContextParentBean"> ... <property name="runOnlyServices" value="basketService profileService"> .. ... </bean>

BA BA

Page 49: Banshun - OSGi-less modularity for Spring

skipped as not needed

runOnlyServices

Page 50: Banshun - OSGi-less modularity for Spring
Page 51: Banshun - OSGi-less modularity for Spring

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>

Page 52: Banshun - OSGi-less modularity for Spring

http://blog.griddynamics.com/search/label/Springhttp://github.com/griddynamics/[email protected]@googlegroups.com

http://goo.gl/RZays

Whodunit

Artem KirichkovOleg MalakhovEugeny MorozovAlexey OlenevVladimir PolyakovMikhail Khludnev

2K LOC

Page 53: Banshun - OSGi-less modularity for Spring

Recommended