Wednesday, November 5, 2008


Toplink/Eclipselink Coherence

Integration Using Spring

Introduction

            The aim of this document is to explain how to integrate EclipseLink and Oracle Coherence using Spring Framework.  These white paper target audiences are developers/technical architects/technical managers. This white paper assumes the reader has the knowledge of the following: -

1.       Java EE framework

2.       Spring Framework

Spring framework is collections of smaller frameworks and act as glue, which tie together different layers of enterprise application and provide consistent and simple programming model based on best practices. Some of the key features of the spring framework are: -

·         Provides IOC container (Inversion of control/Dependency Injection)

·         Provides AOP (Aspect Oriented Programming) framework.

·         Provides Data Access framework

·         Provides declarative Transaction management framework.

·         Provides testing framework which enables use to develop code using TDD approach (Test Driven Development)

3.       Eclipse Link

Eclipse Link is a comprehensive open source persistence solution with around 12 years of commercial usage.  Some of the key features of Eclipse Link are: -

·       Fully JPA compliant

·       Enables simplified configuration of the target application server

·       Enable integration with JTA transaction manager

·       Very flexible framework, which allows customizations like SessionCustomizer & DescriptorCustomizer, which allows customizations of eclipse link session.

·       Provide support for concurrency protection – locking

·       EclipseLink cache. It has two types of caches i.e. L1 cache (EntityManager) and L2 cache (EntityManagerFactory)

·       Provides advance query facilitity like object graph loading optimization using Join and Batch Fetch.

 

4.       Oracle Coherence

Oracle Coherence is a JCache-compliant in memory distributed data grid solution for clustered applications and application servers. Some of the key features of Oracle Coherence are: -

·       Container – less clustering of java processing (pojo – pliain old java objects)

·       Real-time event observation (Listener pattern)

·       Parallel queries and aggregation (Purely object based queries)

·       Clustered JMX

·       Pluggable Cache store

 


Overview

Eclipse link and Oracle coherence integration provides highly scalable solution(s) and also provide data grid-computing capabilities. Spring framework allows powerful feature of retrieving objects from the Spring BeanFactory. This feature can be further being extended to retrieve objects configured in a cache scheme from BeanFactory and hence give better control over object instances creation. This is especially true for cache servers configured with CacheStore objects. Typically these CacheStore need to configure with data sources, connection pools, etc. The following document explains how to integrate Eclipse link and Oracle Coherence using Spring Framework and hence provide ability to leverage spring’s framework programming model and ability to provide easy configuration of data sources/pool etc for plain Java object

Eclipse link grid – spring aware cache store/loader

Coherence supports pluggable CacheLoader and CacheStore implementations. As result the entity classes annotated with JPA specifications can directly interact with Coherence API (get, put, etc)

SpringAwareEntityCacheLoader is class which supports reading the JPA entities from the database by implementing load/loadAll methods. SpringAwareEntityCacheStore extendsSpringAwareEntityCacheLoader and also support write, update and delete operations to the database. This class also implements CacheStore and implements the methods store, storeAll, erase, eraseAll.

The figure shows a typical Oracle Coherence and Eclipse Link integration viaSpringAwareEntityCacheStore




CACHE FACTORY SPRING INTEGRATION

            The entry point to access caches or any other services is CacheFactory through the use of its static methods (getCache etc). Coherence provides flexibility to override its default behavior via use of cache configuration file (coherence-cache-config.xml). Hence its possible to provide custom implementations of Coherence interfaces CacheStore  & CacheLoader. These interfaces can be configured via a class-scheme. Class schemes provide a mechanism for instantiating an arbitrary Java object. The class-scheme may be configured to either instantiate objects directly via their class-name (using new operator), or indirectly via a class-factory-name and method-name. The class-scheme must be configured with either a class-name or class-factory-name and method-name.

It is possible to tell Coherence to retrieve objects (cache store) configured in a class-scheme from a Spring BeanFactory instead of creating its own instance.

 

