この演習では、キャッシュ内にある複合オブジェクトを操作します。ここでは、Coherence APIのPofReader
、PofWriter
およびPortableObject
の使用について取り上げます。Eclipseを使用して新しいContact
クラスを作成し、Portable Object Format (POF)シリアライズを使用してキャッシュにContact
オブジェクトを格納し、格納したオブジェクトを取得します。
この章には次の項が含まれます:
これまで、NamedCache
キャッシュでString
オブジェクトを値として挿入および取得してきました。Coherence Java APIのget
メソッドおよびput
メソッドの実装の多くでは、値とキーをObject
タイプとして定義します。次に例を示します。
public java.lang.Object get(java.lang.Object oKey) public void put(java.lang.Object oKey, java.lang.Object oValue)
どのオブジェクトも値またはキーとして使用できます。これにより、複合オブジェクトを値としてキャッシュに格納できます。
Coherenceではオブジェクトをワイヤ経由で送信することがあるため、オブジェクトはシリアライズ可能である必要があります。オブジェクトのシリアライズは、オブジェクトの状態を一連のバイトとして保存し、その後、バイトを再ビルド(デシリアライズ)してアクティブなオブジェクトにするプロセスです。たとえば、java.io.Serializable
インタフェースを実装するオブジェクトはシリアライズ可能です。
Javaのjava.io.Serializable
インタフェースを使用するかわりに、高性能のシリアライズを目的としたCoherence独自のクラスcom.tangosol.io.pof.PortableObject
を使用することによってパフォーマンスを向上させることができます。PortableObject
形式は、標準のSerializable
と比べると速度が最大6倍で、シリアライズ後の結果セットは小さくなります。
PortableObject
インタフェースにはreadExternal
およびwriteExternal
という2つの単純なメソッドが用意されており、提供されているPofReader
ストリームおよびPofWriter
ストリームからそれぞれ、シリアライズされたオブジェクト属性の読取りと書込みを明示的に行うことができます。シリアライズ形式を制御することによって、Coherenceではプロセスのパフォーマンスを向上させることができます。POFを使用すると、生成されるバイナリ・ファイルのサイズが縮小されます。多くの場合、バイナリ・ファイルのサイズは5分の1 - 10分の1になり、バイナリ・ファイルとの間の変換速度は、オブジェクトのサイズに応じて5 - 20倍になることがあります。
この演習では、従業員の名前、住所、誕生日および電話番号を格納するContact
オブジェクトを作成します。また、POFシリアライズを使用して、PortableObject
インタフェースを実装することによりキャッシュにオブジェクトを挿入し、挿入したオブジェクトを取得します。
ここでは、後で別のデータ・オブジェクトに組み込まれる2つのデータ・オブジェクトの作成方法について説明します。Address
オブジェクトは従業員の住所情報を提供し、PhoneNumber
オブジェクトは電話連絡先情報を提供します。
従業員の住所情報を格納するAddress
オブジェクトを作成します。
Eclipseで、Contacts
という新しいアプリケーション・クライアント・プロジェクトを作成します。開始ページの「Configuration」フィールドでCoherenceConfig
が選択されていることと、「Application Client module」ページで「Create a default main」が選択されていないことを確認します。
詳細は、「Eclipse IDEでの新規プロジェクトの作成」を参照してください。
Address
という新しいJavaクラスを作成します。「Default Package」がcom.oracle.handson
であることを確認します。「Main Method」チェック・ボックスは選択しないでください。詳細は、「Javaクラスの作成」を参照してください。
データのシリアライズにPortableObject
インタフェースを使用するようにクラスを記述します。Eclipseコード・エディタで、生成したAddress
クラスを、com.tangosol.io.pof.PortableObject
を実装するように変更します。PortableObject
インタフェースのimport
文を追加します。
Portable
Object
インタフェースで必要なcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
インタフェースで必要なAddress
のパブリックなデフォルト・コントラクタを追加します。
Address
クラスの次のプライベート属性を入力します。必要に応じて他の属性を追加することもできます。
— String Street1
— String Street2
— String City
— String State
— String Country
この時点で、Address
クラスは次のようになります。
package com.oracle.handson; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PortableObject; import com.tangosol.io.pof.PofWriter; import java.io.IOException; public class Address implements PortableObject { private String Street1; private String Street2; private String City; private String State; private String Zip; private String Country; /** * Default constructor (necessary for PortableObject implementation). */ public Address() { } }
Eclipseでは、作成した属性についてデフォルトのget
メソッドおよびset
メソッドを生成できます。「Source」メニューから、「Generate Getters and Setters」を選択します。「Select All」をクリックして、クラス内のすべての属性を選択します。すべての属性が自動的に選択されます。「OK」をクリックして続行します。
図4-1に、Address
クラスのアクセッサを生成する「Generate Getters and Setters」ダイアログ・ボックスを示します。
デフォルトのコンストラクタおよびequals
メソッドを自動的に生成することもできます。「Source」メニューから、「Generate Constructor using Fields」を選択し、「Select All」をクリックして、「OK」をクリックします。
図4-2に、Street1
、Street2
、City
、State
、Zip
およびCountry
の各フィールドを選択した「Generate Constructor using Fields」ダイアログ・ボックスを示します。
図4-2 「Generate Constructors using Fields」ダイアログ・ボックス
生成されたコンストラクタのメンバーにthis
を追加します。生成されたコンストラクタは次のようになります。
public Address(String Street1, String Street2, String City, String State, String Zip, String Country) { super(); this.Street1 = Street1; this.Street2 = Street2; this.City = City; this.State = State; this.Zip = Zip; this.Country = Country; }
PortableObject
インタフェースでの必要に応じて、readExternal
メソッドおよびwriteExternal
メソッドを実装します。たとえば、readExternal
メソッドを次のように実装すると、street、city、stateおよびcountryの値をPOFオブジェクトとして読み取ることができます。
public void readExternal(PofReader reader) throws IOException { setStreet1(reader.readString(0)); setStreet2(reader.readString(1)); setCity(reader.readString(2)); setState(reader.readString(3)); setZip(reader.readString(4)); setCountry(reader.readString(5)); }
equals
、hashCode
およびtoString
の各オブジェクト・メソッドを実装します。
注意: キャッシュのキーと値は、シリアライズ可能(たとえば、 |
これらのメソッドをサポートするには、com.tangosol.util.Base
クラスとcom.tangosol.util.HashHelper
クラスをインポートします。Base
クラスは、equals
メソッドのサポートを提供します。HashHelper
クラスには、任意のグループのJava組込み関数のハッシュ・コード値を計算するためのヘルパー関数が格納されています。
次のコードは、equals()
メソッドの実装例を示しています。
public boolean equals(Object oThat) { if (this == oThat) { return true; } if (oThat == null) { return false; } Address that = (Address) oThat; return Base.equals(getStreet1(), that.getStreet1()) && Base.equals(getStreet2(), that.getStreet2()) && Base.equals(getCity(), that.getCity()) && Base.equals(getState(), that.getState()) && Base.equals(getZip(), that.getZip()) && Base.equals(getCountry(), that.getCountry()); }
次のコードは、hashCode()
メソッドの実装例を示しています。
public int hashCode() { return HashHelper.hash(getStreet1(), HashHelper.hash(getStreet2(), HashHelper.hash(getZip(), 0))); }
次のコードは、toString()
メソッドの実装例を示しています。
public String toString() { return getStreet1() + "\n" + getStreet2() + "\n" + getCity() + ", " + getState() + " " + getZip() + "\n" + getCountry(); }
作成されたクラスは例4-1のようになります。
例4-1 Addressクラスの実装
package com.oracle.handson; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PortableObject; import com.tangosol.io.pof.PofWriter; import com.tangosol.util.Base; import com.tangosol.util.HashHelper; import java.io.IOException; public class Address implements PortableObject { private String Street1; private String Street2; private String City; private String State; private String Zip; private String Country; /** * Default constructor (necessary for PortableObject implementation). */ public Address() { } public Address(String Street1, String Street2, String City, String State, String Zip, String Country) { super(); this.Street1 = Street1; this.Street2 = Street2; this.City = City; this.State = State; this.Zip = Zip; this.Country = Country; } //------------ accessors-------------------------------- public void setStreet1(String Street1) { this.Street1 = Street1; } public String getStreet1() { return Street1; } public void setStreet2(String Street2) { this.Street2 = Street2; } public String getStreet2() { return Street2; } public void setCity(String City) { this.City = City; } public String getCity() { return City; } public void setState(String State) { this.State = State; } public String getState() { return State; } public void setZip(String Zip) { this.Zip = Zip; } public String getZip() { return Zip; } public void setCountry(String Country) { this.Country = Country; } public String getCountry() { return Country; } // -------- PortableObject Interface------------------------------ public void readExternal(PofReader reader) throws IOException { setStreet1(reader.readString(0)); setStreet2(reader.readString(1)); setCity(reader.readString(2)); setState(reader.readString(3)); setZip(reader.readString(4)); setCountry(reader.readString(5)); } public void writeExternal(PofWriter writer) throws IOException { writer.writeString(0, getStreet1()); writer.writeString(1, getStreet2()); writer.writeString(2, getCity()); writer.writeString(3, getState()); writer.writeString(4, getZip()); writer.writeString(5, getCountry()); } // ----- Object methods -------------------------------------------------- public boolean equals(Object oThat) { if (this == oThat) { return true; } if (oThat == null) { return false; } Address that = (Address) oThat; return Base.equals(getStreet1(), that.getStreet1()) && Base.equals(getStreet2(), that.getStreet2()) && Base.equals(getCity(), that.getCity()) && Base.equals(getState(), that.getState()) && Base.equals(getZip(), that.getZip()) && Base.equals(getCountry(), that.getCountry()); } public int hashCode() { return HashHelper.hash(getStreet1(), HashHelper.hash(getStreet2(), HashHelper.hash(getZip(), 0))); } public String toString() { return getStreet1() + "\n" + getStreet2() + "\n" + getCity() + ", " + getState() + " " + getZip() + "\n" + getCountry(); } }
電話連絡先データを格納するPhoneNumber
クラスを作成します。
PhoneNumber
という新しいJavaクラスを作成します。main
メソッドは含めないでください。
詳細は、「Javaクラスの作成」を参照してください。
データのシリアライズにPortableObject
インタフェースを使用します。Eclipseコード・エディタで、生成したPhoneNumber
クラスを、PortableObject
を実装するように変更します。com.tangosol.io.pof.PortableObject
インタフェースのimport
文を追加します。
Portable
Object
インタフェースで必要なcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
インタフェースで必要なPhoneNumber
クラスのパブリックなデフォルト・コントラクタを追加します。
PhoneNumber
クラスの次のプライベート属性を入力します。他の属性を追加することもできます。
—short AccessCode
—short CountryCode
—short AreaCode
—int LocalNumber
Eclipseでは、作成した属性についてデフォルトのget
メソッドおよびset
メソッドを生成できます。「Source」メニューから、「Generate Getters and Setters」を選択します。「Select All」をクリックして、クラス内のすべての属性を選択します。すべての属性が自動的に選択されます。「OK」をクリックして続行します。
デフォルトのコンストラクタおよびequals
メソッドを自動的に生成することもできます。「Source」メニューから、「Generate Constructor using Fields」を選択し、「Select All」をクリックして、「OK」をクリックします。
生成されたコンストラクタのメンバーにthis
を追加します。生成されたコンストラクタは次のようになります。
public PhoneNumber(short AccessCode, short CountryCode, short AreaCode, int LocalNumber) { super(); this.AccessCode = AccessCode; this.CountryCode = CountryCode; this.AreaCode = AreaCode; this.LocalNumber = LocalNumber; }
PortableObject
インタフェースでの必要に応じて、readExternal
メソッドおよびwriteExternal
メソッドを実装します。
equals
、hashCode
およびtoString
の各オブジェクト・メソッドを実装します。
作成されたクラスは例4-2のようになります。
例4-2 PhoneNumberクラスの実装
package com.oracle.handson; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PofWriter; import com.tangosol.io.pof.PortableObject; import com.tangosol.util.HashHelper; import java.io.IOException; public class PhoneNumber implements PortableObject { private short AccessCode; private short CountryCode; private short AreaCode; private int LocalNumber; //------------ constructors -------------------------------- /** * Default constructor (necessary for PortableObject implementation). */ public PhoneNumber() { } public PhoneNumber(short AccessCode, short CountryCode, short AreaCode, int LocalNumber) { super(); this.AccessCode = AccessCode; this.CountryCode = CountryCode; this.AreaCode = AreaCode; this.LocalNumber = LocalNumber; } //------------ accessors-------------------------------- public void setAccessCode(short AccessCode) { this.AccessCode = AccessCode; } public short getAccessCode() { return AccessCode; } public void setCountryCode(short CountryCode) { this.CountryCode = CountryCode; } public short getCountryCode() { return CountryCode; } public void setAreaCode(short AreaCode) { this.AreaCode = AreaCode; } public short getAreaCode() { return AreaCode; } public void setLocalNumber(int LocalNumber) { this.LocalNumber = LocalNumber; } public int getLocalNumber() { return LocalNumber; } // -------- PortableObject Interface------------------------------ public void readExternal(PofReader reader) throws IOException { setAccessCode(reader.readShort(0)); setCountryCode(reader.readShort(1)); setAreaCode(reader.readShort(2)); setLocalNumber(reader.readInt(3)); } public void writeExternal(PofWriter writer) throws IOException { writer.writeShort(0, getAccessCode()); writer.writeShort(1, getCountryCode()); writer.writeShort(2, getAreaCode()); writer.writeInt(3, getLocalNumber()); } // ----- Object methods ------------------------------------------------- /** * {@inheritDoc} */ public boolean equals(Object oThat) { if (this == oThat) { return true; } if (oThat == null) { return false; } PhoneNumber that = (PhoneNumber) oThat; return getAccessCode() == that.getAccessCode() && getCountryCode() == that.getCountryCode() && getAreaCode() == that.getAreaCode() && getLocalNumber() == that.getLocalNumber(); } /** * {@inheritDoc} */ public int hashCode() { return HashHelper.hash(getAreaCode(), HashHelper.hash(getLocalNumber(), 0)); } /** * {@inheritDoc} */ public String toString() { return "+" + getAccessCode() + " " + getCountryCode() + " " + getAreaCode() + " " + getLocalNumber(); } }
Contact
オブジェクトは、Address
データ・オブジェクトとPhoneNumber
データ・オブジェクトを組み込むことによって、従業員の名前、住所および電話番号の情報を提供します。
Contact
という新しいJavaクラスを作成します。main
メソッドは含めないでください。
詳細は、「Javaクラスの作成」を参照してください。
このクラスではデータのシリアライズにPortableObject
インタフェースを使用するため、Eclipseコード・エディタで、生成したContact
クラスを、PortableObject
を実装するように変更します。com.tangosol.io.pof.PortableObject
インタフェースのimport
文を追加します。
Portable
Object
で必要なcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
で必要なContact
のパブリックなデフォルト・コントラクタを追加します。
Contact
クラスの次のプライベート属性を入力します。他の属性を追加することもできます。
String FirstName
String LastName
Address HomeAddress
Address WorkAddress
Map TelephoneNumbers
java.sql.Date BirthDate
Eclipseでは、作成した属性についてデフォルトのget
メソッドおよびset
メソッドを生成できます。「Source」メニューから、「Generate Getters and Setters」を選択します。「Select All」をクリックして、クラス内のすべての属性を選択します。「OK」をクリックして続行します。
従業員の年齢を計算するアクセッサgetAge
を作成します。
public int getAge() { return (int) ((System.currentTimeMillis() - BirthDate.getTime()) / MILLIS_IN_YEAR); }
MILLIS_IN_YEAR
の定義を追加します。
public static final long MILLIS_IN_YEAR = 1000L * 60L * 60L * 24L * 365L;
デフォルトのコンストラクタを自動的に生成できます。「Source」メニューから、「Generate Constructor using Fields」を選択し、「Select All」をクリックして、「OK」をクリックします。
生成されたコンストラクタは次のようになります。
public Contact(String FirstName, String LastName, Address HomeAddress, Address WorkAddress, Map TelephoneNumbers, Date BirthDate) { super(); this.FirstName = FirstName; this.LastName = LastName; this.HomeAddress = HomeAddress; this.WorkAddress = WorkAddress; this.TelephoneNumbers = TelephoneNumbers; this.BirthDate = BirthDate; }
PortableObject
インタフェースでの必要に応じて、readExternal
メソッドおよびwriteExternal
メソッドを実装します。
equals
、hashCode
およびtoString
の各オブジェクト・メソッドを実装します。
作成されたクラスは例4-3のようになります。
例4-3 Contactクラスのサンプル
package com.oracle.handson; import com.tangosol.io.pof.PortableObject; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PofWriter; import java.io.IOException; import java.sql.Date; import java.util.Iterator; import java.util.Map; public class Contact implements PortableObject { private String FirstName; private String LastName; private Address HomeAddress; private Address WorkAddress; private Map TelephoneNumbers; private java.sql.Date BirthDate; // ----- constructors --------------------------------------------------- /** * Default constructor (necessary for PortableObject implementation). */ public Contact() { } public Contact(String FirstName, String LastName, Address HomeAddress, Address WorkAddress, Map TelephoneNumbers, Date BirthDate) { super(); this.FirstName = FirstName; this.LastName = LastName; this.HomeAddress = HomeAddress; this.WorkAddress = WorkAddress; this.TelephoneNumbers = TelephoneNumbers; this.BirthDate = BirthDate; } // -------- accessors -------------------------------------------- public void setFirstName(String FirstName) { this.FirstName = FirstName; } public String getFirstName() { return FirstName; } public void setLastName(String LastName) { this.LastName = LastName; } public String getLastName() { return LastName; } public void setHomeAddress(Address HomeAddress) { this.HomeAddress = HomeAddress; } public Address getHomeAddress() { return HomeAddress; } public void setWorkAddress(Address WorkAddress) { this.WorkAddress = WorkAddress; } public Address getWorkAddress() { return WorkAddress; } public void setTelephoneNumbers(Map TelephoneNumbers) { this.TelephoneNumbers = TelephoneNumbers; } public Map getTelephoneNumbers() { return TelephoneNumbers; } public void setBirthDate(Date BirthDate) { this.BirthDate = BirthDate; } public Date getBirthDate() { return BirthDate; } /** * Get age. * * @return age */ public int getAge() { return (int) ((System.currentTimeMillis() - BirthDate.getTime()) / MILLIS_IN_YEAR); } // ----- PortableObject interface --------------------------------------- /** * {@inheritDoc} */ public void readExternal(PofReader reader) throws IOException { setFirstName(reader.readString(0)); setLastName(reader.readString(1)); setHomeAddress((Address) reader.readObject(2)); setWorkAddress((Address) reader.readObject(3)); setTelephoneNumbers(reader.readMap(4, null)); setBirthDate(new Date(reader.readLong(5))); } /** * {@inheritDoc} */ public void writeExternal(PofWriter writer) throws IOException { writer.writeString(0, getFirstName()); writer.writeString(1, getLastName()); writer.writeObject(2, getHomeAddress()); writer.writeObject(3, getWorkAddress()); writer.writeMap(4, getTelephoneNumbers()); writer.writeLong(5, getBirthDate().getTime()); } // ----- Object methods ------------------------------------------------- /** * {@inheritDoc} */ public String toString() { StringBuffer sb = new StringBuffer(getFirstName()) .append(" ") .append(getLastName()) .append("\nAddresses") .append("\nHome: ").append(getHomeAddress()) .append("\nWork: ").append(getWorkAddress()) .append("\nTelephone Numbers"); for (Iterator iter = TelephoneNumbers.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); sb.append("\n") .append(entry.getKey()).append(": ").append(entry.getValue()); } return sb.append("\nBirth Date: ").append(getBirthDate()).toString(); } /** * Approximate number of millis in a year ignoring things such as leap * years. Suitable for example use only. */ public static final long MILLIS_IN_YEAR = 1000L * 60L * 60L * 24L * 365L; }
Contact
エントリをキャッシュに挿入し、挿入したエントリを取得する、ContactDriver
というドライバ・クラスを作成します。
Contacts
プロジェクト内にContactDriver
という新しいJavaクラスを作成します。main
メソッドを含むようにしてください。
詳細は、「Javaクラスの作成」を参照してください。
ContactDriver
クラスで、contact
という新しいNamedCache
を作成し、Contact
オブジェクトの新しいインスタンスを挿入します。キャッシュからContact
オブジェクトを取得し、2つのオブジェクトが同一であることを確認します。例4-4は、このクラスの実装例を示しています。
例4-4 ContactDriverクラスのサンプル
package com.oracle.handson; import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache; import java.sql.Date; import java.util.GregorianCalendar; import java.util.Map; import java.util.HashMap; public class ContactDriver { public ContactDriver() { } public static void main(String[] args) { NamedCache contact = CacheFactory.getCache("contact"); Address homeAddress = new Address ("4157 Wash Ave", "Suite 4", "Burlingame", "CA", "94407", "USA"); Address workAddress = new Address ("500 Oracle Pkwy", "MS989", "Redwood Shores", "CA", "94065", "USA"); Date date = new java.sql.Date(new GregorianCalendar(2011, 05, 01).getTime().getTime()); PhoneNumber phonenumber = new PhoneNumber ((short)11, (short)650, (short)506, 7000); Map map = new HashMap(); map.put("home", phonenumber); Contact con1 = new Contact("Tom", "Dunn", homeAddress, workAddress, map, date); contact.put(con1.getFirstName(),con1); Contact con2 = (Contact)contact.get(con1.getFirstName()); if (con2.getFirstName().equals(con1.getFirstName())) { System.out.println("They are the same!!"); } } }
POFシリアライズを使用するには、ユーザー定義オブジェクトをPOF構成ファイルに登録する必要があります。この構成によって、ユーザー定義オブジェクトのクラスが数値に関連付けられます。また、POFシリアライズおよびPOF構成ファイル名をキャッシュ構成ファイルで指定する必要があります。
Contact
オブジェクト、Address
オブジェクトおよびPhoneNumber
オブジェクトのPOF構成ファイルを作成します。
独自のデータ型のPOF構成ファイルを作成するには、プロジェクトで作成したpof-config.xml
ファイルを使用します。
Contact
オブジェクト、Address
オブジェクトおよびPhoneNumber
オブジェクトの<user-type>
要素を定義し、これらに型ID1001
、1002
および1003
を割り当てて、完全なクラス名を指定します。このファイルには、Coherenceデータ型の最初の1000個のIDを予約するcoherence-pof-config.xml
ファイルが含まれている必要があります。
ファイル名を変更し、contacts-pof-config.xml
として保存します(このファイルは、C:\home\oracle\workspace\Contacts\appClientModule
フォルダに保存されます)。例4-5に、contacts-pof-config.xml
ファイルのサンプルを示します。
例4-5 POF構成ファイル
<?xml version="1.0"?> <pof-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-pof-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-pof-config coherence-pof-config.xsd"> <user-type-list> <!-- coherence POF user types --> <include>coherence-pof-config.xml</include> <!-- com.tangosol.examples package --> <user-type> <type-id>1001</type-id> <class-name>com.oracle.handson.Contact</class-name> </user-type> <user-type> <type-id>1002</type-id> <class-name>com.oracle.handson.Address</class-name> </user-type> <user-type> <type-id>1003</type-id> <class-name>com.oracle.handson.PhoneNumber</class-name> </user-type> </user-type-list> <allow-interfaces>true</allow-interfaces> <allow-subclasses>true</allow-subclasses> </pof-config>
キャッシュ構成ファイルを作成します。Project Explorerでcoherence-cache-config.xml
ファイルを使用できます。このファイルはcoherence-cache-config.xsd
ファイルに基づいています。また、coherence.jar
ファイルにcoherence-cache-config.xml
のコピーがあります。
scheme-name
としてExamplesPartitionedPocScheme
を、service-name
としてPartitionedPofCache
を使用します。
serializer
セクションでは、POFシリアライズ・オブジェクトを適切なシリアライズ・ルーチン(PofSerializer
、またはPortableObject
インタフェースを介したコールによる)にマップします。この場合は、com.tangosol.io.pof.ConfigurablePofContext
クラスを使用します。
<init-param>
セクションで、POF構成ファイルの名前(この場合はcontacts-pof-config.xml
)を指定します。
Project Explorerでファイル名を変更し、contacts-cache-config.xml
として保存します(このファイルはC:\home\oracle\workspace\Contacts\appClientModule
フォルダに保存されます)。例4-6に、contacts-cache-config.xml
ファイルのサンプルを示します。
例4-6 キャッシュ構成ファイル
<?xml version="1.0"?> <!-- Note: This XML document is an example Coherence Cache Configuration deployment descriptor that should be customized (or replaced) for your particular caching requirements. The cache mappings and schemes declared in this descriptor are strictly for demonstration purposes and are not required. For detailed information on each of the elements that can be used in this descriptor please see the Coherence Cache Configuration deployment descriptor guide included in the Coherence distribution or the "Cache Configuration Elements" page on the Coherence Wiki (http://wiki.tangosol.com). --> <cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config" xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config http://xmlns.oracle.com/coherence/coherence-cache-config/1.2/coherence-cache-config.xsd"> <!-- The defaults element defines factory-wide default settings. --> <defaults> <!-- Note: This element defines the default serializer for all services defined within this cache configuration descriptor. Valid values include full serializer definitions, as well as named references to serializers defined within the "serializers" element of the operational configuration. Example values include: java, pof. Default value is java. --> <serializer system-property="tangosol.coherence.serializer"/> <!-- Note: This element defines the default socket-provider for all Coherence Extend services defined within this cache configuration descriptor. Valid values include full socket-provider definitions, as well as named references to providers defined within the "socket-providers" element of the operational configuration. This setting only specifies the default socket-provider for Coherence Extend services; TCMP's socket-provider is specified within the "unicast-listener" of the operational configuration. Example values include: system, ssl. Default value is system. --> <socket-provider system-property="tangosol.coherence.socketprovider"/> </defaults> <caching-scheme-mapping> <cache-mapping> <cache-name>*</cache-name> <scheme-name>ExamplesPartitionedPofScheme</scheme-name> </cache-mapping> </caching-scheme-mapping> <caching-schemes> <distributed-scheme> <scheme-name>ExamplesPartitionedPofScheme</scheme-name> <service-name>PartitionedPofCache</service-name> <serializer><instance>
<class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name> <init-params> <init-param> <param-type>String</param-type> <param-value>contacts-pof-config.xml</param-value> </init-param> </init-params></instance>
</serializer> <backing-map-scheme> <local-scheme> <!-- each node will be limited to 250MB --> <high-units>250M</high-units> <unit-calculator>binary</unit-calculator> </local-scheme> </backing-map-scheme> <autostart>true</autostart> </distributed-scheme> </caching-schemes> </cache-config>
Contactsプロジェクトでは、キャッシュ・サーバーが実行されている必要があります。キャッシュ・サーバーとアプリケーションは、同じPOF構成ファイルおよびキャッシュ構成ファイルを参照する必要があります。ここでは、キャッシュ・サーバーとアプリケーションの実行構成を作成する方法について説明します。
実行中のキャッシュ・サーバーがあれば停止します。詳細は、「キャッシュ・サーバーの停止」を参照してください。
キャッシュ・サーバーを起動する実行可能ファイルを作成します。
プロジェクトを右クリックして、「Run As」→「Run Configurations」を選択します。「Run Configurations」ダイアログ・ボックスで、「Name」フィールドにContactsCacheServer
と入力します。
「Main」タブで、「Project」フィールドに「Contacts」が表示されていることを確認します。「Include system libraries when searching for a main class」チェック・ボックスを選択し、「Search」ボタンをクリックします。「Select Main Type」ダイアログ・ボックスで、DefaultCacheServer
と入力し、「DefaultCacheServer - com.tangosol.net」クラスを選択します。「Select Main Type」ダイアログ・ボックスで「OK」をクリックし、「Run Configurations」ダイアログ・ボックスで「Apply」をクリックします。
「Coherence」タブの「General」タブで、「Topology」フィールドの「Absolute File Path」を選択し、C:\home\oracle\workspace\Contacts\appClientModule
ディレクトリのcontacts-cache-config.xml
ファイルを参照します。「Enabled (cache server)」が選択されていることを確認します。「Cluster port」に一意の値を入力します。「Apply」をクリックします。「General」タブは図4-3のようになります。
「Coherence」タブの「Other」タブで、tangosol.pof.config
項目までスクロールダウンします。POF構成ファイルへのパス(C:\home\oracle\workspace\Contacts\appClientModule\contacts-pof-config.xml
)を入力します。
「Arguments」タブで、「VM Arguments」に-showversion
と入力します。
「Classpath」タブで、「User Entries」にContactsプロジェクトが表示されていることを確認します。表示されていない場合は、「Add Projects」ボタンをクリックしてContactsプロジェクトを追加します。
「Common」タブで、「Shared file」を選択し、\Contactsプロジェクトを参照します。
「Run」をクリックして、Contacts
キャッシュ・サーバーを起動します。出力は例4-7のようになります。
例4-7 Contactsキャッシュ・サーバーの出力
java version "1.7.0" Java(TM) SE Runtime Environment (build 1.7.0-b147) Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing) 2012-08-16 15:09:26.380/1.718 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/tangosol-coherence.xml" 2012-08-16 15:09:26.427/1.765 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml" 2012-08-16 15:09:26.474/1.812 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Contacts/build/classes/tangosol-coherence-override.xml" 2012-08-16 15:09:26.474/1.812 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "cache-factory-config.xml" is not specified 2012-08-16 15:09:26.474/1.812 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "cache-factory-builder-config.xml" is not specified 2012-08-16 15:09:26.474/1.812 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified Oracle Coherence Version 12.1.2.0 Build 36845 Grid Edition: Development mode Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 2012-08-16 15:09:26.896/2.234 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a):Loaded cache configuration from "file:/C:/home/oracle/workspace/Contacts/appClientModule/contacts-cache-config.xml"
2012-08-16 15:09:27.427/2.765 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a): Created cache factory com.tangosol.net.ExtensibleConfigurableCacheFactory 2012-08-16 15:09:29.240/4.578 Oracle Coherence GE 12.1.2.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.202:8088 using SystemDatagramSocketProvider 2012-08-16 15:09:32.693/8.031 Oracle Coherence GE 12.1.2.0 <Info> (thread=Cluster, member=n/a): Created a new cluster "cluster:0x47DB" with Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) 2012-08-16 15:09:32.693/8.031 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x47DB Group{Address=224.12.1.0, Port=3155, TTL=4} MasterMemberSet( ThisMember=Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer) OldestMember=Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer) ActualMemberSet=MemberSet(Size=1 Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer) ) MemberId|ServiceVersion|ServiceJoined|MemberState 1|12.1.2|2012-08-16 15:09:29.365|JOINED RecycleMillis=1200000 RecycleSet=MemberSet(Size=0 ) ) TcpRing{Connections=[]} IpMonitor{Addresses=0} 2012-08-16 15:09:32.880/8.218 Oracle Coherence GE 12.1.2.0 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1 2012-08-16 15:09:32.959/8.297 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=1): Loaded Reporter configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/reports/report-group.xml" 2012-08-16 15:09:33.459/8.797 Oracle Coherence GE 12.1.2.0 <Info> (thread=DistributedCache:PartitionedPofCache, member=1):Loaded POF configuration from "file:/C:/home/oracle/workspace/Contacts/build/classes/contacts-pof-config.xml"
2012-08-16 15:09:33.537/8.875 Oracle Coherence GE 12.1.2.0 <Info> (thread=DistributedCache:PartitionedPofCache, member=1): Loaded included POF configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/coherence-pof-config.xml" 2012-08-16 15:09:33.740/9.078 Oracle Coherence GE 12.1.2.0 <D5> (thread=DistributedCache:PartitionedPofCache, member=1): Service PartitionedPofCache joined the cluster with senior service member 1 2012-08-16 15:09:33.802/9.140 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=1): Services ( ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=12.1.2, OldestMemberId=1} InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=12.1.2, OldestMemberId=1} PartitionedCache{Name=PartitionedPofCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0} ) Started DefaultCacheServer...
ContactDriver
実行可能ファイルの実行構成を作成します。
「Project Explorer」でContactDriver.java
ファイルを右クリックし、「Run As」→「Run Configurations」を選択します。
「Run Configurations」ダイアログ・ボックスで、「Oracle Coherence」ノードをダブルクリックします。「Name」フィールドにContactsDriver
と入力します。「Main」タブの「Project」フィールドでContacts
を参照し、「Main class」フィールドでcom.oracle.handson.ContactDriver
を参照します。「Apply」をクリックします。
「Coherence」タブの「General」タブの「Cache configuration descriptor」フィールドで、contacts-cache-config.xml
ファイルへの絶対パスを参照します。「Disable (cache client)」ラジオ・ボタンを選択します。「Cluster port」フィールドに3155
と入力します。
「Coherence」タブの「Other」タブで、「tangosol.pof.config」フィールドまでスクロールダウンし、値をcontacts-pof-config.xml
POF構成ファイルへの絶対パスに置き換えます。
「Classpath」タブで、「User Entries」に「Contacts (default classpath)」が表示されていることを確認します。
「Run」をクリックして、ContactDriver
の構成を実行します。Contacts
の出力例は例4-8のようになります。
この例では、Contact
オブジェクトが実行時にPOFに変換されます。POFを使用すると、CPU時間と生成されるバイナリ・ファイルのサイズにおいて、パフォーマンスが大幅に向上します。
例4-8 Eclipse IDEでのContactsの出力例
java version "1.7.0" Java(TM) SE Runtime Environment (build 1.7.0-b147) Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing) 2012-08-16 15:15:22.568/0.500 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/tangosol-coherence.xml" 2012-08-16 15:15:22.615/0.547 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml" 2012-08-16 15:15:22.662/0.594 Oracle Coherence 12.1.2.0 <Info> (thread=main, member=n/a): Loaded operational overrides from "file:/C:/home/oracle/workspace/Contacts/build/classes/tangosol-coherence-override.xml" 2012-08-16 15:15:22.662/0.594 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "cache-factory-config.xml" is not specified 2012-08-16 15:15:22.662/0.594 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "cache-factory-builder-config.xml" is not specified 2012-08-16 15:15:22.662/0.594 Oracle Coherence 12.1.2.0 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified Oracle Coherence Version 12.1.2.0 Build 36845 Grid Edition: Development mode Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 2012-08-16 15:15:23.099/1.031 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a):Loaded cache configuration from "file:/C:/home/oracle/workspace/Contacts/appClientModule/contacts-cache-config.xml"
2012-08-16 15:15:23.490/1.422 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a): Created cache factory com.tangosol.net.ExtensibleConfigurableCacheFactory 2012-08-16 15:15:24.693/2.625 Oracle Coherence GE 12.1.2.0 <D4> (thread=main, member=n/a): TCMP bound to /130.35.99.202:8090 using SystemDatagramSocketProvider 2012-08-16 15:15:25.068/3.000 Oracle Coherence GE 12.1.2.0 <Info> (thread=Cluster, member=n/a): Failed to satisfy the variance: allowed=16, actual=31 2012-08-16 15:15:25.068/3.000 Oracle Coherence GE 12.1.2.0 <Info> (thread=Cluster, member=n/a): Increasing allowable variance to 17 2012-08-16 15:15:25.396/3.328 Oracle Coherence GE 12.1.2.0 <Info> (thread=Cluster, member=n/a): This Member(Id=2, Timestamp=2012-08-16 15:15:25.193, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) joined cluster "cluster:0x47DB" with senior Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) 2012-08-16 15:15:25.630/3.562 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service Management with senior member 1 2012-08-16 15:15:25.630/3.562 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=n/a): Member 1 joined Service PartitionedPofCache with senior member 1 2012-08-16 15:15:25.630/3.562 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0x47DB Group{Address=224.12.1.0, Port=3155, TTL=4} MasterMemberSet( ThisMember=Member(Id=2, Timestamp=2012-08-16 15:15:25.193, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver) OldestMember=Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer) ActualMemberSet=MemberSet(Size=2 Member(Id=1, Timestamp=2012-08-16 15:09:29.365, Address=130.35.99.202:8088, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:5792, Role=CoherenceServer) Member(Id=2, Timestamp=2012-08-16 15:15:25.193, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver) ) MemberId|ServiceVersion|ServiceJoined|MemberState 1|12.1.2|2012-08-16 15:09:29.365|JOINED, 2|12.1.2|2012-08-16 15:15:25.193|JOINED RecycleMillis=1200000 RecycleSet=MemberSet(Size=0 ) ) TcpRing{Connections=[1]} IpMonitor{Addresses=0} 2012-08-16 15:15:25.755/3.687 Oracle Coherence GE 12.1.2.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1 2012-08-16 15:15:25.849/3.781 Oracle Coherence GE 12.1.2.0 <Info> (thread=main, member=2): Loaded Reporter configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/reports/report-group.xml" 2012-08-16 15:15:26.224/4.156 Oracle Coherence GE 12.1.2.0 <Info> (thread=DistributedCache:PartitionedPofCache, member=2):Loaded POF configuration from "file:/C:/home/oracle/workspace/Contacts/build/classes/contacts-pof-config.xml"
2012-08-16 15:15:26.302/4.234 Oracle Coherence GE 12.1.2.0 <Info> (thread=DistributedCache:PartitionedPofCache, member=2): Loaded included POF configuration from "jar:file:/C:/oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar!/coherence-pof-config.xml" 2012-08-16 15:15:26.427/4.359 Oracle Coherence GE 12.1.2.0 <D5> (thread=DistributedCache:PartitionedPofCache, member=2): Service PartitionedPofCache joined the cluster with senior service member 1They are the same!!
キャッシュ・サーバーの出力をもう一度参照すると、Contactsキャッシュ・クライアントがクラスタに参加し、処理を完了した後にクラスタから離脱したことを示すメッセージを確認できます。例4-9を参照してください。
例4-9 Contactsクライアントの参加と離脱を示すContactsキャッシュ・サーバー
... Started DefaultCacheServer... 2012-08-16 15:15:25.396/360.734 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2012-08-16 15:15:25.193, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver) joined Cluster with senior member 1 2012-08-16 15:15:25.755/361.093 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1 2012-08-16 15:15:26.490/361.828 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member 2 joined Service PartitionedPofCache with senior member 1 2012-08-16 15:15:26.646/361.984 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2012-08-16 15:15:25.193, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver) due to a peer departure; removing the member. 2012-08-16 15:15:26.646/361.984 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1 2012-08-16 15:15:26.646/361.984 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member 2 left service PartitionedPofCache with senior member 1 2012-08-16 15:15:26.646/361.984 Oracle Coherence GE 12.1.2.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2012-08-16 15:15:26.646, Address=130.35.99.202:8090, MachineId=18578, Location=site:,machine:tpfaeffl-lap7,process:4572, Role=OracleHandsonContactDriver) left Cluster with senior member 1