17
Persist and Replay Runtime Data Using Apache Java Caching System and Javassist https://bitbucket.org/ wishcoder/ jcs.marketdata.replay/ wiki/Home Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Java - Persist and Replay Runtime Data

Embed Size (px)

Citation preview

Page 1: Java - Persist and Replay Runtime Data

Persist and Replay Runtime Data Using Apache Java Caching

System and Javassist

https://bitbucket.org/wishcoder/jcs.marketdata.replay/wiki/Home

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 2: Java - Persist and Replay Runtime Data

Persist and Replay Runtime Data

• The ability to persist data created at runtime is useful when application states and data are required to be replayed multiple times to investigate application issues.

• This article demonstrates how to persist

runtime data to disk and load disk persisted data to replay in new JVM instances.

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 3: Java - Persist and Replay Runtime Data

Apache JCS and Javassist

• JCS is a distributed caching system written in Java. Indexed Disk Auxiliary Cache is used to persist data on disk. JCS only persist Serializable java objects.

• Javassist (Java Programming Assistant) makes Java bytecode manipulation simple. Javassist is used to dynamically set values for transient fields that are not persisted due to transient nature.

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 4: Java - Persist and Replay Runtime Data

Maven Dependencies<properties>

<org.javassist-version>3.19.0-GA</org.javassist-version><jcs-version>1.3</jcs-version>

</properties>

<dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>${org.javassist-version}</version></dependency><dependency><groupId>jcs</groupId><artifactId>jcs</artifactId><version>${jcs-version}</version></dependency>

</dependencies>

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 5: Java - Persist and Replay Runtime Data

Log4j Settings for JCS<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">

<layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%d [%t] %C{1} %p - %m%n"/>

</layout></appender>

<logger name="org.apache.jcs"><!– DEBUG level in dev mode will enable useful logs from JCS jar -><!– DON’T PUT THIS IN PRODUCTION ENVIRONMENT -><level value="DEBUG"/><appender-ref ref="CONSOLE"/>

</logger>

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 6: Java - Persist and Replay Runtime Data

Setup JCS - DEFAULT CACHE REGION

Properties props = new Properties();

props.put("jcs.default", "DC");props.put("jcs.default.cacheattributes", "org.apache.jcs.engine.CompositeCacheAttributes");props.put("jcs.default.cacheattributes.MaxObjects", 1000);props.put("jcs.default.cacheattributes.MemoryCacheName", "org.apache.jcs.engine.memory.lru.LRUMemoryCache");props.put("jcs.default.cacheattributes.DiskUsagePatternName", "UPDATE");props.put("jcs.default.elementattributes", "org.apache.jcs.engine.ElementAttributes");props.put("jcs.default.elementattributes.IsSpool", "true");props.put("jcs.region.elementattributes.IsEternal", "false");props.put("jcs.default.elementattributes.IsLateral", "false");props.put("jcs.default.elementattributes.IsRemote", "false");

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 7: Java - Persist and Replay Runtime Data

Setup JCS - AUXILARY/DISK CACHEprops.put("jcs.auxiliary.DC", "org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory");props.put("jcs.auxiliary.DC.attributes", "org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes");props.put("jcs.auxiliary.DC.attributes.DiskPath", “C:\TradeCache”);props.put("jcs.auxiliary.DC.attributes.MaxPurgatorySize", "10000000"); // 10000000// If the maximum key size is less than 0, no limit will be placed on// the number of keys. By default, the max key size is 5000.props.put("jcs.auxiliary.DC.attributes.MaxKeySize", "-1");

// Use Thread Pool for disk operationprops.put("jcs.auxiliary.DC.attributes.EventQueueType", "POOLED");props.put("jcs.auxiliary.DC.attributes.EventQueuePoolName", "disk_cache_event_queue");

// Disk Cache Event Queue Poolprops.put("thread_pool.disk_cache_event_queue.useBoundary", "false");props.put("thread_pool.remote_cache_client.maximumPoolSize", "15");props.put("thread_pool.disk_cache_event_queue.minimumPoolSize", "1");props.put("thread_pool.disk_cache_event_queue.keepAliveTime", "3500");props.put("thread_pool.disk_cache_event_queue.startUpSize", "1");

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 8: Java - Persist and Replay Runtime Data

