この章では、キャッシュ内に存在する複合オブジェクトを扱います。JDeveloperを使用して新しいContact
クラスを作成し、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のSerializable
インタフェースを使用するかわりに、高性能シリアライズのためのCoherence独自のクラスcom.tangosol.io.pof.PortableObject
を使用してパフォーマンスを向上させることができます。PortableObject
は標準的なjava.io.Serializable
の最大6倍の速さで、シリアライズ後の結果セットは標準より小さくなります。
PortableObject
インタフェースには、2つの単純なメソッドreadExternal
およびwriteExternal
が用意されており、提供されているPofReader
ストリームおよびPofWriter
ストリームからそれぞれ、シリアライズされたオブジェクト属性の読取りと書込みを明示的に行うことができます。シリアライズ形式を制御することにより、Coherenceでは、プロセスのパフォーマンスを大幅に向上させることができます。POFを使用すると、生成されるバイナリのサイズが大幅に縮小されます。バイナリのサイズは5分の1〜10分の1になり、バイナリとの間の変換速度は、オブジェクトのサイズにもよりますが、5〜20倍になる場合があります。
この演習では、従業員の名前、住所、誕生日および電話番号が含まれるContact
オブジェクトを作成します。また、POFシリアライズを使用して、PortableObject
インタフェースを実装することによりキャッシュにオブジェクトを挿入して取得します。
この項では、後で別のデータ・オブジェクトに組み込まれる2つのデータ・オブジェクトの作成方法について説明します。Address
オブジェクトは従業員の住所情報を提供し、PhoneNumber
オブジェクトは電話連絡先情報を提供します。
従業員の住所情報を格納するAddress
オブジェクトを作成します。
JDeveloperで、Contacts
という新規プロジェクトを作成します。詳細は、「既存アプリケーションでの新規プロジェクトの作成」を参照してください。
プロジェクトにContacts
という名前を付けます。「デフォルト・パッケージ」がcom.oracle.handson
、「Javaソースパス」がC:\home\oracle\labs\Contacts\src
、「出力ディレクトリ」がC:\home\oracle\labs\Contacts\classes
であることを確認します。
Coherenceエントリについて、「プロジェクト・プロパティ」をチェックし、さらに「ライブラリとクラスパス」の値をチェックします。coherence.jar
のフルパスC:\oracle\product\coherence\lib\coherence.jar
が指定されていることを確認します。
「実行/デバッグ/プロファイル」で、ローカル記憶域を無効にするようデフォルトの構成を編集します。「Javaオプション」フィールドに次の行を追加します。
-Dtangosol.coherence.distributed.localstorage=false
Address
という新規Javaクラスを作成します。詳細は、「Javaクラスの作成」を参照してください。
このJavaクラスにAddress
という名前を付けます。「mainメソッド」チェック・ボックスは選択しないでください。
データのシリアライズにPortableObject
を使用するようクラスを記述します。JDeveloperコード・エディタで、com.tangosol.io.pof.PortableObject
を実装するように、生成したAddress
クラスを変更します。PortableObject
クラス用にimport
文を追加します。
Portable
Object
で必要となるcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
で必要となるAddress
のpublicなデフォルト・コンストラクタを追加します。
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() { } }
JDeveloperでは、独自の属性用にデフォルトのgetメソッドおよびsetメソッドを生成できます。「ソース」メニューから、「アクセッサの生成」を選択します。Address
クラスの横にあるチェック・ボックスを選択します。これで、すべての属性が自動的に選択されます。「OK」をクリックして続行します。
デフォルトのコンストラクタおよびequalsメソッドを自動的に生成することもできます。「ソース」メニューから、「フィールドからコンストラクタの生成」を選択し、「すべて選択」をクリックしてから「OK」をクリックします。
生成されたコンストラクタは次のようになります。
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
の各オブジェクト・メソッドを実装します。
注意: キャッシュのキーと値は、シリアライズ可能(たとえば、java.io.Serializable )である必要があります。さらに、キャッシュ・キーはhashCode() メソッドとequals() メソッドを実装する必要があり、これらのメソッドはクラスタ・ノード間で一貫性のある結果を返す必要があります。これは、hashCode() およびequals() の実装は、オブジェクトのシリアライズ可能な状態(つまり、オブジェクトの一時的でないフィールド)にのみ基づいている必要があることを示しています。String 、Integer 、Date などのほとんどの組込みのJava型はこの要件を満たしています。一部のキャッシュの実装(特にパーティション・キャッシュ)では、等価の検証にキー・オブジェクトのシリアライズされた形式を使用します。つまり、equals() でtrueを返すキーは、同様の方法でシリアライズされる必要があります。ほとんどの組込みのJava型はこの要件を満たしています。 |
これらのメソッドをサポートするには、com.tangosol.util.Base
クラスおよびcom.tangosol.util.HashHelper
クラスをインポートします。次のコードは、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 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
を使用します。JDeveloperコード・エディタで、com.tangosol.io.pof.PortableObject
を実装するように、生成したPhoneNumber
クラスを変更します。PortableObject
クラス用にimport
文を追加します。
Portable
Object
で必要となるcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
で必要となるPhoneNumber
のpublicなデフォルト・コンストラクタを追加します。
PhoneNumber
クラス用に次のプライベート属性を入力します。必要に応じて他の属性も追加できます。
—short AccessCode
—short CountryCode
—short AreaCode
—int LocalNumber
JDeveloperでは、独自の属性用にデフォルトのgetメソッドおよびsetメソッドを生成できます。「ソース」メニューから、「アクセッサの生成」を選択します。PhoneNumber
クラスの横にあるチェック・ボックスを選択します。これで、すべての属性が自動的に選択されます。「OK」をクリックして続行します。
デフォルトのコンストラクタを自動的に生成することができます。「ソース」メニューから、「フィールドからコンストラクタの生成」を選択し、「すべて選択」をクリックしてから「OK」をクリックします。
生成されたコンストラクタは次のようになります。
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 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; /** * 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
を使用するため、com.tangosol.io.pof.PortableObject
を実装するように、JDeveloperコード・エディタで、生成したContact
クラスを変更します。PortableObject
クラス用にimport
文を追加します。
Portable
Object
で必要となるcom.tangosol.io.pof.PofReader
クラス、com.tangosol.io.pof.PofWriter
クラスおよびjava.io.IOException
クラスをインポートします。
PortableObject
で必要となるContact
のpublicなデフォルト・コンストラクタを追加します。
Contact
クラス用に次のプライベート属性を入力します。必要に応じて他の属性も追加できます。
String FirstName
String LastName
Address HomeAddress
Address WorkAddress
Map TelephoneNumbers
java.sql.Date BirthDate
JDeveloperでは、独自の属性用にデフォルトのgetメソッドおよびsetメソッドを生成できます。「ソース」メニューから、「アクセッサの生成」を選択します。Contact
クラスの横にあるチェック・ボックスを選択します。これで、すべての属性が自動的に選択されます。「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;
デフォルトのコンストラクタを自動的に生成することができます。「ソース」メニューから、「フィールドからコンストラクタの生成」を選択し、「すべて選択」をクリックしてから「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 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 ContactDriverクラスのサンプル
package com.oracle.handson; import com.tangosol.net.CacheFactory; import com.tangosol.net.NamedCache; import java.sql.Date; 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 Date(2009, 04, 01); 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構成ファイルを作成するには、モデルとしてcoherence-pof-config.xml
ファイルを使用します。このファイルのコピーは、coherence.jar
にあります。
Contact
オブジェクト、Address
オブジェクトおよびPhoneNumber
オブジェクトの<user-type>
要素を定義し、これらに型ID 1001
、1002
および1003
を割り当てて、完全なクラス名を指定します。このファイルには、Coherenceデータ型の最初の1000個のIDを予約するcoherence-pof-config.xml
ファイルを含めます。
このファイルをcontacts-pof-config.xml
という名前でC:\home\oracle\labs
ディレクトリに保存します。coherence-pof-config.xml
ファイルのコピーをlabs
ディレクトリにも保存します。例4-5は、contacts-pof-config.xml
ファイルのサンプルを示しています。
例4-5 POF構成ファイル
<?xml version="1.0"?> <!DOCTYPE pof-config SYSTEM "pof-config.dtd"> <pof-config> <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>
キャッシュ構成ファイルを作成します。coherence-cache-config.xml
ファイルを使用できます。これはcache-config.dtd
に基づいています。coherence-cache-config.xml
のコピーは、coherence.jar
にあります。
scheme-name
としてExamplesPartitionedPocScheme
を、service-name
としてPartitionedPofCache
を使用します。serializer
セクションは、POFシリアライズされたオブジェクトの適切なシリアライズ・ルーチン(PofSerializer
、またはPortableObject
インタフェースを介したコールによる)へのマッピングを担当します。この場合、com.tangosol.io.pof.ConfigurablePofContext
クラスを使用します。<init-param>
セクションは、POF構成ファイルの名前(この場合、contacts-pof-config.xml
)を指します。
このファイルをcontacts-cache-config.xml
という名前でC:\home\oracle\labs
ディレクトリに保存します。cache-config.dtd
ファイルのコピーをlabs
ディレクトリにも保存します。例4-6は、contacts-cache-config.xml
ファイルのサンプルを示しています。
例4-6 キャッシュ構成ファイル
<?xml version="1.0"?> <!DOCTYPE cache-config SYSTEM "cache-config.dtd"> <cache-config> <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> <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> </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-cache-server.cmd
という名前を付け、次の情報を追加します。
クラスパスに対するcoherence.jar
ファイルの場所: %COHERENCE_HOME%\lib\coherence.jar
クラスパスに対するアプリケーション・クラス・ファイルの場所: C:\home\oracle\labs\Contacts\classes
クラスパスに対するPOF構成ファイルの場所: C:\home\oracle\labs
-Dtangosol.coherence.cacheconfig
によるサーバー構成の場所
デフォルトのキャッシュ・サーバーを起動するコマンド: com.tangosol.net.DefaultCacheServer
例4-7に、contacts-cache-server.cmd
実行可能ファイルのサンプルを示します。
例4-7 キャッシュ・サーバー実行可能ファイルのサンプル
@echo off setlocal if (%COHERENCE_HOME%)==() ( set COHERENCE_HOME=c:\oracle\product\coherence ) set CONFIG=c:\home\oracle\labs set COH_OPTS=%COH_OPTS% -server -cp %COHERENCE_HOME%\lib\coherence.jar;C:\home\oracle\labs\Contacts\classes;C:\home\oracle\labs; set COH_OPTS=%COH_OPTS% -Dtangosol.coherence.cacheconfig=%CONFIG%\contacts-cache-config.xml java %COH_OPTS% -Xms1g -Xmx1g -Xloggc: com.tangosol.net.DefaultCacheServer %2 %3 %4 %5 %6 %7 :exit
Contacts
プロジェクトがまだコンパイルされていない場合は、これをコンパイルします。
Contacts
プロジェクトを右クリックし、「Contacts.jprのメイク」を選択します。
実行されているキャッシュ・サーバーがあれば停止します。
コマンドラインでcontacts-cache-server.cmd
を実行し、Contactsキャッシュ・サーバーを起動します。
例4-8に、contacts-cache-server.cmd
を実行したときのサンプル出力を示します。
例4-8 POFキャッシュ・サーバーの起動
C:\oracle\product\coherence\bin>contacts-cache-server.cmd 2010-05-27 13:42:18.826/0.297 Oracle Coherence 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence.xml" 2010-05-27 13:42:18.826/0.297 Oracle Coherence 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/tangosol-coherence-override-dev.xml" 2010-05-27 13:42:18.826/0.297 Oracle Coherence 3.6.0.0 DPR3 <D5> (thread=main, member=n/a): Optional configuration override "/tangosol-coherence-override.xml" is not specified 2010-05-27 13:42:18.842/0.313 Oracle Coherence 3.6.0.0 DPR3 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified Oracle Coherence Version 3.6.0.0 DPR3 Build 16141 Grid Edition: Development mode Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 2010-05-27 13:42:19.092/0.563 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Loaded cache configuration from "file:/C:/home/oracle/labs/contacts-cache-config.xml" 2010-05-27 13:42:19.451/0.922 Oracle Coherence GE 3.6.0.0 DPR3 <D4> (thread=main, member=n/a): SystemSocketProvider bound to port 8088 2010-05-27 13:42:22.904/4.375 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=Cluster, member=n/a): Created a new cluster "cluster:0xC4DB" with Member(Id=1, Timestamp=2010-05-27 13:42:19.467, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5200, Role=CoherenceServer, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0x822363D500000128DB8051CBC2D51F98 2010-05-27 13:42:22.920/4.391 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=main, member=n/a): Started cluster Name=cluster:0xC4DB Group{Address=224.3.6.0, Port=36000, TTL=4} MasterMemberSet ( ThisMember=Member(Id=1, Timestamp=2010-05-27 13:42:19.467, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5200, Role=CoherenceServer) OldestMember=Member(Id=1, Timestamp=2010-05-27 13:42:19.467, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5200, Role=CoherenceServer) ActualMemberSet=MemberSet(Size=1, BitSetCount=2 Member(Id=1, Timestamp=2010-05-27 13:42:19.467, Address=130.35.99.213:8088, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:5200, Role=CoherenceServer) ) RecycleMillis=1200000 RecycleSet=MemberSet(Size=0, BitSetCount=0 ) ) TcpRing{Connections=[]} IpMonitor{AddressListSize=0} 2010-05-27 13:42:23.029/4.500 Oracle Coherence GE 3.6.0.0 DPR3 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1 2010-05-27 13:42:23.279/4.750 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=Cluster, member=1): Loaded POF configuration from "file:/C:/home/oracle/labs/contacts-pof-config.xml" 2010-05-27 13:42:23.295/4.766 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=Cluster, member=1): Loaded included POF configuration from "jar:file:/C:/oracle/product/coherence/lib/coherence.jar!/coherence-pof-config.xml" 2010-05-27 13:42:23.373/4.844 Oracle Coherence GE 3.6.0.0 DPR3 <D5> (thread=DistributedCache:PartitionedPofCache, member=1): Service PartitionedPofCac he joined the cluster with senior service member 1 2010-05-27 13:42:23.388/4.859 Oracle Coherence GE 3.6.0.0 DPR3 <Info> (thread=main, member=1): Services ( ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.6, OldestMemberId=1} InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1} PartitionedCache{Name=PartitionedPofCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0} ) Started DefaultCacheServer...
JDeveloperでPOFキャッシュ・サーバーを設定します。
既存のプロジェクト・プロパティにCLASSPATH
エントリを追加します。「ツール」→「プロジェクト・プロパティ」→「ライブラリとクラスパス」に移動します。「JAR/ディレクトリの追加」をクリックします。プロジェクトでCLASSPATH
にC:\home\oracle\labs
を追加します。coherence.jar
がクラスパスにあることを確認します。
「実行/デバッグ/プロファイル」をクリックしてランタイム・プロパティを編集します。ローカル記憶域が無効であることを確認します。「Javaオプション」フィールドにcontacts-cache-config.xml
ファイルのパスを追加します。次を含む必要があります:
-Dtangosol.coherence.distributed.localstorage=false -Dtangosol.coherence.cacheconfig=c:\home\oracle\labs\contacts-cache-config.xml
「OK」をクリックしてランタイム構成の変更を保存し、再度「OK」をクリックして「プロジェクト・プロパティ」ダイアログ・ボックスを閉じます。
JDeveloperのIDEからContactDriver.java
を実行して、機能することを確認します。
この例で、Contact
オブジェクトは実行時にPOFに変換されます。POFを使用すると、CPU時間と生成されるバイナリのサイズの点で、パフォーマンスが大幅に向上します。