SpringAwareCacheStoreFactory is spring aware class, which extends DefaultConfigurableCacheFactory, and provides the ability to delegate class-scheme bean instantiations responsibility to spring’s BeanFactory class.



Key features of SpringAwareCacheStoreFactory

1.       Application Context Aware class: - Since this class implements spring ApplicationContextAware interface, as result at the time bean post processing, this class will be handed over the current ApplicationContext. Hence it will be useful for the cache servers that require beans from the spring container.

2.       Bean Factory Ware class: - This class also implements spring BeanFactoryAware interface, as result at the time of bean post processing current BeanFactory will be handed over to it. As a result a BeanFactory can be provided at the runtime by an application or provided directly by the spring container. This is useful for Coherence applications running in a container that already has an existing BeanFactory.

Note: - Implementation of spring’s InitializingBean interface will make sure BeanFatory is set before making call to DefaultConfigurableFactory class instantiateAny method is called. This is the key method, which creates object (cache store)-using class-scheme. Typically the object will be configured as spring-bean: myCaheStore in the class-scheme tag in the coherence config file.

3.       Ability to set the path of coherence configuration file and hence clean approach to manage coherence configuration files.

 

Conclusion

            Using Spring as a glue framework to integrate Eclipse Link and Oracle Coherence provides following key benefits: -

 

1.       Ability to inject separate data source to be used by SpringAwareCacheStore to perform the database operations. The data source can be setup in spring configuration file

2.       Ability to provide pool of data sources. Again these data sources pools can be configured in spring configuration file.

3.       Provide seprate EntityManager for the SpringAwareEntityCacheStore as result application’s transaction will never be interfered.

4.       Make it possible to use spring’s JpaDaoSupport and hence spring declarative transaction management and also spring programming model (best practices)


Sunday, September 7, 2008

Eclipse Link and Oracle Coherence integration using Spring

For the last few days I have an intresting journey into Oracle Coherence. Spring being one of the most powerful and widely accepted framework, I thought of playing with it. The belwo article is an outocome of my journey ....

EclipseLink and Coherence can be used together in several combinations. This blog discusses, how to integrate using Spring framework.These options including using Coherence as a Eclipse Link plug-in, using Eclipse Link as a Coherence plug-in via the CacheStore interface and bulk-loading Coherence caches from a Eclipse Link query. Most applications that use Coherence and EclipseLink would like to use a mixture of these approaches. The Eclipse Link API features powerful management of entities and relationships, and the Coherence API delivers maximum performance and scalability.

Aim:

1. To make Oracle Coherence as the L2 shared cache using spring framework.








CacheStore/CachLoader:

Orache Coherence provides above two interfaces based on the Jcache specifications. Jcache specifies API and semantics for temporary, in memory caching of Java objects, including object creation, shared access, spooling, invalidation, and consistency across JVM's.

In order to make Oracle Coherence as the distributed cache, as a first step it is important to make the CacheStore and CacheLoader which will do

· Store/Update/Delete the java object in the oracle coherence

· Retrieve object from the cache.

So lets make two classes EclipseLinkCacheStore which implements CacheStore and EclipseLinkCacheLoder which implements the CacheStore, as shown below:-

public class OhiEclipseLinkEntityCacheLoader extends Base implements CacheLoader {

// Will be injected using spring

private EntityManagerFactory emf;

private EntityManager em;

protected String m_sEntityName = "";

protected Class m_sEntityClass;

public void setEntityName(String entityName) {

this.m_sEntityName = entityName;

}

public void setEntityClass(Class entityClass) {

this.m_sEntityClass = entityClass;

}

public OhiEclipseLinkEntityCacheLoader(EntityManagerFactory emf) {

this.emf = emf;

// Create a new Entity manager to avoid any

// conflicts with the existing Enity manager

// which is using L1 cache

this.em = emf.createEntityManager();

}

- - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - -

// Implement other inteface methods

}

