XStream 1.4 アップグレード
Confluence は、XStream 1.1.1 から 1.4.x へのアップグレードを予定しています。XStream は、XML にオブジェクトをシリアル化して再び戻すためのライブラリです。
- 6 月 27 日アップデート (8.0.0-m015)
- 5 月 9 日アップデート (7.18.0-m68)
- 2 月 22 日の更新
- 12 月 15 日の更新
- 12 月 9 日更新 (7.10.0-rc1)
- 12 月 1 日更新 (7.10.0-beta1)
- 26 10 月更新 (マイルストーン 7.10.0-xstream-14-m02)
- 5 11 月 更新 (マイルストーン 7.10.0-xstream-14-m03)
以降のアップデート
XStream 許可リストを既定かつ唯一の動作として有効にしました (これは Confluence 8.0 から有効になります)。また、ブロックリストを削除しました。
以降のアップデート
Confluence 7.18 で XStream を 1.4.19 にアップグレードしましたが、現時点では XStream 許可リストを有効にしていません (これは Confluence 8.0 で実施予定です)。ご利用のアプリが Confluence API によって XStream とやり取りを行う場合には影響ありません。
独自の xStream を初期化していて Confluence xStream API / ConfluencexStreamCompat を使用しないアプリは、破損する場合があります。ご利用のアプリが独自の XStream を使用する場合は、その XStream インスタンスで許可リストをマークする必要があります。
からの更新
confluence-compat-lib 1.4.2 がリリースされました。これによって、xstream-security モジュールが開発モードの confluence-compat-lib で正しく動作しないという問題が解決されます。今後、プラグインは atlassian-plugin.xml の xstream-security モジュールによって XStream 許可リストで必要なクラスをマークできるようになりました。
詳細については、 CONFSERVER-74692 - 課題情報を取得中... ステータス をご確認ください。このライブラリのアップグレードされたバージョンがバンドルされている Confluence のバージョンも確認することができます。
からの更新
confluence-compat-lib 1.4.1 がリリースされました。
CONFSERVER-60576 - 課題情報を取得中... ステータス への対応として、コンバーター/エイリアスへのアクセスを必要とするプラグインを提供するために、XStreamManagerCompat
に 3 つのメソッド getXStream()
、registerConverter(converter, priority)
、alias(alias, class)
を追加しました。これらのメソッドでは、プラグイン ベンダーが Confluence バージョンに関係なく、XStream コンバーターとエイリアスを自動でフックできます。本来、Bandana を使用するプラグインではこのいずれも使用する必要はないため、これらのメソッドは、それ自体で XStream をカスタムして使用するプラグイン向けのものです。クラスの現在の構造については、次のコード例をご参照ください。
/**
* This class lets plugins to be compatible with all supported versions of Confluence for XStream.
* Since 7.10 Confluence uses newer XStream and has added methods in XStreamManager.
* XStreamManagerCompat is responsible for choosing between XStreamManager or creating a new XStream(Confluence 7.9 and prior)
*/
@Component
public class XStreamManagerCompat {
/**
* Serialize an object to a pretty-printed XML String.
*/
public String toXML(Object obj) {
return delegate.toXML(obj);
}
/**
* Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed afterwards and in case * of an exception.
*/
public void toXML(Object obj, Writer writer) {
delegate.toXML(obj, writer);
}
/**
* Deserialize an object from an XML String.
*/
public Object fromXML(String xml) {
return delegate.fromXML(xml);
}
/**
* Deserialize an object from an XML Reader.
*/
public Object fromXML(Reader reader){
return delegate.fromXML(reader);
}
/**
* Provides a way to access 1.1.1 XStream object
* Supposed to be removed when Confluence 7.9 is EOL.
* @return XStream 1.1.1 equivalent object.
*/
public XStream getXStream() {
return delegate.getXStream();
}
/**
* Register a converter with the appropriate priority.
* @param XStream converter to register
* @param priority Priority to be used in XStream
*/
public void registerConverter(Converter converter, Integer priority) {
delegate.registerConverter(converter, priority);
}
/**
* Alias a Class to a shorter name to be used in XML elements.
* @param name Short name
* @param type Type to be aliased
*/
public void alias(String name, Class<?> type) {
delegate.alias(name, type); }
}
からの更新
Confluence 7.10.0-rc1 が利用可能になりました (リリース候補 1)。リリース候補 (およびそれ以前のベータ リリース) には XStream のアップグレードが含まれています。以下に説明するように、変更が必要になる可能性があるため、プラグインをテストすることを強く推奨します。
から更新
7.10.0-xstream-14-m03 マイルストーンで次の変更を行いました。
プラグインがシリアル化中にプラグイン バンドル クラスローダーを使用できるようにし、クラスローダーの不一致に起因する classCastExceptions を避けるために、ConfluenceXStreamManager でもう 1 つのメソッドを追加しました。簡単に言えば、Confluence コアは、その XStream で uberClassLoader を使用しますが、プラグイン クラスは一般的に BundleClassLoader によってロードされます。XML XStream 文字列がデシリアライズされると、プラグインのクラスローダー、したがって ClassCastException に属していないクラス オブジェクトになる可能性があります。そのため、プラグインは、
ConfluenceXStreamManager
から次のメソッドを使用できます。/** * Allows to use plugin OSGi classloaders and avoid ClassCastException in case of plugin re-installations. * * @param classLoader classLoader to use for serialization/deserialization in XStream * @return ConfluenceXStream based on classLoader */ ConfluenceXStream getPluginXStream(ClassLoader classLoader);
古い例で上記の API を使用する場合、使用方法は次のようになります。
public class ExampleClass { private final ConfluenceXStream pluginXStream; @Autowired public ExampleClass(@ComponentImport ConfluenceXStreamManager confluenceXStreamManager) { //Note that classLoader being used below is plugin's classloader this.pluginXStream = confluenceXStreamManager.getPluginXStream(getClass().getClassLoader()); //Also noe that pluginXStream is directly made a field and can just be created once in plugin lifecycle. } private SomeObject toSomeObject(String someString) { return (SomeObject) pluginXStream.toXML(someString); } }
confluence-compat-lib
1.4.0 は、サポートされているすべての Confluence バージョンで 1 つのバージョンを維持したいプラグイン用の下位互換コードを提供するためにリリースされました。
プラグインは、コンポーネントcom.atlassian.confluence.compat.setup.xstream.XStreamManagerCompat
プラグインを利用できます。これは、Spring を使用して開始するか、引数なしのコンストラクターXStreamManagerCompat()
を移用して手動で開始することができます。その署名については、以下を参照してください。/** * This class lets plugins to be compatible with all supported versions of Confluence for XStream. * Since 7.10 Confluence uses newer XStream and has added methods in XStreamManager. * XStreamManagerCompat is responsible for choosing between XStreamManager or creating a new XStream(Confluence 7.9 and prior) */ @Component public class XStreamManagerCompat { /** * Serialize an object to a pretty-printed XML String. */ public String toXML(Object obj) { return delegate.toXML(obj); } /** * Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed afterwards and in case * of an exception. */ public void toXML(Object obj, Writer writer) { delegate.toXML(obj, writer); } /** * Deserialize an object from an XML String. */ public Object fromXML(String xml) { return delegate.fromXML(xml); } /** * Deserialize an object from an XML Reader. */ public Object fromXML(Reader reader){ return delegate.fromXML(reader); } }
プラグインは、次の例を参照することにより、上記の compat API を使用できます。
pom.xml スニペット<dependency> <groupId>com.atlassian.confluence.compat</groupId> <artifactId>confluence-compat-lib</artifactId> <version>1.4.0</version> </dependency>
spring-component.xml<bean id="xStreamManagerCompat" class="com.atlassian.confluence.compat.setup.xstream.XStreamManagerCompat"/>
互換性コードの例public class ExampleClass { private final XStreamManagerCompat xStreamManagerCompat; @Autowired public ExampleClass(@Qualifier("xStreamManagerCompat") final XStreamManagerCompat xStreamManagerCompat) { this.xStreamManagerCompat = xStreamManagerCompat; } private SomeObject toSomeObject(String someString) { return (SomeObject) xStreamManagerCompat.toXML(someString); } }
から更新
Confluence により、XStream は 1.1.1 から 1.4.13 にアップグレードされる予定です。XStream は、XML にオブジェクトをシリアル化し、再び戻すためのライブラリです。
残念ながら、XStream 14.x は、保存されたデータの古い形式との互換性を壊し、データのアンマーシャリング時に ConversionException エラーをスローします。既存のデータ変換をサポートするため、後方互換性レイヤーを追加することで、Bandana にあるデータをサポートします。
ほとんどの場合、プラグインは Bandana ストレージのために XStream を使用する必要はありませんが、歴史的な理由により、人々は独自の XStream インスタンスを作成している可能性があります (この Jira のコメントに記載されている例の通り)。独自の "new XStream()"
インスタンスがあるクラスは、1.1.1 互換 XStream を利用できません。
また、Bandana にはすでに XStream マーシャリング/アンマーシャリングがすでに含まれているため、プラグインがマーシャリングも処理している場合は、不要なダブル マーシャリング/アンマーシャリングが発生します。このアプローチから離れ、Bandana Manager のアンマーシャラーのみを利用することを強くお勧めします。ダブルマーシャリング/アンマーシャリングの 2 つの例を次に示します。
private static final BandanaContext BANDANA_CONTEXT = new ConfluenceBandanaContext();
private final XStream xStream = new XStream();
public SomeObject getSomeObject() {
Object aStringObject = this.bandanaManager.getValue(BANDANA_CONTEXT, "some-key");
if (aStringObject instanceof String) {
try {
Object someObject = this.xStream.fromXML((String)aStringObject);
if (someObject instanceof SomeObject) {
return (SomeObject) someObject;
}
} catch (ConversionException var3) {
LOG.error("couldn't parse data");
throw new Exception("Some Exception");
}
}
}
public void setSomeObject(SomeObject someObject) {
this.bandanaManager.setValue(BANDANA_CONTEXT, "some-key", this.xStream.toXML(someObject));
}
private DesignConfiguration getConfig() {
DesignConfiguration config = null;
try {
Serializable serializable = (Serializable) bandanaManager.getValue(confluenceBandanaContext, BD_KEY);
if (serializable instanceof DesignConfiguration) {
config = (DesignConfiguration) serializable;
} else if (serializable instanceof String) {
config = (DesignConfiguration) xStream.fromXML((String) serializable);
}
} catch (Exception e) {
logger.warn("Error converting DesignConfiguration", e);
}
return config;
}
プラグインが何らかの理由で XStream を使用する必要がある場合には、ConfluenceXStreamManager を通じて Confluence 管理 XStream インスタンスを公開しています。まず、次のクラスの使用をおすすめします。
com.atlassian.confluence.setup.xstream.ConfluenceXStream
com.atlassian.confluence.setup.xstream.ConfluenceXStreamManager
(ID "xStreamManager" があるプラグイン アクセス可能スプリング ビーン)com.atlassian.confluence.impl.xstream.DefaultConfluenceXStreamManager
com.atlassian.confluence.setup.xstream.XStreamManager
(DefaultConfluenceXStreamManager
のため廃止予定としてマークされている既存のクラス)
スプリング ビーン "xStreamManager"
は、XStream のラッパーであるが下位互換性レイヤーがある ConfluenceXStream
を提供します。confluenceXStream.toXML(obj)
は、xstream.toXML(obj)
と同じ結果を達成します。次のページをご確認ください。
public interface ConfluenceXStream {
/**
* Serialize an object to a pretty-printed XML String.
*
* @throws XStreamException if the object cannot be serialized
*/
String toXML(Object obj);
/**
* Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed afterwards and in case
* of an exception.
*
* @throws XStreamException if the object cannot be serialized
*/
void toXML(Object obj, Writer writer);
/**
* Deserialize an object from an XML String.
*
* @throws XStreamException if the object cannot be deserialized
*/
Object fromXML(String xml);
/**
* Deserialize an object from an XML Reader.
*
* @throws XStreamException if the object cannot be deserialized
*/
Object fromXML(Reader reader);
}
必要なアクション
- Bandana にダブル マーシャリングがあるかどうかを確認します (上記の例で述べた通り)。存在する場合は、これを回避し、移行タスクを追加してこの状況から離れる必要があります。
ダブル マーシャリングを取り除くことができれば、プラグインの起動時に実行される移行レイヤーを導入する必要があるかもしれません。これは、ConfluenceXStream の
toXML(obj)
を活用して String から正しい bandanaValue を作成し、次の手順を行うことで実施できます。private DesignConfiguration getConfig() { DesignConfiguration config = null; try { config = (DesignConfiguration) bandanaManager.getValue(confluenceBandanaContext, BD_KEY); } catch (Exception e) { logger.warn("Error converting DesignConfiguration", e); } return config; }
ダブル マーシャリングを取り除くことができない場合は、独自の XStream オブジェクトの代わりに
confluenceXStreamManager.getConfluenceXStream.toXML(obj)
を使用してください。以下に例を示します。public class ExampleClass { private final ConfluenceXStreamManager confluenceXStreamManager; @Autowired public ExampleClass(@ComponentImport ConfluenceXStreamManager confluenceXStreamManager) { this.confluenceXStreamManager = confluenceXStreamManager; } private DesignConfiguration getConfig() { DesignConfiguration config = null; try { Serializable serializable = (Serializable) bandanaManager.getValue(confluenceBandanaContext, BD_KEY); if (serializable instanceof DesignConfiguration) { config = (DesignConfiguration) serializable; } else if (serializable instanceof String) { config = (DesignConfiguration) confluenceXStreamManager.getConfluenceXStream().toXML((String) serializable); } } catch (Exception e) { logger.warn("Error converting DesignConfiguration", e); } return config; } }
注:
confluenceXStreamManager.getConfluenceXStream()
は、confluenceXStream
が各 PluginInstall / PluginUninstall でリセットされるたびに実行する必要があります。
- プラグインが XStream 自体に触れることなく BandanaManager API を使用しているだけなら、このプラグインは安全です。心配する必要はありません。下位互換性は無料で提供されます。
プラグインで XStream がカスタム処理を行う必要がある場合は、
xStream.toXML(obj)
の代わりにconfluenceXStreamManager.getConfluenceXStream.toXML(obj)
を使用します。次のページをご確認ください。public class ExampleClass { private final ConfluenceXStreamManager confluenceXStreamManager; @Autowired public ExampleClass(@ComponentImport ConfluenceXStreamManager confluenceXStreamManager) { this.confluenceXStreamManager = confluenceXStreamManager; } private SomeObject toSomeObject(String someString) { return (SomeObject) confluenceXStreamManager.getConfluenceXStream().toXML(someString); } }
Confluence XStream API から XStream を使用するために必要なセキュリティの変更
- XStream 1.4.xは、独自のセキュリティ モジュールを提供します。以前は、当社には独自の
XStreamSecurityClassFilterを持っていました。許可リスト モードの使用に必要なこのセキュリティ モジュールは、デフォルトでは有効になっていません。 お客様が XStream 許可リストを有効にし、デフォルトですべてをブロックできる
xstream.allowlist.enable
システム プロパティが導入されました。- 注: プラグインをセキュリティ許可リストと連携させるため、EAP マイルストーンの
xstream.allowlist.enable
システム プロパティはデフォルトでオンになっています。 プラグインは、
atlassian-plugin.xml
の新しいxstream-security
モジュールを使用して Confluence の XStreams を型、正規表現、またはワイルドカードで設定できます。お客様がより厳格なモードに移行した場合、XStream の制限を回避するために、プラグインにこれを実装することを強くお勧めします。次のページをご確認ください。
<xstream-security key = "xstream-set" name="Some XStream allowlist set"> <type>com.atlassian.test.ExampleClass</type> <type>com.atlassian.test.AnotherExampleClass</type> <regex>com.atlassian.example.*</regex> <wildcard>com.some.package.**</wildcard> </xstream-security>
- これらの型、正規表現、またはワイルドカードは、ドキュメントの XStream 状態と一致います。詳細については、https://x-stream.github.io/security.html#example を参照してください。
- XStream 1.5 はデフォルトで許可リストのセキュリティ動作になります。これは、次の XStream アップグレードで導入される可能性があります。
今後の変更
まだこのアップグレードに取り組んでいます。将来の EAP マイルストーンの予定は次の通りです。
- 1.1.1 形式の Bandana データを1.4.xデータ形式に移行するためのアップグレード タスクを導入します
- CCMA がサーバー 1.1.1 形式を認識し、1.4.x 形式を使用してクラウドのためのエクスポートを作成するようにします