ConfigurationLoader 使用時の注意事項¶
項目
注意事項¶
ConfigurationLoader#load or #loadAll メソッドは、JAXB(Java Architecture for XML Binding)を利用して設定ファイルからデータを読み込んでいるため、使用するには設定ファイル、スキーマ定義、および、スキーマ定義に基づいたクラスが必要となります。しかし、JAXB を利用してスキーマ定義から自動生成したクラスをConfigurationLoader で使用すると ThreadLocal が開放されずにメモリリーク します。ConfigurationLoader を使用して設定ファイルを読み込む場合はスキーマ定義から自動生成したクラスを修正してください。
スキーマ定義から自動生成したクラスの修正¶
修正対象¶
スキーマ定義から自動生成したクラスがメモリリークしないようにするため、以下のクラスを修正する必要があります。
@XmlRegistry アノテーションが付与されているクラス @XmlType アノテーションが付与されているクラス
修正方法¶
@XmlRegistry アノテーションが付与されているクラスの修正¶
インスタンスを生成しているメソッドを static メソッド に修正してください。通常は自動生成時に @XmlType アノテーションが付与されているクラスのインスタンスを生成するメソッドが定義されていますが不足している場合はインスタンスを生成して返却する static メソッドを作成してください。@XmlRegistry public class ObjectFactory { public static JaxbConfig createJaxbConfig() { return new JaxbConfig(); } public static JaxbConfig.JaxbNestedConfig createJaxbConfigJaxbNestedConfig() { return new JaxbConfig.JaxbNestedConfig(); } }
コラム
自動生成時のインスタンス生成メソッドは以下の命名規則に従って定義されます。
- クラス名の先頭に「create」を加えた「create(クラス名)」で定義されます。
- ネストクラスに @XmlType アノテーションが付与されている場合は「create(外側のクラス名)(ネストクラス名)」で定義されます。
@XmlType アノテーションが付与されているクラスの修正¶
@XmlType アノテーションに factoryClass、および、factoryMethod を指定してください。
factoryClass同一パッケージ内のクラスから @XmlRegistry アノテーションが付与されているクラスを指定してください。 factoryMethodfactoryClass で指定したクラスのメソッドから自身のインスタンスを生成するメソッドを文字列で指定してください。@XmlType(name = "", propOrder = { "jaxbNestedConfig" }, factoryClass = ObjectFactory.class , factoryMethod = "createJaxbConfig") @XmlRootElement(name = "jaxb-config") public class JaxbConfig { @XmlType(name = "", propOrder = { "value" }, factoryClass = ObjectFactory.class , factoryMethod = "createJaxbConfigJaxbNestedConfig") public static class JaxbNestedConfig {
修正例¶
以下のスキーマ定義から自動生成されたクラスの修正例を示します。
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://intra_mart.co.jp/jaxb/sample/jaxb-config" xmlns:tns="http://intra_mart.co.jp/jaxb/sample/jaxb-config" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0" elementFormDefault="qualified"> <xs:annotation> <xs:appinfo> <jaxb:schemaBindings> <jaxb:package name="jp.co.intra_mart.jaxb.sample" /> </jaxb:schemaBindings> </xs:appinfo> </xs:annotation> <xs:element name="jaxb-config"> <xs:complexType> <xs:sequence> <xs:element name="jaxbNestedConfig"> <xs:complexType> <xs:sequence> <xs:element name="value" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
@XmlRegistry アノテーションが付与されているクラス¶
自動生成時はメソッドに static 修飾子がありません。処理内容は変更せず、static メソッドに修正するのみです。自動生成時package jp.co.intra_mart.jaxb.sample; import javax.xml.bind.annotation.XmlRegistry; @XmlRegistry public class ObjectFactory { public ObjectFactory() { } public JaxbConfig createJaxbConfig() { return new JaxbConfig(); } public JaxbConfig.JaxbNestedConfig createJaxbConfigJaxbNestedConfig() { return new JaxbConfig.JaxbNestedConfig(); } }修正例package jp.co.intra_mart.jaxb.sample; import javax.xml.bind.annotation.XmlRegistry; @XmlRegistry public class ObjectFactory { public ObjectFactory() { } public static JaxbConfig createJaxbConfig() { return new JaxbConfig(); } public static JaxbConfig.JaxbNestedConfig createJaxbConfigJaxbNestedConfig() { return new JaxbConfig.JaxbNestedConfig(); } }
@XmlType アノテーションが付与されているクラス¶
自動生成時は @XmlType アノテーションに factoryClass , factoryMethod の指定がありません。@XmlType アノテーションは JaxbConfig クラス、および JaxbNestedConfig クラスに付与されているため二箇所 factoryClass , factoryMethod を指定する修正が必要です。
factoryClass@XmlRegistry アノテーションは ObjectFactory クラスに付与されているため、両クラスとも@XmlType アノテーションの factoryClass には「factoryClass = ObjectFactory.class」と指定します。 factoryMethodObjectFactory クラスには両クラスのインスタンスを生成するメソッドが定義されているため各 @XmlType アノテーションの factoryMethod に自身のインスタンスを生成するメソッドを指定します。JaxbConfig クラスは「factoryMethod = “createJaxbConfig”」と指定します。JaxbNestedConfig クラスは「factoryMethod = “createJaxbConfigJaxbNestedConfig”」と指定します。自動生成時package jp.co.intra_mart.jaxb.sample; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "jaxbNestedConfig" }) @XmlRootElement(name = "jaxb-config") public class JaxbConfig { @XmlElement(required = true) protected JaxbConfig.JaxbNestedConfig jaxbNestedConfig; public JaxbConfig.JaxbNestedConfig getJaxbNestedConfig() { return jaxbNestedConfig; } public void setJaxbNestedConfig(JaxbConfig.JaxbNestedConfig value) { this.jaxbNestedConfig = value; } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "value" }) public static class JaxbNestedConfig { @XmlElement(required = true) protected String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }修正例package jp.co.intra_mart.jaxb.sample; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "jaxbNestedConfig" }, factoryClass = ObjectFactory.class , factoryMethod = "createJaxbConfig") @XmlRootElement(name = "jaxb-config") public class JaxbConfig { @XmlElement(required = true) protected JaxbConfig.JaxbNestedConfig jaxbNestedConfig; public JaxbConfig.JaxbNestedConfig getJaxbNestedConfig() { return jaxbNestedConfig; } public void setJaxbNestedConfig(JaxbConfig.JaxbNestedConfig value) { this.jaxbNestedConfig = value; } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "value" }, factoryClass = ObjectFactory.class , factoryMethod = "createJaxbConfigJaxbNestedConfig") public static class JaxbNestedConfig { @XmlElement(required = true) protected String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }