In this chapter, you work with complex objects residing in the cache. Using JDeveloper, you will create a new Person
class that is serializable, store and retrieve Person
objects in the cache, and serialize your own objects.
This chapter contains the following sections:
Until now you have been putting and getting String
objects as the value in a NamedCache
. Many of the implementations of the get
and put
methods in the Coherence Java API define the values and keys to be of type Object
. For example:
public java.lang.Object get(java.lang.Object oKey) public void put(java.lang.Object oKey, java.lang.Object oValue)
Any object can potentially be used as a value or key. This enables you to store complex objects as values in the cache.
Because Coherence may need to send the object across the wire, the object must be serializable. Object serialization is the process of saving an object's state into a sequence of bytes, and then rebuilding them into a live object at some future time. For example, objects that implement the java.io.Serializable
interface are serializable.
Coherence supplies its own class for high-performance serialization called com.tangosol.io.pof.PortableObject
. This is up to six times faster than the standard Serializable
and the serialized result set is smaller.
In this exercise you will create a Person
object that has attributes of various data types, and a program that uses Java Serialization to put the object into the cache and retrieve it.
To create complex objects and place them in the cache:
Create a Person
class to store in the cache.
Create a new project in JDeveloper called Lab4
. Hint: Right-click the Coherence application and choose New... In the New Gallery choose Projects under Categories and Generic Project under Items. Click OK.
Figure 3-1 Creating a New Project in the New Gallery
Name the project Lab4
and select Java from Project Technologies. Click Next.
Ensure that the Default Package is com.oracle.coherence.handson
, the Java Source Path is C:\home\oracle\labs\Lab4\src
and the Output Directory is C:\home\oracle\labs\Lab4\classes
. Click Finish.
Figure 3-3 Configuring Java Settings for the New Project
Create a new Java class called Person
. Right click the Lab4
project and select New.... In the New Gallery, choose Java under General and Java Class under Items. Click OK.
Name the Java class Person
. Do not select the Generate Main Method check box. Click OK.
In the JDeveloper code editor, change your class to implement java.io.Serializable
. Hint: Use implements
java.io.Serializable
. Add an import
statement for the java.io.Serializable
class.
Enter the following private attributes for your Person
class. You can add others if you like.
— int id
— String lastname
— String firstname
— String address
— int age
— String gender
The Person
class should look similar to the image in Figure 3-6.
Figure 3-6 Person Class in the JDeveloper Code Editor
JDeveloper can generate the default get/set methods for your attributes. From the Source menu, select Generate Accessors. Select the check box next to the Person
class. All of the attributes are now automatically selected. Click OK to continue.
Figure 3-7 Generating Accessors for the Java Class Attributes
You can also generate the default constructor and equals methods automatically. From the Source menu, select Generate Constructor from Fields, click Select All, and then click OK.
Figure 3-8 Generating Constructors for the Java Class
From the Source menu, select Generate equals () and hashCode(), click Select All, and then click OK.
Figure 3-9 Generating equals() and hashCode() Methods
Change the Java process to be storage-disabled when you run it. right click the project and select Project Properties. In the Project Properties dialog box select Run/Debug/Profile and click Edit. Set Virtual Machine to Server and enter the following values for local storage and log level in the Java Options field of the Edit Run Configuration dialog box.
-Dtangosol.coherence.distributed.localstorage=false -Dtangosol.coherence.log.level=3
Click OK in the Edit Run Configuration dialog box and OK in the Project Properties dialog box to return to the JDeveloper IDE.
Create a driver class called PersonExample
to put
and get
your Person
class.
Create a new Java class called PersonExample
in the Lab4 project. Right click the Lab4
project and select New.... In the New Gallery, choose Java under General and Java Class under Items. Click OK.
Name the Java class PersonExample
. Select the Generate Main Method check box. Click OK.
Figure 3-11 Creating a Java Class with a main() Method
Create a new NamedCache
called person
and put a new instance of the Person
class in it.
Get the person
object from the cache and ensure that the two objects are identical. Example 3-1 illustrates a sample program.
Example 3-1 Comparing an Object from the Cache with the Original
public static void main(String[] args) { NamedCache person = CacheFactory.getCache("person"); Person p1 = new Person(1,"Middleton","Tim", "Level 2, 66 Kings Park Road, West Perth", 39,Person.MALE); person.put(p1.getId(),p1); Person p2 = (Person)person.get(p1.getId()); if (p2.equals(p1)) { System.out.println("They are the same!!"); } }
Note:
You will observe the following error:Type or field 'MALE' not found in Person
. You will resolve this in the next step.Open Person.java
and add the following lines to initialize the gender variable.
static String MALE="M"; static String FEMALE="F";
Add these two lines right after where you declared these attributes:
private int id; private String lastname; private String firstname; private Stringaddress; private intage; private String gender;
Start the cache server.
C:\oracle\product\coherence\bin>cache-server.cmd
Execute PersonExample
and view the result.
Figure 3-12 Results of Running PersonExample.java File
Implement faster serialization: change the Person
class to implement the Coherence PortableObject
class.
Edit the Person
class in JDeveloper and change import java.io.Serializable
to import com.tangosol.io.pof.PortableObject
. Change implements Serializable
to implements PortableObject
. Note that the Person
class now appears with a red underline. If you place your cursor on this, JDeveloper tells you what the problem is.
Methods not implemented: readExternal(PofReader) writeExternal(PofWriter)
Using the PortableObject
class requires that you implement its readExternal(PofReader)
and writeExternal(writeExternal)
methods.
Right-click Person
and choose Code Assist. Select Implement Methods. The Implement Methods dialog box should appear. This generates the required readExternal and writeExternal methods. Accept the defaults and click OK.
Make the following changes to the Person
class. (You may need to import java.io.IOException
.)
Figure 3-14 Implementing the PortableObject.readExternal and writeExternal Methods
Save the changes and rebuild your application.
Create a POF configuration file for person
.
Create a copy of coherence-pof-config.xml
and name it lab4-pof-config.xml
.
Note:
If thecoherence-pof-config.xml
file is not already present in your file system, you can find a copy of it in the coherence.jar
file.cp coherence-pof-config.xml lab4-pof-config.xml
Edit lab4-pof-config.xml
and add a <user-type>
element for Person
to the <user-type-list>
section. Use 1001
as the value for the <type-id>
subelement and the full class name for Person
in the <class-name>
subelement. This is illustrated in Example 3-2.
Save the lab4-pof-config.xml
file in the \home\oracle\labs
directory.
Create a copy of coherence-cache-config.xml
and name it lab4-cache-config.xml
.
Note:
If thecoherence-cache-config.xml
file is not already present in your file system, you can find a copy of it in the coherence.jar
file.cp coherence-cache-config.xml lab4-cache-config.xml
Edit lab4-cache-config.xml
and un-comment the serializer
section for the example-distributed
caching scheme. This is illustrated in Example 3-3.
Example 3-3 Serializer Section in the Cache Configuration File
... <caching-schemes> <!-- Distributed caching scheme. --> <distributed-scheme> <scheme-name>example-distributed</scheme-name> <service-name>DistributedCache</service-name> <!-- To use POF serialization for this partitioned service, uncomment the following section --> <serializer> <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> </serializer> ...
Add an <init-param>
element to the serializer passing the name lab4-pof-config.xml
.
Example 3-4 <init-param> Section in the Cache Configuration File
... <serializer> <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> <init-params> <init-param> <param-value>lab4-pof-config.xml</param-value> <param-type>String</param-type> </init-param> </init-params> </serializer> ...
Stop all cache servers.
Copy cache-server.cmd
to pof-cache-server.cmd
and save the file in the \oracle\product\coherence\bin
directory.
cd /oracle/product/coherence/bin cp cache-server.cmd pof-cache-server.cmd
Edit pof-cache-server.cmd
to point to the lab4-cache-config.xml
file and \home\oracle\labs
directory to the classpath. This is to ensure that the cache can find lab4-pof-config.xml
file at runtime.
Add \home\oracle\labs
to the classpath.
Add the location of Person.class
to your classpath (\home\oracle\labs\Lab4\classes
)
Add COHERENCE_OPTS="-Dtangosol.coherence.cacheconfig=\home\oracle\labs\lab4-cache-config.xml"
Add COHERENCE_OPTS
to the JAVAEXEC
command line. The resulting pof-cache-server.cmd
file should look similar to this:
Example 3-5 Sample pof-cache-config.cmd File
@echo off @ @rem This will start a cache server @ setlocal :config @rem specify the Coherence installation directory set coherence_home=c:\oracle\product\coherence @rem specify the JVM heap size set memory=512m :start if not exist "%coherence_home%\lib\coherence.jar" goto instructions if "%java_home%"=="" (set java_exec=java) else (set java_exec=%java_home%\bin\java) :launch set java_opts="-Xms%memory% -Xmx%memory%" set coherence_opts="-Dtangosol.coherence.log.level=9 -Dtangosol.coherence.cacheconfig=C:/home/oracle/labs/lab4-cache-config.xml" "%java_exec%" -server -showversion "%java_opts%" "%coherence_opts%" -cp "%coherence_home%\lib\coherence.jar;C:\home\oracle\labs\Lab4\classes;C:\home\oracle\labs" com.tangosol.net.DefaultCacheServer %1 goto exit :instructions echo Usage: echo ^<coherence_home^>\bin\pof-cache-server.cmd goto exit :exit endlocal @echo on
Start the cache server by executing the following command:
C:\oracle\product\coherence\bin>pof-cache-server.cmd
Example 3-6 lists sample output from running pof-cache-server.cmd
.
Example 3-6 Starting the POF Cache Server
C:\oracle\product\coherence\bin>pof-cache-server.cmdjava version "1.6.0_05"Java(TM) SE Runtime Environment (build 1.6.0_05-b13)Java HotSpot(TM) Server VM (build 10.0-b19, mixed mode)2008-12-16 18:20:05.665/0.547 Oracle Coherence 3.4.1/407 <Info> (thread=main, member=n/a): Loaded operational configuration from resource "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml"2008-12-16 18:20:05.681/0.563 Oracle Coherence 3.4.1/407 <Info> (thread=main, member=n/a): Loaded operational overrides from resource "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml"2008-12-16 18:20:05.681/0.563 Oracle Coherence 3.4.1/407 <D5> (thread=main, member=n/a): Optional configuration override "/tangosol-coherence-override.xml" is not specified2008-12-16 18:20:05.697/0.579 Oracle Coherence 3.4.1/407 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified2008-12-16 18:20:05.697/0.579 Oracle Coherence 3.4.1/407 <D6> (thread=main, member=n/a): Loaded edition data from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/coherence-grid.xml"Oracle Coherence Version 3.4.1/407 Grid Edition: Development modeCopyright (c) 2000-2008 Oracle. All rights reserved.2008-12-16 18:20:06.400/1.282 Oracle Coherence GE 3.4.1/407 <Info> (thread=main, member=n/a): Loaded cache configuration from file "C:\home\oracle\labs\lab4-cache-config.xml"2008-12-16 18:20:07.322/2.204 Oracle Coherence GE 3.4.1/407 <D5> (thread=Cluster, member=n/a): Service Cluster joined the cluster with senior service member n/a2008-12-16 18:20:07.540/2.422 Oracle Coherence GE 3.4.1/407 <Info> (thread=Cluster, member=n/a): This Member(Id=3, Timestamp=2008-12-16 18:20:07.322, Address=130.35.99.248:8089, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,process:5564, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=1, SocketCount=1) joined cluster "cluster:0x23CB" with senior Member(Id=1, Timestamp=2008-12-16 13:01:46.572, Address=130.35.99.248:8088, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,process:1592, Role=CoherenceConsole, Edition=Grid Edition, Mode=Development, CpuCount=1, SocketCount=1)2008-12-16 18:20:07.837/2.719 Oracle Coherence GE 3.4.1/407 <D5> (thread=DistributedCache, member=3): Service DistributedCache joined the cluster with senior service member 32008-12-16 18:20:07.868/2.750 Oracle Coherence GE 3.4.1/407 <Info> (thread=DistributedCache, member=3): Loading POF configuration from resource "file:/C:/home/o racle/labs/lab4-pof-config.xml" 2008-12-16 18:20:07.884/2.766 Oracle Coherence GE 3.4.1/407 <Info> (thread=Distr ibutedCache, member=3): Loading POF configuration from resource "jar:file:/C:/or acle/product/coherence/lib/coherence.jar!/coherence-pof-config.xml" 2008-12-16 18:20:08.337/3.219 Oracle Coherence GE 3.4.1/407 <D5> (thread=Replica tedCache, member=3): Service ReplicatedCache joined the cluster with senior serv ice member 3 2008-12-16 18:20:08.353/3.235 Oracle Coherence GE 3.4.1/407 <D5> (thread=Optimis ticCache, member=3): Service OptimisticCache joined the cluster with senior serv ice member 3 2008-12-16 18:20:08.384/3.266 Oracle Coherence GE 3.4.1/407 <D5> (thread=Invocat ion:InvocationService, member=3): Service InvocationService joined the cluster w ith senior service member 3 2008-12-16 18:20:08.384/3.266 Oracle Coherence GE 3.4.1/407 <Info> (thread=main, member=3): Started DefaultCacheServer... SafeCluster: Name=cluster:0x23CB Group{Address=224.3.4.1, Port=34407, TTL=4} MasterMemberSet ( ThisMember=Member(Id=3, Timestamp=2008-12-16 18:20:07.322, Address=130.35.99.2 48:8089, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,proces s:5564, Role=CoherenceServer) OldestMember=Member(Id=1, Timestamp=2008-12-16 13:01:46.572, Address=130.35.99 .248:8088, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,proc ess:1592, Role=CoherenceConsole) ActualMemberSet=MemberSet(Size=2, BitSetCount=2 Member(Id=1, Timestamp=2008-12-16 13:01:46.572, Address=130.35.99.248:8088, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,process:1592, R ole=CoherenceConsole) Member(Id=3, Timestamp=2008-12-16 18:20:07.322, Address=130.35.99.248:8089, MachineId=49912, Location=site:us.oracle.com,machine:tpfaeffl-pc,process:5564, R ole=CoherenceServer) ) RecycleMillis=120000 RecycleSet=MemberSet(Size=0, BitSetCount=0 ) ) Services ( TcpRing{TcpSocketAccepter{State=STATE_OPEN, ServerSocket=130.35.99.248:8089},Connections=[]} ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.4, OldestMemberId=1} DistributedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0} ReplicatedCache{Name=ReplicatedCache, State=(SERVICE_STARTED), Id=2, Version=3.0, OldestMemberId=3} Optimistic{Name=OptimisticCache, State=(SERVICE_STARTED), Id=3, Version=3.0, OldestMemberId=3} InvocationService{Name=InvocationService, State=(SERVICE_STARTED), Id=4, Version=3.1, OldestMemberId=3} )2008-12-16 18:20:09.087/3.969 Oracle Coherence GE 3.4.1/407 <D5> (thread=TcpRingListener, member=3): TcpRing: connecting to member 1 using TcpSocket{State=STATE_OPEN, Socket=Socket[addr=/130.35.99.248,port=4044,localport=8089]}
Try to run the POF cache server in JDeveloper. To do this, add additional CLASSPATH
entries to the existing project properties. Navigate to Tools > Project Properties > Libraries and Classpath. Click Add JAR/Directory. In your project, add \home\oracle\labs
to your CLASSPATH
.
Figure 3-15 Adding Labs and Configuration Files to the Classpath
Click Run/Debug/Profile to edit the runtime properties. Append the following line to the existing Java Options.
-Dtangosol.coherence.cacheconfig=C:\home\oracle\labs\lab4-cache-config.xml
Click OK to save your changes to the runtime configuration and OK again to dismiss the Project Properties dialog box.
Rerun PersonExample.java
from the JDeveloper IDE to ensure that it works.
In this example, the Person
object is converted to POF at run time instead of the standard Java serialized format. Using POF should provide significant performance improvements in terms of CPU time and the size of the binary generated.
Figure 3-17 PersonExample Output Run from JDeveloper
In this practice, you create a simple domain object that can be placed into a Coherence cache. This practice assumes that you have a good understanding of Java language serialization rules.
Coherence requires that any non-primitive object placed into its cache be Java-Serializable. This is because the objects may need to be transported across process boundaries, that is, between JVMs, across networks, or processes on the same physical machine. The standard way to transport an object is to serialize, transmit, and then deserialize it. Coherence requires objects to be placed in a cache for them to be serializable.
Create a Java class called EndOfDayStockSummary
that implements the java.io.Serializable
interface.
The purpose of this file is to capture the open, high, low, close, and adjusted close prices (in dollars) of a stock (called a symbol) for a specific date, with the trading volume. The variables in Example 3-7 can be the attribute definitions for the class:
Example 3-7 Attributes for a Sample Serializable Class
private String symbol private long date private double openPrice private double highPrice private double lowPrice private double closePrice private double adjustedClosePrice private long volume
Define a method called getKey()
to return a String
that is a combination of the symbol and date attributes.
Declare serialVersionUID
.
Define a public default constructor EndOfDayStockSummary()
.
Define a public constructor that accepts values for all the attributes specified.
Example 3-8 illustrates a sample solution.
Example 3-8 Sample Domain Object for the Coherence Cache
package com.oracle.coherence.handson; import java.io.Serializable; import java.util.Date; public class EndOfDayStockSummary implements Serializable { private static final long serialVersionUID = -200684451000777011L; private String symbol; private long date; private double openPrice; private double highPrice; private double lowPrice; private double closePrice; private double adjustedClosePrice; private long volume; public EndOfDayStockSummary() { //for Java Serialization. not to be called directly by application code } public EndOfDayStockSummary(String symbol, long date, double openPrice, double highPrice, double lowPrice, double closePrice, double adjustedClosePrice, long volume) { this.symbol = symbol; this.date = date; this.openPrice = openPrice; this.highPrice = highPrice; this.lowPrice = lowPrice; this.closePrice = closePrice; this.adjustedClosePrice = adjustedClosePrice; this.volume = volume; } public String getKey() { return symbol + date; } public String getSymbol() { return symbol; } public long getDate() { return date; } public double getOpenPrice() { return openPrice; } public double getHighPrice() { return highPrice; } public double getLowPrice() { return lowPrice; } public double getClosePrice() { return closePrice; } public double getAdjustedClosePrice() { return adjustedClosePrice; } public long getVolume() { return volume; } public String toString() { return String.format("EndOfDayPrice{symbol=%s, date=%s, open=%f, high=%f, low=%f, close=%f, adj-close=%f, volume=%d}", symbol, new Date(date), openPrice, highPrice, lowPrice, closePrice, adjustedClosePrice, volume); } }
Create a console application called CacheAnObject
which contains a main
method.
In the application, create an instance of the EndOfDayStockSummary
class and use the NamedCache
put
method to place it into a Coherence cache called dist-eodStockSummaries
. The application should then retrieve the summery and display it in the console.
Example 3-9 illustrates a sample solution.
Example 3-9 Sample Console Application
import java.util.Date; import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache; public class CacheAnObject { public static void main(String[] args) { CacheFactory.ensureCluster(); NamedCache namedCache = CacheFactory.getCache("dist-eodStockSummaries"); EndOfDayStockSummary eodStockSummary = new EndOfDayStockSummary("orcl", new Date().getTime(), 25.00, 27.00, 24.00, 26.00, 26.00, 1000); namedCache.put(eodStockSummary.getKey(), eodStockSummary); System.out.println(namedCache.get(eodStockSummary.getKey())); CacheFactory.shutdown(); } }
Edit the Lab4 Project Properties and modify the Run/Debug/Profile configuration. Remove the following line from the existing Java Options if it is present.
-Dtangosol.coherence.cacheconfig=\home\oracle\labs\lab4-cache-config.xml
This field should still contain the following lines:
-Dtangosol.coherence.distributed.localstorage=false -Dtangosol.coherence.log.level=3
Figure 3-18 Project Properties for the EndOfDayStockSummary Application
Edit cache-server.cmd
and add the following:
Add \home\oracle\labs
to the classpath.
Add the location of Person.class
to your classpath (\home\oracle\labs\Lab4\classes
)
Ensure that all other cache servers are shut down and execute cache-server.cmd
. Ensure that the cache server starts successfully, then shut it down.
Execute CacheAnObject
from the JDeveloper IDE and observe the results.
Figure 3-19 Output from the CacheAnObject Console Application
In this exercise, you improve the serialization performance of domain objects placed in the Coherence cache using the com.tangosol.io.pof.PortableObject
interface.
This exercise assumes that you have successfully completed the previous section, "Caching a Complex Object using Java Serialization".
Standard Java serialization performance is often a significant bottleneck for applications that communicate across process boundaries, especially those that depend on networks. Java serialization also produces serialization streams that are often very verbose in their binary format, typically containing much more information than required by an application. It is also possible that the streams are encoded in such a manner that it is inefficient to send across a network, or to construct and destruct in a Java heap (memory). This consequently leads to increased garbage collection requirements.
To resolve some of these issues, including dramatically improving serialization performance, reducing the binary format size, and reducing the impact on garbage collection, Coherence provides its own proprietary serialization known as the PortableObject
format. The PortableObject
interface introduces two simple methods, readExternal
and writeExternal
, that permit a developer to explicitly read and write serialized object attributes from the provided PofReader
and PofWriter
streams respectively. By taking control over the serialization format, Coherence provides a way to dramatically improve the performance of the process. Using POF will dramatically reduce the size of the resulting binary. The size of the binary is often 5 to 10x smaller, and the conversion to-or-from the binary can be between 5 and 20 times faster, depending on the size of the object.
Note:
Properties in POF are indexed and they should be read from the same index they were written to.To implement PortableObject
serialization format:
Modify the EndOfDayStockSummary
class from the previous exercise to implement the com.tangosol.io.pof.PortableObject
interface.
Using the methods defined in com.tangosol.io.pof.PofReader
class and com.tangosol.io.pof.PofWriter
the non-static methods defined in the DataInput
and DataOutput
streams, implement the readExternal
and writeExternal
methods.
Example 3-10 Sample PortableObject Implementation
package com.oracle.coherence.handson; import java.io.IOException; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PofWriter; import com.tangosol.io.pof.PortableObject; import java.util.Date; public class EndOfDayStockSummary implements PortableObject { private static final long serialVersionUID = -200684451000777011L; private String symbol; private long date; private double openPrice; private double highPrice; private double lowPrice; private double closePrice; private double adjustedClosePrice; private long volume; public EndOfDayStockSummary() { //for Java Serialization. not to be called directly by application code } public EndOfDayStockSummary(String symbol, long date, double openPrice, double highPrice, double lowPrice, double closePrice, double adjustedClosePrice, long volume) { this.symbol = symbol; this.date = date; this.openPrice = openPrice; this.highPrice = highPrice; this.lowPrice = lowPrice; this.closePrice = closePrice; this.adjustedClosePrice = adjustedClosePrice; this.volume = volume; } public String getKey() { return symbol + date; } public String getSymbol() { return symbol; } public long getDate() { return date; } public double getOpenPrice() { return openPrice; } public double getHighPrice() { return highPrice; } public double getLowPrice() { return lowPrice; } public double getClosePrice() { return closePrice; } public double getAdjustedClosePrice() { return adjustedClosePrice; } public long getVolume() { return volume; } public String toString() { return String.format("EndOfDayPrice{symbol=%s, date=%s, open=%f, high=%f, low=%f, close=%f, adj-close=%f, volume=%d}", symbol, new Date(date), openPrice, highPrice, lowPrice, closePrice, adjustedClosePrice, volume); } public void readExternal(PofReader pofReader) throws IOException { symbol=pofReader.readString(0); date=pofReader.readLong(1); openPrice=pofReader.readDouble(2); lowPrice=pofReader.readDouble(3); highPrice=pofReader.readDouble(4); closePrice=pofReader.readDouble(5); adjustedClosePrice=pofReader.readDouble(6); volume=pofReader.readLong(7); } public void writeExternal(PofWriter pofWriter) throws IOException { pofWriter.writeString(0, symbol); pofWriter.writeLong(1, date); pofWriter.writeDouble(2, openPrice); pofWriter.writeDouble(3, highPrice); pofWriter.writeDouble(4, lowPrice); pofWriter.writeDouble(5, closePrice); pofWriter.writeDouble(6, adjustedClosePrice); pofWriter.writeLong(7, volume); } }
Modify lab4-pof-config.xml
in \home\oracle\labs
to have an entry for EndOfDayStockSummary
. Hint: You can change <type-id>
to 1002
and <class-name>
to com.oracle.coherence.handson.EndOfDayStockSummary
.
Edit the Lab4 Project Properties and modify the Run/Debug/Profile configuration. Append the following line to the existing Java Options:
-Dtangosol.coherence.cacheconfig=\home\oracle\labs\lab4-cache-config.xml
Figure 3-20 Setting Java Options for the PortableObject Implementation
Save the changes and rebuild your application.
Ensure that all other cache servers are shut down and execute pof-cache-server.cmd
on the command line
C:\oracle\product\coherence\bin>pof-cache-server.cmd
In the output from the server startup, you should see lines similar to those in Example 3-11 that indicate that a POF configuration is being employed.
Example 3-11 Output from Starting the Server with a POF Configuration
... 2008-12-17 18:47:12.900/3.407 Oracle Coherence GE 3.4.1/407 <Info> (thread=Distr ibutedCache, member=2): Loading POF configuration from resource "file:/C:/home/o racle/labs/lab4-pof-config.xml" 2008-12-17 18:47:12.931/3.438 Oracle Coherence GE 3.4.1/407 <Info> (thread=Distr ibutedCache, member=2): Loading POF configuration from resource "jar:file:/C:/or acle/product/coherence/lib/coherence.jar!/coherence-pof-config.xml" 2008-12-17 18:47:13.431/3.938 Oracle Coherence GE 3.4.1/407 <D5> (thread=Replica tedCache, member=2): Service ReplicatedCache joined the cluster with senior serv ice member 2 2008-12-17 18:47:13.462/3.969 Oracle Coherence GE 3.4.1/407 <D5> (thread=Optimis ticCache, member=2): Service OptimisticCache joined the cluster with senior serv ice member 2 2008-12-17 18:47:13.478/3.985 Oracle Coherence GE 3.4.1/407 <D5> (thread=Invocat ion:InvocationService, member=2): Service InvocationService joined the cluster w ith senior service member 2 2008-12-17 18:47:13.478/3.985 Oracle Coherence GE 3.4.1/407 <Info> (thread=main, member=2): Started DefaultCacheServer... ...
Verify that your CacheAnObject.java
class from the previous exercise uses the EndOfDayStockSummary
that implemented PortableObject
. Run CacheAnObject
from the JDeveloper IDE.
Figure 3-21 Running EndOfDayStockSummary with a PortableObject Implementation
It is important to keep the order of the attributes and their indexes consistent between the readExternal
and writeExternal
methods. As an experiment, try changing the index of the object attributes written in the writeExternal
method to be different from the index of the reading object attributes in the readExternal
method.
For example, change the order of the openPrice
and lowPrice
attributes and indexes as they currently appear in the writeExternal
method:
... pofWriter.writeDouble(2, openPrice); pofWriter.writeDouble(3, highPrice); pofWriter.writeDouble(4, lowPrice); ...
to this order:
... pofWriter.writeDouble(2, lowPrice); pofWriter.writeDouble(3, highPrice); pofWriter.writeDouble(4, openPrice); ...
Run CacheAnObject.java
again. Notice that the assigned values in the output are transposed.