banshun - osgi-less modularity for spring

Post on 10-May-2015

477 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

Yet Another One....

Banshun

a tiny based Modular Framework

http://flic.kr/p/EWNYh

Agenda

●Enterprise Applications

●Banshun vs OSGi, EJB

●1, 2, 3 - BOOM!

●Features ...

Agenda - Features

● buildtime & runtime app customization

● developer friendliness

○ references validation

○ cycles resolution

○ root cause logging

○ fault-tolerance

○ dependencies graph

● Spring AOP support

Is it your app?

:TheService

+ doBusiness(param) : Result

Is it your app?

:TheService

+ doBusiness(param) : Result

RDBMS

Is it your app?

:TheService

+ doBusiness(param) : Result

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>

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

<<EAR>>

<<container>>

Don't you need to deploy it?

:TheService

+ doBusiness(param) : Result

<<WAR>>

<<container>>

The app becomes big

:FooService

:ZooService

:MooService

:FooService

:BarService

:BazService

<<WAR>>

The app becomes big

<<WAR>>:FooService

:BarService

:BazService

:FooService

:BarService

:BazService

it have to be modular

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

:AService

:BService

:CService

:DService

:EService

<<component>>

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

:FooService

:BarService

:BazService

:MooService

:ZooService

<<component>>

<<WAR>> / <<EAR>>

is not modular out-of-the-box

even

is not modular

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

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

Glue code should allow

to forge modules in isolation

and then work altogether

II. Banshun vs

OSGi, EJB

OSGi, EJBis about multiple

classloaders Single classloader

is enough!

Banshun resolves versions at build time

OSGi, EJBis about

hot partial redeploy

Never do thatat prod

it's not possible to assure that it works

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

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>

Banshun

●don't need any build facility

●a few row artefacts

OSGi, EJBhas weak runtime facilities

launch and pray

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

Banshunhas full-fledged runtime

●and for everyday development

●for production

III How does it work?

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

1. instantiate children contexts

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

<<WAR>>

...

2. export singleton

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

3. import singleton

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

IV Features

Legend

References Checks

●wrong interface/name

●no exports

● lack of import

Handling Cycles●detect ●prohibit ●resolve

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

Fault-tolerance mode

failurecauses skipping

BA

A

B

Build time Customization

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

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

*

B A

Run time Customization

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

BA BA

skipped as not needed

runOnlyServices

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>

http://blog.griddynamics.com/search/label/Springhttp://github.com/griddynamics/banshunmkhludnev@griddynamics.combanshun@googlegroups.com

http://goo.gl/RZays

Whodunit

Artem KirichkovOleg MalakhovEugeny MorozovAlexey OlenevVladimir PolyakovMikhail Khludnev

2K LOC

top related