Setup JCS – CUSTOM DATA CACHE REGION

props.put("jcs.region.marketdata_cache", "DC");props.put("jcs.region.marketdata_cache.cacheattributes", "org.apache.jcs.engine.CompositeCacheAttributes");props.put("jcs.region.marketdata_cache.cacheattributes.MaxObjects", maxObjectInMemory);props.put("jcs.region.marketdata_cache.cacheattributes.MemoryCacheName",

"org.apache.jcs.engine.memory.lru.LRUMemoryCache");props.put("jcs.region.marketdata_cache.cacheattributes.DiskUsagePatternName", "UPDATE");props.put("jcs.region.marketdata_cache.elementattributes", "org.apache.jcs.engine.ElementAttributes");props.put("jcs.region.marketdata_cache.elementattributes.IsEternal", "false");props.put("jcs.region.marketdata_cache.elementattributes.IsLateral", "false");props.put("jcs.region.marketdata_cache.elementattributes.IsRemote", "false");

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 9: Java - Persist and Replay Runtime Data

Initialize and use JCSCompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();ccm.configure(props )

CacheAccess cCache = JCS.getInstance(“marketdata_cache”);

• Write cCache.put(Object name, Object obj);

• ReadObject obj = cCache.get(name);

• Persist Cache To Disk // marketdata_cache.data and marketdata_cache.key files generatedcCache.dispose();

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 10: Java - Persist and Replay Runtime Data

JCS - Load Data From CacheCompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();ccm.configure(props )

CacheAccess cCache = JCS.getInstance(“marketdata_cache”);

• ReadObject obj = cCache.get(name);

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 11: Java - Persist and Replay Runtime Data

Javassist – Inject Transient Data

Javassist (Java Programming Assistant) makes Java bytecode manipulation simple. Javassist is used to dynamically set values for transient fields that are not persisted due to transient nature.

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 13: Java - Persist and Replay Runtime Data

Javassist – Dynamically Add Setter Method

List<CtMethod> setterMethods = new ArrayList<CtMethod>();CtClass sourceClass =

ClassPool.getDefault().get("com.wishcoder.samples.jcs.trade.common.data.TickEvent");CtMethod setSourceMethod = getCacheManager().getMethod(sourceClass,

"setSource", "source","com.wishcoder.samples.jcs.trade.common.data.User");

setterMethods.add(setTickBookMethod);CacheReplayHelper.addSetterMethods(sourceClass, setterMethods);

Class<?>[] userObject = new Class[1];userObject[0] =

Class.forName("com.wishcoder.samples.jcs.trade.common.data.User");HashMap<String, Class<?>[]> parameterMap = new HashMap<String, Class<?>[]>();parameterMap.put("setSource", userObject);

CacheReplayHelper.prepareNonSerializeSetters("com.wishcoder.samples.jcs.trade.common.data.TickEvent",parameterMap);

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 14: Java - Persist and Replay Runtime Data

Javassist – Set Transient Data • Read object from JCS Cache:CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();ccm.configure(props )

CacheAccess cCache = JCS.getInstance(“marketdata_cache”);Object cachedObject = cCache.get(name);

• Initialize object that need to be injected in cached objectUser user = new User(‘1’, ‘Name’);

• Inject Transient data in cached object cachedObject = CacheReplayHelper.setNonSerializeSetter(cachedObject ,"setSource", user );

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 15: Java - Persist and Replay Runtime Data

Wiki and Source Repository

https://bitbucket.org/wishcoder/jcs.marketdata.replay/wiki/Home

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 16: Java - Persist and Replay Runtime Data

Useful Links

• Log4J• Java• Java MigLayout• Javassist• Apache Java Caching System - JCS

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder

Page 17: Java - Persist and Replay Runtime Data

Questions?

Ajay Singh | [email protected] LinkedIn - https://www.linkedin.com/in/ajaysinghonline

Bitbucket - https://bitbucket.org/wishcoder Slideshare - http://www.slideshare.net/ajaysingh672

Ajay Singh | [email protected] | LinkedIn - https://www.linkedin.com/in/ajaysinghonline | Bitbucket - https://bitbucket.org/wishcoder