Post on 10-May-2015
description
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
http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/Inside_the_JBoss_Class_Loading_Architecture-The_Complete_Class_Loading_Model.html
are about multiple classloaders
OSGi EJB
http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/Inside_the_JBoss_Class_Loading_Architecture-The_Complete_Class_Loading_Model.html
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