The example POJO classes used for are: Person, Student, and Address. Below are their definition (note that neither class implements Serializable ) along with the annotation.
@org.jboss.cache.pojo.annotation.Replicable public class Person { String name=null; int age=0; Map hobbies=null; Address address=null; Set skills; List languages; public String getName() { return name; } public void setName(String name) { this.name=name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Map getHobbies() { return hobbies; } public void setHobbies(Map hobbies) { this.hobbies = hobbies; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Set getSkills() { return skills; } public void setSkills(Set skills) { this.skills = skills; } public List getLanguages() { return languages; } public void setLanguages(List languages) { this.languages = languages; } }
public class Student extends Person { String year=null; public String getYear() { return year; } public void setYear(String year) { this.year=year; } }
@org.jboss.cache.pojo.annotation.Replicable public class Address { String street=null; String city=null; int zip=0; public String getStreet() { return street; } public void setStreet(String street) { this.street=street; } ... }
Below is a sample xml configuration for Cache that you can use for PojoCache creation.
<?xml version="1.0" encoding="UTF-8" ?> <server> <mbean code="org.jboss.cache.pojo.jmx.PojoCacheJmxWrapper" name="jboss.cache:service=PojoCache"> <depends>jboss:service=TransactionManager</depends> <!-- Configure the TransactionManager --> <attribute name="TransactionManagerLookupClass"> org.jboss.cache.transaction.DummyTransactionManagerLookup </attribute> <!-- Isolation level : SERIALIZABLE REPEATABLE_READ (default) READ_COMMITTED READ_UNCOMMITTED NONE --> <attribute name="IsolationLevel">REPEATABLE_READ</attribute> <!-- Valid modes are LOCAL, REPL_ASYNC and REPL_SYNC --> <attribute name="CacheMode">REPL_SYNC</attribute> <!-- Name of cluster. Needs to be the same for all caches, in order for them to find each other --> <attribute name="ClusterName">PojoCacheCluster</attribute> <!-- JGroups protocol stack properties. --> <attribute name="ClusterConfig"> <config> <!-- UDP: if you have a multihomed machine, set the bind_addr attribute to the appropriate NIC IP address --> <!-- UDP: On Windows machines, because of the media sense feature being broken with multicast (even after disabling media sense) set the loopback attribute to true --> <UDP mcast_addr="228.1.2.3" mcast_port="48866" ip_ttl="64" ip_mcast="true" mcast_send_buf_size="150000" mcast_recv_buf_size="80000" ucast_send_buf_size="150000" ucast_recv_buf_size="80000" loopback="false"/> <PING timeout="2000" num_initial_members="3"/> <MERGE2 min_interval="10000" max_interval="20000"/> <FD shun="true"/> <FD_SOCK/> <VERIFY_SUSPECT timeout="1500"/> <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" max_xmit_size="8192"/> <UNICAST timeout="600,1200,2400",4800/> <pbcast.STABLE desired_avg_gossip="400000"/> <FC max_credits="2000000" min_threshold="0.10"/> <FRAG2 frag_size="8192"/> <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true"/> <pbcast.STATE_TRANSFER/> </config> </attribute> <!-- Whether or not to fetch state on joining a cluster --> <attribute name="FetchInMemoryState">true</attribute> <!-- The max amount of time (in milliseconds) we wait until the initial state (ie. the contents of the cache) are retrieved from existing members in a clustered environment --> <attribute name="InitialStateRetrievalTimeout">15000</attribute> <!-- Number of milliseconds to wait until all responses for a synchronous call have been received. --> <attribute name="SyncReplTimeout">15000</attribute> <!-- Max number of milliseconds to wait for a lock acquisition --> <attribute name="LockAcquisitionTimeout">10000</attribute> </mbean> </server>
Attached is a full listing for pojocache-aop.xml.
<?xml version="1.0" encoding="UTF-8"?> <!-- This is the PojoCache configuration file that specifies: 1. Interceptor stack for API 2. Annotation binding for POJO (via "prepare" element) Basically, this is a variant of jboss-aop.xml. Note that except for the customization of interceptor stack, you should not need to modify this file. To run PojoCache, you will need to define a system property: jboss.aop.path that contains the path to this file such that JBoss Aop can locate it. --> <aop> <!-- This defines the PojoCache 2.0 interceptor stack. Unless necessary, don't modify the stack here! --> <!-- Check id range validity --> <interceptor name="CheckId" class="org.jboss.cache.pojo.interceptors.CheckIdInterceptor" scope="PER_INSTANCE"/> <!-- Track Tx undo operation --> <interceptor name="Undo" class="org.jboss.cache.pojo.interceptors.PojoTxUndoInterceptor" scope="PER_INSTANCE"/> <!-- Begining of interceptor chain --> <interceptor name="Start" class="org.jboss.cache.pojo.interceptors.PojoBeginInterceptor" scope="PER_INSTANCE"/> <!-- Check if we need a local tx for batch processing --> <interceptor name="Tx" class="org.jboss.cache.pojo.interceptors.PojoTxInterceptor" scope="PER_INSTANCE"/> <!-- Mockup failed tx for testing. You will need to set PojoFailedTxMockupInterceptor.setRollback(true) to activate it. --> <interceptor name="MockupTx" class="org.jboss.cache.pojo.interceptors.PojoFailedTxMockupInterceptor" scope="PER_INSTANCE"/> <!-- Perform parent level node locking --> <interceptor name="TxLock" class="org.jboss.cache.pojo.interceptors.PojoTxLockInterceptor" scope="PER_INSTANCE"/> <!-- Interceptor to perform Pojo level rollback --> <interceptor name="TxUndo" class="org.jboss.cache.pojo.interceptors.PojoTxUndoSynchronizationInterceptor" scope="PER_INSTANCE"/> <!-- Interceptor to used to check recursive field interception. --> <interceptor name="Reentrant" class="org.jboss.cache.pojo.interceptors.MethodReentrancyStopperInterceptor" scope="PER_INSTANCE"/> <!-- Whether to allow non-serializable pojo. Default is false. --> <interceptor name="MarshallNonSerializable" class="org.jboss.cache.pojo.interceptors.CheckNonSerializableInterceptor" scope="PER_INSTANCE"> <attribute name="marshallNonSerializable">false</attribute> </interceptor> <!-- This defines the stack macro --> <stack name="Attach"> <interceptor-ref name="Start"/> <interceptor-ref name="CheckId"/> <interceptor-ref name="MarshallNonSerializable"/> <interceptor-ref name="Tx"/> <!-- NOTE: You can comment this out during production although leaving it here is OK. --> <interceptor-ref name="MockupTx"/> <interceptor-ref name="TxLock"/> <interceptor-ref name="TxUndo"/> </stack> <stack name="Detach"> <interceptor-ref name="Start"/> <interceptor-ref name="CheckId"/> <interceptor-ref name="Tx"/> <!-- NOTE: You can comment this out during production although leaving it here is OK. --> <interceptor-ref name="MockupTx"/> <interceptor-ref name="TxLock"/> <interceptor-ref name="TxUndo"/> </stack> <stack name="Find"> <interceptor-ref name="Start"/> <interceptor-ref name="CheckId"/> </stack> <!-- The following section should be READ-ONLY!! It defines the annotation binding to the stack. --> <!-- This binds the jointpoint to specific in-memory operations. Currently in PojoUtil. --> <bind pointcut="execution(* @org.jboss.cache.pojo.annotation.Reentrant->toString())"> <interceptor-ref name="Reentrant"/> </bind> <bind pointcut="execution(* org.jboss.cache.pojo.PojoUtil->@org.jboss.cache.pojo.annotation.TxUndo(..))"> <interceptor-ref name="Undo"/> </bind> <bind pointcut="execution(* org.jboss.cache.pojo.impl.PojoCacheImpl->@org.jboss.cache.pojo.annotation.Attach(..))"> <stack-ref name="Attach"/> </bind> <bind pointcut="execution(* org.jboss.cache.pojo.impl.PojoCacheImpl->@org.jboss.cache.pojo.annotation.Detach(..))"> <stack-ref name="Detach"/> </bind> <bind pointcut="execution(* org.jboss.cache.pojo.impl.PojoCacheImpl->@org.jboss.cache.pojo.annotation.Find(..))"> <stack-ref name="Find"/> </bind> <!-- Following is declaration for JDK50 annotation. You use the specific annotation on your POJO such that it can be instrumented. Idea is user will then need only to annotate like: @org.jboss.cache.pojo.annotation.Replicable in his POJO. There will be no need of jboss-aop.xml from user's side. --> <!-- If a POJO has PojoCachable annotation, it will be asepctized. --> <prepare expr="field(* $instanceof{@org.jboss.cache.pojo.annotation.Replicable}->*)" /> <!-- Observer and Observable to monitor field modification --> <bind pointcut=" set(* $instanceof{@org.jboss.cache.pojo.annotation.Replicable}->*) "> <interceptor class="org.jboss.cache.pojo.observable.SubjectInterceptor"/> </bind> <introduction class="$instanceof{@org.jboss.cache.pojo.annotation.Replicable}"> <mixin> <interfaces>org.jboss.cache.pojo.observable.Subject</interfaces> <class>org.jboss.cache.pojo.observable.SubjectImpl</class> <construction>new org.jboss.cache.pojo.observable.SubjectImpl(this)</construction> </mixin> </introduction> </aop>