public class OhiEclipseLinkEntityCacheStore extends OhiEclipseLinkEntityCacheLoader implements CacheStore {

private EntityManagerFactory emf;

private String name="";

public OhiEclipseLinkEntityCacheStore(EntityManagerFactory emf) {

super(emf);

- - - - - - - -

- - - - - - -

// Implement other inteface methods

}

Spring can inject the Enity Manager as shown below: -

class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">

value="org.eclipse.persistence.platform.database.oracle.OraclePlatform" />

class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" />

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

value="oracle.jdbc.pool.OracleDataSource" />

value="jdbc:oracle:thin:@xxxx:1521:XE" />

class="org.springframework.orm.jpa.JpaTransactionManager">

ref="entityManagerFactory" />

class="com.oracle.healthinsurance.eclipselink.cachestore.OhiEclipseLinkEntityCacheStore"

scope="prototype">

What’s next?

Lets create spring aware cache store which can pick up the oracle coherence configure files (in a more declrative way rather than passing it using –D options as specified in the oracle coherence documentation)

SpringAwareCacheStore provides a facility to access caches declared in a "cache-config.dtd" compliant configuration file, similar to its super class (DefaultConfigurableCacheFactory). In addition, this factory provides the ability to reference beans in a Spring application context via the use of a class-scheme element. This factor is made ApplicationContextAware so that it will very trivial to get can access to BeanFactory. This can be useful for stand-alone JVMs such as cache servers. It can also be configured at runtime with a pre-configured Spring bean factory. This can be useful for Coherence applications running in an environment that is itself responsible for tarting the Spring bean factory, such as a web container.

The following the code snippet which further extends the spring aware cache factory mentioned in the Oracle Coherence documentations

public class SpringAwareCacheStore extends DefaultConfigurableCacheFactory

implements BeanFactoryAware, ApplicationContextAware, InitializingBean

/**

* This constructor automatically figure out the absolute path to the spring

* configuraion file using DiscoveryUtils. Hence as result cache config file

* can be appeneded at runtime.

*

* If this construtor is used the bean factory is set in the afterProperties

* set method.

*

* @param sPath

*/

public SpringAwareCacheStore(String sPath) {

super(DiscoverUtils.getPathToResouce(sPath));

}

/**

* Appliction context. This application context will be required to get the

* BeanFactory in case this class is instantiated with the constructor which

* take the cache file name.

*/

private ApplicationContext appContext;

public void setApplicationContext(ApplicationContext applicationContext)

throws BeansException {

this.appContext = applicationContext;

}

public void afterPropertiesSet() throws Exception {

if (m_beanFactory == null) {

m_beanFactory = appContext.getAutowireCapableBeanFactory();

// register a shutdown hook so the bean factory cleans up

// upon JVM exit

((AbstractApplicationContext) m_beanFactory).registerShutdownHook();

}

}

// ----- extended methods -----------------------------------------------

// Picked up from the Oracle Coherence documentation

/**

* Create an Object using the "class-scheme" element.

In addition to

* the functionality provided by the super class, this will retreive an

* object from the configured Spring BeanFactory for class names that use

* the following format:

*

*

* <class-name>spring-bean:sampleCacheStore</class-name>

*

*

* Parameters may be passed to these beans via setter injection as well:

*

*

* <init-params>

* <init-param>

* <param-name>setEntityName</param-name>

* <param-value>{cache-name}</param-value>

* </init-param>

* </init-params>

*

*

* Note that Coherence will manage the lifecycle of the instantiated Spring

* bean, therefore any beans that are retreived using this method should be

* scoped as a prototype in the Spring configuration file, for example:

*

*

* <bean id="sampleCacheStore"

* class="com.company.SampleCacheStore"

* scope="prototype"/>

*

*

* @param info

* the cache info

* @param xmlClass

* "class-scheme" element.

* @param context

* BackingMapManagerContext to be used

* @param loader

* the ClassLoader to instantiate necessary classes

*

* @return a newly instantiated Object

*

* @see DefaultConfigurableCacheFactory#instantiateAny( CacheInfo,

* XmlElement, BackingMapManagerContext, ClassLoader)

*/

protected Object instantiateAny(CacheInfo info, XmlElement xmlClass,

BackingMapManagerContext context, ClassLoader loader) {

if (translateSchemeType(xmlClass.getName()) != SCHEME_CLASS) {

throw new IllegalArgumentException("Invalid class definition: "

+ xmlClass);

}

String sClass = xmlClass.getSafeElement("class-name").getString();

if (sClass.startsWith(SPRING_BEAN_PREFIX)) {

String sBeanName = sClass.substring(SPRING_BEAN_PREFIX.length());

azzert(sBeanName != null && sBeanName.length() > 0,

"Bean name required");

XmlElement xmlParams = xmlClass.getElement("init-params");

XmlElement xmlConfig = null;

if (xmlParams != null) {

xmlConfig = new SimpleElement("config");

XmlHelper.transformInitParams(xmlConfig, xmlParams);

}

Object oBean = getBeanFactory().getBean(sBeanName);

if (xmlConfig != null) {

for (Iterator iter = xmlConfig.getElementList().iterator(); iter

.hasNext();) {

XmlElement xmlElement = (XmlElement) iter.next();

String sMethod = xmlElement.getName();

String sParam = xmlElement.getString();

try {

ClassHelper.invoke(oBean, sMethod,

new Object[] { sParam });

} catch (Exception e) {

ensureRuntimeException(e, "Could not invoke " + sMethod

+ "(" + sParam + ") on bean " + oBean);

}

}

}

return oBean;

} else {

return super.instantiateAny(info, xmlClass, context, loader);

}

}

How my Oracle Coherene config file looks like?

Using the above factory the cache config file can be put in the class path and the above factory class will automatically pick it and lauch the Oracle Cohernece.

Here is the sample config file??

*

ohi-cache-distributed

ohi-cache-distributed

spring-bean:entityCacheStore

setEntityName

{cache-name}

5s

true

Below is the spring magic which lanches the above oracle coherence

class="com.oracle.healthinsurance.cache.factory.SpringAwareCacheStore">

value="/META-INF/spring/coherence-cache-config.xml" />

class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

value="com.tangosol.net.CacheFactory" />

value="setConfigurableCacheFactory" />

This is equivalent to the code

BeanFactory bf = applicationContext.getBeanFactory();

SpringAwareCacheStore scf = new SpringAwareCacheStore /META-INF/spring/",bf);

scf.setBeanFactory(applicationContext.getBeanFactory());

CacheFactory.setConfigurableCacheFactory(scf);

Here my sample Unit test case (based on AbstractJpaTests provided by spring)

NamedCache cache = CacheFactory.getCache("CodFlexCodeSystemsB");

Assert.assertNotNull(cache);

CodFlexCodeSystemsB obj = (CodFlexCodeSystemsB) cache.get(new Long(10001));

System.err.println(">>>" + obj.getSubtype());

Assert.assertNotNull(obj);

obj.setSubtype("SIFC");

cache.put(new Long(10001), obj);

try {

Thread.sleep(8000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

CodFlexCodeSystemsB obj1 = (CodFlexCodeSystemsB) cache.get(new Long(10001));

System.err.println(obj1.getId());

System.err.println(obj1.getSubtype());

System.err.println("size " + obj1.getCodFlexCodeSystemsTlList().size());

Conclusion

Using spring its very simple to launch oracle coherence as L2 cache and make it enity store. But care should be taken not put all the entity in oracle coherence as it will be negative affect on the performance. After this integration its very simple to exploit the oracle coherence powerful feature like Filters,Query etc.

Sunday, July 6, 2008

Externalize Business Rules/Validation to Scripting Language

Goal
Business rules (stored as Ruby/Groovy or Bean Shell) mentioned on the "Object", should be triggered automatically whenever there is an update/modification to its value.The modification/update can be called from UI/ any other external source. Following key driving parameters for design:-

1. Optimal but not lightening performance, that is, the system should not go for sleep when performing the validation

2. There will be bulk insert/update scenarios/use cases, hence special care should be taken for memory leaks.

3. Flexibility

4. Easily maintainable

This page is an attempt to design/solve the control rule evaluation

at server side mainly.


Assumptions

1. Use Ruby 0.9 / 1.0 or Groovy 1.0 / 1.5 or BeanShell 2.0 for writing the control rules. The design should be extensible that is, if some client want to use rule engine or java code.,the impact should be minimum.

2. The framework in which the below mentioned design will be implemented should support

a. Support Dependency Injection at runtime

b. Support Aspect Oriented Programming

3. Store groovy validation as a method inside the groovy class to enable injection of groovy class into java class.This will also avoid any class loading issues.

4. UI should take script in a compiled format.


Design principles

  1. Automatic syntax checking, compilation and loading at runtime. Note scripting language like groovy uses JIT compilation
  1. Lose coupling i.e. validation module at runtime will be injected into the Domain Object whenever there is a change/modification.
  1. Avoid any class loading issue between groovy object & java object.
  1. Changes to the control rules (i.e. groovy scripts) should be refreshed & loaded at runtime.

Tech Stack

1. Using spring 2.5. 2 dynamic scripting support & JEE 1.5 + platform

Usage of Spring Framework dynamic scripting provides out of the box support for the design principles mentioned above without any extra effort in research/coding.


Design

1. Any change in the domain model trigger “Validation”

2. As soon as there is an update operation on the domain model field, on which business rules are specified, "Object Model value validation Aspect” will be triggered, which take all the responsibility of:-

a. Find the correct validation as groovy script

b. Inject the above groovy validation as normal java object into the "Domain Model"& perform required validation


Here is the sequence diagram


Summary

1. Using aspect-oriented approach there is no hard coupling between 1 & 2 mentioned above.

2. Since groovy validation is injected into the java object – "DomainObject", there will be no class loading issues.

3. The above design exploits "Single Responsibility Design Principle" via usage of runtime dependency injection and aspect (hence loosely coupled code) of spring. That is, aspect take up the following responsibility and will be coded at one place:-

a. Find the validation for the "DomainObject"value

b. Inject into the target object i.e. "DomainObject"

c. Call the groovy validation using java reflection API (Method Dispatcher).

4. In spring all beans are singleton and thread safe which will avoid memory leaks. This will ensure very fast performance & response time.








Sunday, May 18, 2008

Object Queue/Pooling

Currently I am in design phase of a system which require high throughput and equally very high level for performance. In one of the design meeting, one of the very experienced member in the team make a very interesting remark, lets make object pool, this will increase the performance. Hmmm. That was really interesting for me and inspired me to write this blog on object pooling.

The myth about the object pooling goes like this “Object pooling works. The idea is that we can reuse objects by pooling them on and off free lists instead of using new and letting the garbage collector pick them up. Once you have more than one thread going off the pool, you need a synchronized free list, which has costs. If the list gets hot and contended, you can get scaling bugs. It gets complicated too fast and is not worth it for small to even moderate sized objects. Use it only for large objects.”

Object Pooling is about objects being pre-created and “pooled” for later use. The concept behind object pooling is that it is far cheaper to access an object from a pool of identical objects rather than create a new instance of the object. Creating a new instance involves the following steps:

  1. Loading the class if not already loaded.
  2. Obtaining the required memory from the heap.
  3. Creating an instance of the class within the obtained memory.

In the case of object pooling all these steps would have been performed for a pre-configured number of objects already. It was argued that one of these pre-configured objects could be utilized when a new instance is required. After use, this object would be returned to the pool. The problems with this paradigm are:

Pooling is not cheap. It requires the following steps as part of its execution:

  1. The pool should be locked when the object is being obtained.
  2. The pool needs to be potentially scanned for unused objects.
  3. The object needs to be marked as _used_.
  4. The pool can then be unlocked.

All these steps are not cheap since they involved synchronization locks across multiple threads.

  1. Pooling does not automatically support garbage collection. The object needs to be explicitly returned back to the pool to avoid memory leaks. Isn’t garbage collection one of the most compelling reasons to use Java or a similar language in the first place?
  2. Objects need to be coded to be “stateless”. Otherwise, the object may have to be re-initialized to ensure that it can be re-used back from the pool. This may be a feature of the pooling implementation but would add overhead during deallocation.

Hence it’s pretty conclusive that object pooling make no sense but resource pooling (like connection pool etc) make lots of sense.

Friday, May 9, 2008

OSGi

OSGi: - Open Services Gateway Initiative

Motivation

JEE world buzzwords have always been scalability, transaction management, security, high availability, manageability, monitoring etc. Trust me coming from my personal experience it is a stereotypical statement, but we do understand these problems and have successfully crafted solutions for each of them to an acceptable degree. But the major challenge lies in JEE based application deployment and things have basically remained unchanged since the very origin of JEE. No denying the implementation of modularization is implemented in code by dividing code base in modules, whether logical, physical or conceptual, at runtime they are seen as one monolithic application in which, making a change (be it large or small), requires a restart.

Modularity in java is achieved by using

· Java class files

· Java Archive (JAR) files

1.Provide form of physical modularity

2. May contain applications, extensions, or services

3. May declare dependencies

4. May contain package version and sealing information

Java provides the mechanisms to do these things, but they are

· Low level

· Error prone

· Ad hoc

Java's shortcoming are particular evident in its support for both modularity and dynamism

Java Modularity Limitations

· Limited scoping mechanisms

§ No module access modifier

· Simplistic version handling

1. Class path is first version found

2. JAR files assume backwards compatibility at best

· Implicit dependencies

1. Dependencies are implicit in class path ordering

2. JAR files add improvements for extensions, but cannot control visibility

· Split packages by default

1. Class path approach searches until it finds, which leads to shadowing or version mixing

2. JAR files can provide sealing

· Unsophisticated consistency model

1. Cuts across previous issues, it is difficult to ensure class space consistency

2. Missing module concept

3. Classes are too fine grained, packages are too simplistic, class loaders are too low level

· No deployment support

Java Dynamism Limitation

· Low-level support for dynamics

- Class loaders are complicated to use and error prone

· Support for dynamics is still purely manual

- Must be completely managed by the programmer

- Leads to many ad hoc, incompatible solutions

· Limited deployment support

- Unable to load modified classes at runtime

OSGi

OSGi framework provides

  • Simple component model
  • Component life cycle management
  • Service registry
  • Standard service definitions (separation of specification & implementation)

OSGi Resolves many deficiencies associated with standard Java support for modularity and dynamism

  • Defines a module concept

- Explicit sharing of code (i.e., importing and exporting)

  • Automatic management of code dependencies

- Enforces sophisticated consistency rules for class loading

  • Life-cycle management

- Manages dynamic deployment and configuration

OSGi framework is used as a modularity mechanism for Java and provides logical and physical system structuring. It has benefits for development and deployment. It provides sophisticated dynamic module life-cycle management. It simplifies creation of dynamically extensible systems, where system components can be added, removed, or rebound at run time while the system as a whole continues to function

OSGi framework promotes a service oriented interaction pattern as shown below: -

OSGi Features

  1. Simple component and packaging model

Bundles = JARs and contain java classes, resources and meta-data

That is, bundle represents a single component contained in a JAR file. A bundle defines a logical and physical modularity unit with

· Explicit boundaries

- External interface (i.e., exports)

- Internal class path

Java code, resources, and native libraries

· Explicit dependencies

- Package dependencies (i.e., imports)

· Explicit versioning

- Package version, bundle version

· Isolation via class loaders

· Packaging format (bundle JAR file)

    • Meta-data explicitly defines boundaries & dependencies as java package imports & exports.
    • Dependencies & associated consistency are automatically managed

The framework automatically resolves package dependencies when a bundle is activated

- Matches bundle’s imports to available exports

- Ensures package version consistency

· If a bundle cannot be successfully resolved, then it cannot be activated/used

Hence OSGi is a collection of bundles that interact via service interfaces and these bundles may be independently developed and deployed. Bundles and their associated services may appear or disappear at any time

  1. Defines a component life cycle

OSGi framework defines dynamic bundle life cycle

· Possible to install, update, and uninstall code at run time

· Automatic package dependency resolution

· Replaces low-level class loaders

  1. Explicitly considers dynamic scenarios
  2. Interaction through service interfaces
  3. Multi-version support

That is, it’s possible to have more than one version of a shared package in memory at the same time. As result for a given bundle, the service registry is implicitly partitioned according to the package versions visible to it

  1. Import version range

That is, exporters still export a precise version, but importers may specify an open or closed version range. It also eliminates existing backwards compatibility assumption.

Import-Package: ClaimService; version=“[1.0.0,1.5.0)”

Note: - Multi-version sharing and importing version ranges make implementation package sharing possible

  1. Arbitary export/import attributes

· Exporters may attach arbitrary attributes to their exports, importers can match against these arbitrary attributes

· Exporters may declare attributes as mandatory

· Mandatory attributes provide simple means to limit package visibility

· Importers influence package selection using arbitrary attribute matching

Import-Package: ServiceImpl;

version=“1.0.0”;

myattr=“myvalue”

  1. Package Consitency model

· Exporters may declare package “uses” dependencies

· Exported packages express dependencies on imported or other

exported packages, which constrain the resolve process

· The framework must ensure that importers do not violate constraints implied by “uses” dependencies.

Hence its pretty conclusive OSGi will provide in true sense modularization in java and much needed deployment ease

Wednesday, April 2, 2008

In Memory Computation

I was having a recent chat about caching with someone/group of people and the best part is the magic word used “Caching will improve performance, put it in cache”. It was interesting enough for me/my wife Shikha (she is also a practicing JEE architect) to reflect on and add to my ruminations here in this blog. Just to add this my blog and my ideas and is no way meant to hurt anybody.

The Basic Concept

Yes off course no body can deny, caching is all about performance. The basic rationale behind this is to avoid repeating a complex, input-dependent, stable operation- be it data manipulation, algorithmic computation or expensive calls over the network - by storing the results of the previous computation and returning the results from some kind of a caching repository using some key based on the inputs passed to this operation.

The preceding definition probably has left you more blurry eyed than what you were when you first stumbled on to this page! Like Sherlock Holmes would say, there are certain singular points about caching that are of interest and hence would require further elaboration.

Complex Operation Dependent on Input

Now what is complex operation; I define a complex operation as something that would consume a lot of computing resources. These resources can be CPU resources or network bandwidth or anything else that is sparse and should not be used in a profligate way. This operation should be input dependent, which means that every invocation of this operation must produce the same result given that the inputs are the same. The operation also has to be stable meaning that the results produced by it should not change in a random way. For instance, the results cannot be based on some random number generation or be influenced by the current time of invocation. However, it is acceptable that the results change with time. For instance, it is acceptable to cache data that is editable by the user.

Cache

To re-iterate, the idea in caching is to avoid the computation again by storing the results of the first computation in some place. So where do we store the results? The answer is that we store it somewhere from where we can easily retrieve them again when needed. This place is the caching repository or in short cache. Hence the cache is the place you go to when you want to

  • Store results
  • Retrieve them in a future call.

Cache Key

We have already said that the computation performed by the “cached operation” produces a result that is only dependent on the input parameters and nothing else. Hence by using the input parameters as the key we should be able to retrieve the results of the previous computation without repeating the entire operation once again. This key that is dependent on the input parameters for the operation is called the cache key. The results are stored in the cache using this key. They are also retrieved using this key.

How is Caching implemented?

This is best illustrated with an example.
Consider the diagram below:

The client makes a call to a complex operation. This call is intercepted typically by a caching interceptor, which computes the key from the input parameters and queries the cache with the key. If a value is found in the cache it is returned back to the client thereby bypassing the call to underlying method. Otherwise, the complex operation is invoked and its results are cached into the cache. The results are then returned back to the client. Thus the cache gets updated for future requests.

Types of Caching

  • Reactive
  • Pro-active

The above diagram shows reactive caching wherein the cache is only populated on the first request. The cache would never be populated if there had been no requests with the particular input parameters. A second approach is Pro-active caching where some agent running in the background populates the cache actively. The results are returned from the cache.

A combination of both pro-active and reactive caches is also possible. In this approach, the cache is populated pro-actively. When an actual request is made, the cache is first checked to see if it contains the data that needs to be returned. If the data is found it is returned. Else the cache is first populated reactively as before and returned.

Which cache fits where?

Pro-active caching works well in the following cases:

  • The total number of items in the cache is limited - in other words the total number of cache keys are finite. This is a corollary of another caching axiom - don’t use caching when the memory requirements are expected to be very high.
  • During the life of the application, it is expected that all of the items in the cache are likely to be used at one time or the other.
  • Example of pro-active caches can include caches of all the states within a country, cache of the postal codes etc.

Reactive caching is more suitable when

  • The cache can potentially have a lot of combination of cache keys.
  • The operation is potentially invoked with a vast variation of parameters during the life of the application
  • Reactive caches include caches of all transactions for a particular customer, account information etc. This kind of information tends to be too large to be cached pro-actively. The queries against these kinds of information also tend to be arbitrary. For instance, there might be a lot of accounts whose transactions would never be queried during the life of the application and hence it would be wasteful to cache this kind of information.

The Problems involved in using a cache - A Balancing Act

The use of caching, like any software strategy, tends to become a tight ropewalk dictated by a few parameters, which need to be considered carefully. The biggest problem with caching is that of “cache staleness”. What this means is that the caches can potentially contain data that has since been updated at the source. Hence the data retrieved from the cache becomes stale data and unfit for serious applications. Example: Let us say we are caching account balances. The balance has got updated into the database afterwards thereby resulting in stale data in the cache.

This problem tends to get compounded if the data at the source changes frequently. Hence the following observations prevail:

  • Caching is easy to implement for “static data”
  • Caching for data that changes frequently can only be non-stale if all updates to the data go through the caching layer.

The second point above is interesting. If all the access to the data were accomplished thru the cache, then the cache would automatically be non-stale. Hence isn’t it sensible to keep the cache as close as possible to the source of the data? The answer is a little moot because the whole point of caching is to optimize on the operation. Often the most expensive part of invoking an operation is the network overhead of making this call. If we want to avoid the network overhead, it makes sense to cache the data as close as possible to the consumer of the data and not the producer of the data. Reconciling these two apparently contradictory requirements constitutes an important step in optimizing the cache.

Sunday, December 2, 2007

JDK 6 Script Engine

One of the cool feature of jdk1.6 is the ability to call java script from the java code. Have a look at the sample code, which reverse the string using java script

package com.jdk16;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ReverseUsingJS {
public static void main(String args[]) {
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine engine = scriptManager.getEngineByName("javascript");
try {
engine.put("name", "reverse");
engine.eval("var outputVar = '';for (i = 0; i <= name.length; i++) {"
+ " outputVar = name.charAt(i) + outputVar" + "}");
String name = (String) engine.get("outputVar");
System.out.println(name);
} catch (ScriptException e) {
System.err.println(e);
}
}
}

About Me

Gaurav Malhotra
I am Senior Java Architect expertise in JEE + JEE Open source. I love making JEE framework. I think and breathe java and love discussing on it. Currently I am working business intelligence frameworks for financial companies which provide flexibility for creating/manging dynamic changing business rules changes, business process changes, dynamic UI validation and flexible navigations. My current assignment is of a product eventualist and involved in making Business Rule Management System, on lines of products like Visual rules, ILog JRules. My involvement in this product is as of a Sr Architect and Product Technical Manager doing research for finding features etc along with future for this product Next step in my life, shortly I will be working with Oracle Fusion - Health Care Product line (Europe) Specialties: Business Intelligence frameworks for banks, insurance companies, targetted for the financial market. Business Rules, BPM, ESB, MDA and SOA are my area of interest/learning/research Linked in :- http://www.linkedin.com/profile?viewProfile=&key=11546066
View my complete profile

Arch & Budding Arch

Arch & Budding Arch
Gaurav & Naman