インタフェースObjectInputFilter

関数型インタフェース:
ã“れã¯é–¢æ•°åž‹ã‚¤ãƒ³ã‚¿ãƒ•ェースãªã®ã§ã€ãƒ©ãƒ ãƒ€å¼ã¾ãŸã¯ãƒ¡ã‚½ãƒƒãƒ‰å‚ç…§ã®ä»£å…¥å…ˆã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã™ã€‚

@FunctionalInterface public interface ObjectInputFilter
直列化復元中ã«ã‚¯ãƒ©ã‚¹ã€é…列ã®é•·ã•ãŠã‚ˆã³ã‚°ãƒ©ãƒ•・メトリックをフィルタã—ã¾ã™ã€‚

警告: ä¿¡é ¼ã§ããªã„データã®ç›´åˆ—化復元ã¯ã€æœ¬è³ªçš„ã«å±é™ºã§ã‚りã€å›žé¿ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ 「Java SEã«å¯¾ã™ã‚‹ã‚»ã‚­ãƒ¥ã‚¢ãƒ»ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã®ã‚¬ã‚¤ãƒ‰ãƒ©ã‚¤ãƒ³ã€ã®"直列化ãŠã‚ˆã³ç›´åˆ—化復元"セクションã«å¾“ã£ã¦ã€ä¿¡é ¼ã§ããªã„データを慎é‡ã«æ¤œè¨¼ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ 「直列化フィルタリングã€ã§ã¯ã€ã‚·ãƒªã‚¢ãƒ«ãƒ»ãƒ•ィルタã®ä½¿ã„ã‚„ã™ã•ã«é–¢ã™ã‚‹ãƒ™ã‚¹ãƒˆãƒ»ãƒ—ラクティスã«ã¤ã„ã¦èª¬æ˜Žã—ã¾ã™ã€‚

アプリケーション開発者ã¯ã€ç›´åˆ—化復元ã®è„†å¼±æ€§ã‹ã‚‰ä¿è­·ã™ã‚‹ãŸã‚ã«ã€å„コンãƒãƒ¼ãƒãƒ³ãƒˆã¾ãŸã¯ãƒ©ã‚¤ãƒ–ラリã§ç›´åˆ—化復元ã§ãるオブジェクトを明確ã«è¨˜è¿°ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ コンテキストãŠã‚ˆã³ãƒ¦ãƒ¼ã‚¹ã‚±ãƒ¼ã‚¹ã”ã¨ã«ã€é–‹ç™ºè€…ã¯é©åˆ‡ãªãƒ•ィルタを作æˆã—ã¦é©ç”¨ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚

直列化復元フィルタリング・ファクトリãŠã‚ˆã³ãƒ•ィルタ

直列化復元フィルタリングã®éƒ¨åˆ†ã¯ã€ãƒ•ィルタã€ã‚³ãƒ³ãƒã‚¸ãƒƒãƒˆãƒ»ãƒ•ィルタãŠã‚ˆã³ãƒ•ィルタ・ファクトリã§ã™ã€‚ å„フィルタã§ã¯ã€ã‚¯ãƒ©ã‚¹ã¨ãƒªã‚½ãƒ¼ã‚¹åˆ¶é™ã®ãƒã‚§ãƒƒã‚¯ãŒå®Ÿè¡Œã•れã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒå¦èªæ¸ˆã€è¨±å¯æ¸ˆã¾ãŸã¯æœªæ±ºå®šã¨ã—ã¦æ±ºå®šã•れã¾ã™ã€‚ フィルタã¯ã€ä»–ã®ãƒ•ィルタã‹ã‚‰æ§‹æˆã§ãã€çµæžœã‚’マージã¾ãŸã¯çµåˆã§ãã¾ã™ã€‚ フィルタ・ファクトリã¯ã€å„ObjectInputStreamã®ãƒ•ィルタã®ç¢ºç«‹ãŠã‚ˆã³æ›´æ–°ã‚’担当ã—ã¾ã™ã€‚

å˜ç´”ãªã‚±ãƒ¼ã‚¹ã®å ´åˆã€ãƒ•ィルタ・ファクトリを設定ã›ãšã«ã€ã‚¢ãƒ—リケーション全体ã«å¯¾ã—ã¦é™çš„ãªJVM全体ã®ãƒ•ィルタを設定ã§ãã¾ã™ã€‚ JVM全体ã®ãƒ•ィルタã¯ã€ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã§ã‚·ã‚¹ãƒ†ãƒ ãƒ»ãƒ—ロパティを使用ã™ã‚‹ã‹ã€Config.setSerialFilterを呼ã³å‡ºã—ã¦è¨­å®šã§ãã¾ã™ã€‚ カスタム・フィルタ・ファクトリを指定ã™ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“。組込ã¿ãƒ•ィルタ・ファクトリã«ãƒ‡ãƒ•ォルト設定ã•れã¾ã™ã€‚ 組込ã¿ãƒ•ィルタ・ファクトリã¯ã€ObjectInputStreamã”ã¨ã«ã€Œé™çš„JVM全体ã®ãƒ•ィルタã€ã‚’æä¾›ã—ã¾ã™ã€‚

ãŸã¨ãˆã°ã€ã‚µãƒ³ãƒ—ル・クラスを許å¯ã—ã€java.baseモジュールã®ã‚¯ãƒ©ã‚¹ã‚’許å¯ã—ã€ä»–ã®ã™ã¹ã¦ã®ã‚¯ãƒ©ã‚¹ã‚’æ‹’å¦ã™ã‚‹ãƒ•ィルタを設定ã§ãã¾ã™ : コマンドライン・プロパティã¨ã—ã¦:

    % java -Djdk.serialFilter="example.*;java.base/*;!*" ...
ã¾ãŸã¯ãƒ—ログラム的ã«:
    var filter = ObjectInputFilter.Config.createFilter("example.*;java.base/*;!*")
    ObjectInputFilter.Config.setSerialFilter(filter);

複数ã®å®Ÿè¡Œã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã‚’æŒã¤ã‚¢ãƒ—リケーションã§ã¯ã€ã‚¢ãƒ—リケーションã”ã¨ã«ã‚«ã‚¹ã‚¿ãƒ ãƒ»ãƒ•ィルタをæä¾›ã™ã‚‹ã“ã¨ã§ã€å€‹ã€…ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã‚’ä¿è­·ã™ã‚‹ãŸã‚ã®ã€Œãƒ•ィルタ・ファクトリã€ã‚’æä¾›ã§ãã¾ã™ã€‚ ストリームãŒä½œæˆã•れるã¨ã€ãƒ•ィルタ・ファクトリãŒã‚³ãƒ¼ãƒ«ã•れã€ç¾åœ¨ã®ã‚¹ãƒ¬ãƒƒãƒ‰ãƒ»ãƒ­ãƒ¼ã‚«ãƒ«çŠ¶æ…‹ã€ã‚³ãƒ¼ãƒ«å…ƒã®éšŽå±¤ã€ãƒ©ã‚¤ãƒ–ラリã€ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãŠã‚ˆã³ã‚¯ãƒ©ã‚¹ãƒ»ãƒ­ãƒ¼ãƒ€ãƒ¼ãªã©ã€ä½¿ç”¨å¯èƒ½ãªæƒ…å ±ã‹ã‚‰å®Ÿè¡Œã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãŒè­˜åˆ¥ã•れã¾ã™ã€‚ ãã®æ™‚点ã§ã€ãƒ•ィルタを作æˆã¾ãŸã¯é¸æŠžã™ã‚‹ãŸã‚ã®ãƒ•ィルタ・ファクトリ・ãƒãƒªã‚·ãƒ¼ã¯ã€ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã«åŸºã¥ã„ã¦ç‰¹å®šã®ãƒ•ィルタã¾ãŸã¯ãƒ•ã‚£ãƒ«ã‚¿ã®æ§‹æˆã‚’é¸æŠžã§ãã¾ã™ã€‚ JVM全体ã®ç›´åˆ—化復元フィルタ・ファクトリã«ã‚ˆã‚Šã€ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå›ºæœ‰ã®ç›´åˆ—化復元フィルタをã™ã¹ã¦ã®ObjectInputStreamã«è¨­å®šã§ãã€ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‹ã‚‰èª­ã¿å–られるã™ã¹ã¦ã®ã‚ªãƒ–ジェクトをãƒã‚§ãƒƒã‚¯ã§ãã¾ã™ã€‚

フィルタ・ファクトリã®èµ·å‹•

JVM全体ã®ãƒ•ィルタ・ファクトリã¯ã€å„ObjectInputStreamãŒã€Œæ§‹æˆã•れã€ã€ã€Œã‚¹ãƒˆãƒªãƒ¼ãƒ å›ºæœ‰ã®ãƒ•ィルタãŒè¨­å®šã•れãŸã€ã®å ´åˆã«å‘¼ã³å‡ºã•れる関数ã§ã™ã€‚ パラメータã¯ç¾åœ¨ã®ãƒ•ィルタã¨ãƒªã‚¯ã‚¨ã‚¹ãƒˆã•れãŸãƒ•ィルタã§ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ ã«ä½¿ç”¨ã•れるフィルタを返ã—ã¾ã™ã€‚ 「ObjectInputStreamコンストラクタã€ã‹ã‚‰èµ·å‹•ã™ã‚‹ã¨ã€æœ€åˆã®ãƒ‘ラメータã¯nullã§ã€2番目ã®ãƒ‘ラメータã¯ã€Œé™çš„JVM全体ã®ãƒ•ィルタã€ã§ã™ã€‚ ObjectInputStream.setObjectInputFilterã‹ã‚‰å‘¼ã³å‡ºã•れるã¨ã€æœ€åˆã®ãƒ‘ラメータã¯ã‚¹ãƒˆãƒªãƒ¼ãƒ  (コンストラクタã§è¨­å®šã•れãŸã‚‚ã®)ã§ç¾åœ¨è¨­å®šã•れã¦ã„るフィルタã§ã€2番目ã®ãƒ‘ラメータã¯ObjectInputStream.setObjectInputFilterã«æŒ‡å®šã•れãŸãƒ•ィルタã§ã™ã€‚ ç¾åœ¨ãŠã‚ˆã³æ–°ã—ã„フィルタã¯ãれãžã‚Œnullã§ã€ãƒ•ァクトリã¯nullã‚’è¿”ã—ã¾ã™ã€‚ フィルタ・ファクトリã®å®Ÿè£…ã§ã¯ã€ã‚¢ãƒ—リケーション・スレッド・コンテキストã¾ãŸã¯ãã®ã‚³ãƒ¼ãƒ«ãƒ»ã‚¹ã‚¿ãƒƒã‚¯ã‹ã‚‰æŠ½å‡ºã•れãŸã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆæƒ…報を自由ã«ä½¿ç”¨ã—ã¦ã€æ–°ã—ã„フィルタを作æˆã—ã¦çµ„ã¿åˆã›ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ 2ã¤ã®ãƒ‘ラメータã®ã¿ã‚’使用ã™ã‚‹ã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“。

アクティブãªç›´åˆ—化復元フィルタ・ファクトリã¯ã€æ¬¡ã®ã„ãšã‚Œã‹ã§ã™:

フィルタ

フィルタã¯ã€ã€Œãƒ‘ターン文字列ã€ã‹ã‚‰ã€ã¾ãŸã¯ã€Œã‚¯ãƒ©ã‚¹ã®è¿°èªžã€ã‹ã‚‰allowã¾ãŸã¯rejectクラスã«åŸºã¥ã„ã¦ä½œæˆã§ãã¾ã™ã€‚

フィルタcheckInput(FilterInfo)メソッドã¯ã€ã€Œã‚ªãƒ–ジェクトã®èª­å–りã€ä¸­ã«ã‚¼ãƒ­å›žä»¥ä¸Šå‘¼ã³å‡ºã•れã¾ã™ã€‚ メソッドã¯ã€ã‚¯ãƒ©ã‚¹ã€å„é…列ã®é•·ã•ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‹ã‚‰èª­ã¿å–られるオブジェクト数ã€ã‚°ãƒ©ãƒ•ã®æ·±ã•ãŠã‚ˆã³ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‹ã‚‰èª­ã¿å–られãŸãƒã‚¤ãƒˆã®åˆè¨ˆæ•°ã‚’検証ã™ã‚‹ãŸã‚ã«ã‚³ãƒ¼ãƒ«ã•れã¾ã™ã€‚

複åˆãƒ•ィルタã¯ã€ä»–ã®ãƒ•ィルタã®çµæžœã‚’çµåˆã¾ãŸã¯ãƒã‚§ãƒƒã‚¯ã—ã¾ã™ã€‚ merge(filter, anotherFilter)フィルタã¯ã€2ã¤ã®ãƒ•ィルタã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹å€¤ã‚’組ã¿åˆã›ã¾ã™ã€‚ rejectUndecidedClass(filter)ã¯ã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒUNDECIDEDã®å ´åˆã«ã€ã‚¯ãƒ©ã‚¹ã®ãƒ•ィルタã®çµæžœã‚’ãƒã‚§ãƒƒã‚¯ã—ã¾ã™ã€‚ 多ãã®å ´åˆã€ãƒ•ィルタã«ã‚ˆã‚‹ALLOWEDã§ã¯ãªã„クラスã¯REJECTEDã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚

直列化復元フィルタã«ã‚ˆã‚Šã€å¼•数を許å¯ã™ã‚‹ã‹æ‹’å¦ã™ã‚‹ã‹ã‚’決定ã—ã€é©åˆ‡ãªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’è¿”ã—ã¾ã™: ALLOWEDã¾ãŸã¯REJECTED。 フィルタãŒã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’判別ã§ããªã„å ´åˆã¯ã€UNDECIDEDã‚’è¿”ã—ã¾ã™ã€‚ フィルタã¯ã€ç‰¹å®šã®ãƒ¦ãƒ¼ã‚¹ãƒ»ã‚±ãƒ¼ã‚¹ãŠã‚ˆã³äºˆæƒ³ã•れるタイプ用ã«è¨­è¨ˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ 特定ã®ç”¨é€”å‘ã‘ã«è¨­è¨ˆã•れãŸãƒ•ィルタã¯ã€ãƒ•ィルタã®ç¯„囲外ã®ã‚¯ãƒ©ã‚¹ã«æ¸¡ã•れる場åˆãŒã‚りã¾ã™ã€‚ フィルタã®ç›®çš„ãŒã‚¯ãƒ©ã‚¹ã‚’æ‹’å¦ã™ã‚‹ã“ã¨ã§ã‚ã‚‹å ´åˆã¯ã€ä»–ã®å€™è£œã‚¯ãƒ©ã‚¹ã§UNDECIDEDã‚’ç…§åˆã—ã€ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹å€™è£œã‚¯ãƒ©ã‚¹ã‚’æ‹’å¦ã§ãã¾ã™ã€‚ フィルタã¯ã€ã‚¯ãƒ©ã‚¹ãŒnullã€arrayLength㌠-1ã€æ·±ã•ã€å‚ç…§æ•°ãŠã‚ˆã³ã‚¹ãƒˆãƒªãƒ¼ãƒ ãƒ»ã‚µã‚¤ã‚ºã¨ç­‰ã—ã„状態ã§ã‚³ãƒ¼ãƒ«ã•れã€1ã¤ã¾ãŸã¯ä¸€éƒ¨ã®å€¤ã®ã¿ã‚’åæ˜ ã™ã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’è¿”ã—ã¾ã™ã€‚ ã“れã«ã‚ˆã‚Šã€ãƒ•ィルタをレãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹é¸æŠžè‚¢ã«ç‰¹å®šã§ãã€è¨±å¯ã¾ãŸã¯å¦èªæ¸ˆã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’強制ã›ãšã«ä»–ã®ãƒ•ィルタを使用ã§ãã¾ã™ã€‚

フィルタ・モデルã®ä¾‹

å˜ç´”ãªã‚¢ãƒ—リケーションã®å ´åˆã€è¨±å¯ã¾ãŸã¯æ‹’å¦ã•れãŸã‚¯ãƒ©ã‚¹ã‚’リストã™ã‚‹å˜ä¸€ã®äº‹å‰å®šç¾©æ¸ˆãƒ•ィルタã§ã€äºˆæœŸã—ãªã„クラスã®ç›´åˆ—化復元ã®ãƒªã‚¹ã‚¯ã‚’管ç†ã§ãã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚

複数ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¾ãŸã¯ãƒ©ã‚¤ãƒ–ラリã‹ã‚‰æ§‹æˆã•れるアプリケーションã§ã¯ã€ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®æ§‹é€ ã‚’使用ã—ã¦ã€ã‚¢ãƒ—リケーションã®å„コンテキストã§è¨±å¯ã¾ãŸã¯æ‹’å¦ã™ã‚‹ã‚¯ãƒ©ã‚¹ã‚’å„ObjectInputStreamã§è­˜åˆ¥ã§ãã¾ã™ã€‚ å„ã‚¹ãƒˆãƒªãƒ¼ãƒ ã®æ§‹æˆæ™‚ã«ç›´åˆ—化復元フィルタ・ファクトリãŒèµ·å‹•ã•れã€ã‚¹ãƒ¬ãƒƒãƒ‰ã¾ãŸã¯ãƒ—ログラムを確èªã—ã¦é©ç”¨ã™ã‚‹ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå›ºæœ‰ã®ãƒ•ィルタを決定ã§ãã¾ã™ã€‚ 考ãˆã‚‰ã‚Œã‚‹ä¾‹:

  • スレッド・ローカル状態ã¯ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ å›ºæœ‰ã®ãƒ•ィルタã§é©ç”¨ã¾ãŸã¯æ§‹æˆã™ã‚‹ãƒ•ã‚£ãƒ«ã‚¿ã‚’ä¿æŒã§ãã¾ã™ã€‚ フィルタã¯ã€ã‚¢ãƒ—リケーションã¾ãŸã¯ãƒ©ã‚¤ãƒ–ラリã«ã‚ˆã£ã¦ç®¡ç†ã•れる仮想フィルタã®ã‚¹ã‚¿ãƒƒã‚¯ã‹ã‚‰ãƒ—ッシュãŠã‚ˆã³ãƒãƒƒãƒ—アップã§ãã¾ã™ã€‚
  • フィルタ・ファクトリã¯ã€ç›´åˆ—化復元メソッドã®å‘¼å‡ºã—元を識別ã—ã€ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¾ãŸã¯ãƒ©ã‚¤ãƒ–ラリ・コンテキストを使用ã—ã¦ãƒ•ã‚£ãƒ«ã‚¿ã‚’é¸æŠžã™ã‚‹ã‹ã€é©åˆ‡ãªã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå›ºæœ‰ã®ãƒ•ィルタを構æˆã§ãã¾ã™ã€‚ メカニズムã¯ã€ç›´åˆ—化ã•れãŸã‚¯ãƒ©ã‚¹ã«å¯¾ã™ã‚‹åˆ¶é™ä»˜ãアクセスã¾ãŸã¯ç„¡åˆ¶é™ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’æŒã¤å‘¼ã³å‡ºã—元を識別ã—ã€ãれã«å¿œã˜ã¦ãƒ•ã‚£ãƒ«ã‚¿ã‚’é¸æŠžã§ãã¾ã™ã€‚

スレッドã®ã™ã¹ã¦ã®ç›´åˆ—化復元をフィルタã™ã‚‹ä¾‹

ã“ã®ã‚¯ãƒ©ã‚¹ã¯ã€ã‚¢ãƒ—リケーションæä¾›ã®ãƒ•ィルタ・ファクトリãŒãƒ•ィルタを組ã¿åˆã›ã¦ã€ã‚¹ãƒ¬ãƒƒãƒ‰ã§å®Ÿè¡Œã•れるã™ã¹ã¦ã®ç›´åˆ—化復元æ“作をãƒã‚§ãƒƒã‚¯ã™ã‚‹æ–¹æ³•を示ã—ã¾ã™ã€‚ スレッド固有ã®ãƒ•ã‚£ãƒ«ã‚¿ã‚’ä¿æŒã™ã‚‹ã‚¹ãƒ¬ãƒƒãƒ‰ãƒ»ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã‚’定義ã—ã€é™çš„JVM全体ã®ãƒ•ィルタãŠã‚ˆã³ã‚¹ãƒˆãƒªãƒ¼ãƒ å›ºæœ‰ã®ãƒ•ィルタã§ãƒ•ィルタを構æˆã™ã‚‹ãƒ•ィルタ・ファクトリを構æˆã—ã€ã“れら2ã¤ã®ãƒ•ィルタã§å‡¦ç†ã•れãªã„クラスを拒å¦ã—ã¾ã™ã€‚ ストリーム固有ã®ãƒ•ィルタãŒè¨­å®šã•れã€ã‚¯ãƒ©ã‚¹ã‚’å—ã‘入れãŸã‚Šæ‹’å¦ã—ãŸã‚Šã—ãªã„å ´åˆã€JVM全体ã®ãƒ•ィルタã¨ã‚¹ãƒ¬ãƒƒãƒ‰ãƒ»ãƒ•ィルタを組ã¿åˆã‚ã›ã¦é©ç”¨ã•れã¾ã™ã€‚ doWithSerialFilterメソッドã¯ã€ã‚¹ãƒ¬ãƒƒãƒ‰å›ºæœ‰ã®ãƒ•ィルタã®è¨­å®šã‚’行ã„ã€ã‚¢ãƒ—リケーションRunnableã‚’èµ·å‹•ã—ã¾ã™ã€‚
public static final class FilterInThread implements BinaryOperator<ObjectInputFilter> {

    private final ThreadLocal<ObjectInputFilter> filterThreadLocal = new ThreadLocal<>();

    // Construct a FilterInThread deserialization filter factory.
    public FilterInThread() {}

    // Returns a composite filter of the static JVM-wide filter, a thread-specific filter,
    // and the stream-specific filter.
    public ObjectInputFilter apply(ObjectInputFilter curr, ObjectInputFilter next) {
        if (curr == null) {
            // Called from the OIS constructor or perhaps OIS.setObjectInputFilter with no current filter
            var filter = filterThreadLocal.get();
            if (filter != null) {
                // Merge to invoke the thread local filter and then the JVM-wide filter (if any)
                filter = ObjectInputFilter.merge(filter, next);
                return ObjectInputFilter.rejectUndecidedClass(filter);
            }
            return (next == null) ? null : ObjectInputFilter.rejectUndecidedClass(next);
        } else {
            // Called from OIS.setObjectInputFilter with a current filter and a stream-specific filter.
            // The curr filter already incorporates the thread filter and static JVM-wide filter
            // and rejection of undecided classes
            // If there is a stream-specific filter merge to invoke it and then the current filter.
            if (next != null) {
                return ObjectInputFilter.merge(next, curr);
            }
            return curr;
        }
    }

    // Applies the filter to the thread and invokes the runnable.
    public void doWithSerialFilter(ObjectInputFilter filter, Runnable runnable) {
        var prevFilter = filterThreadLocal.get();
        try {
            filterThreadLocal.set(filter);
            runnable.run();
        } finally {
            filterThreadLocal.set(prevFilter);
        }
    }
}

フィルタ・ファクトリã®ä½¿ç”¨

FilterInThreadユーティリティを使用ã™ã‚‹ã«ã¯ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’作æˆã—ã€JVM全体ã®ãƒ•ィルタ・ファクトリã¨ã—ã¦æ§‹æˆã—ã¾ã™ã€‚ doWithSerialFilterメソッドã¯ã€ã‚µãƒ³ãƒ—ル・アプリケーションã¨ã‚³ã‚¢ãƒ»ã‚¯ãƒ©ã‚¹ã‚’許å¯ã™ã‚‹ãƒ•ィルタã§å‘¼ã³å‡ºã•れã¾ã™:
       // Create a FilterInThread filter factory and set
       var filterInThread = new FilterInThread();
       ObjectInputFilter.Config.setSerialFilterFactory(filterInThread);

       // Create a filter to allow example.* classes and reject all others
       var filter = ObjectInputFilter.Config.createFilter("example.*;java.base/*;!*");
       filterInThread.doWithSerialFilter(filter, () -> {
             byte[] bytes = ...;
             var o = deserializeObject(bytes);
       });

特ã«è¨˜è¼‰ãŒãªã„ã‹ãŽã‚Šã€ã“ã®ã‚¤ãƒ³ã‚¿ãƒ•ェースãŠã‚ˆã³ãã®ãƒã‚¹ãƒˆã•れãŸã‚¯ãƒ©ã‚¹ã®ãƒ¡ã‚½ãƒƒãƒ‰ã«null引数を渡ã™ã¨ã€NullPointerExceptionãŒã‚¹ãƒ­ãƒ¼ã•れã¾ã™ã€‚

å°Žå…¥ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³:
9
関連項目:
  • ãƒã‚¹ãƒˆã•れãŸã‚¯ãƒ©ã‚¹ã®ã‚µãƒžãƒªãƒ¼

    ãƒã‚¹ãƒˆã•れãŸã‚¯ãƒ©ã‚¹
    修飾å­ã¨åž‹
    インタフェース
    説明
    static final class 
    JVM全体ã®ç›´åˆ—化復元フィルタ・ファクトリを設定ãŠã‚ˆã³å–å¾—ã™ã‚‹ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ãƒ»ã‚¯ãƒ©ã‚¹ã€é™çš„ãªJVM全体ã®ãƒ•ィルタã€ã¾ãŸã¯ãƒ‘ターン文字列ã‹ã‚‰ãƒ•ィルタを作æˆã™ã‚‹ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ãƒ»ã‚¯ãƒ©ã‚¹ã€‚
    static interface 
    FilterInfoã¯ã€ç›´åˆ—化復元ã•れã¦ã„ã‚‹ç¾åœ¨ã®ã‚ªãƒ–ジェクトã«é–¢ã™ã‚‹æƒ…å ±ã¨ObjectInputStreamã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’æä¾›ã—ã¾ã™ã€‚
    static enum 
    クラスã®ãƒã‚§ãƒƒã‚¯ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€é…列ã®é•·ã•ã€å‚ç…§æ•°ã€æ·±ã•ãŠã‚ˆã³ã‚¹ãƒˆãƒªãƒ¼ãƒ ãƒ»ã‚µã‚¤ã‚ºã€‚
  • メソッドã®ã‚µãƒžãƒªãƒ¼

    修飾å­ã¨åž‹
    メソッド
    説明
    allowFilter(Predicate<Class<?>> predicate, ObjectInputFilter.Status otherStatus)
    クラスã®è¿°èªžãŒtrueã®å ´åˆã€Status.ALLOWEDã‚’è¿”ã™ãƒ•ィルタを返ã—ã¾ã™ã€‚
    クラスã€é…列ã®é•·ã•ã€ã‚ªãƒ–ジェクトå‚ç…§ã®æ•°ã€æ·±ã•ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ ãƒ»ã‚µã‚¤ã‚ºã€ãŠã‚ˆã³ãã®ä»–ã®ä½¿ç”¨å¯èƒ½ãªãƒ•ィルタリング情報を確èªã—ã¾ã™ã€‚
    merge(ObjectInputFilter filter, ObjectInputFilter anotherFilter)
    フィルタã¨åˆ¥ã®ãƒ•ィルタã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’マージã™ã‚‹ãƒ•ィルタを返ã—ã¾ã™ã€‚
    クラスã®è¿°èªžãŒtrueã®å ´åˆã€Status.REJECTEDã‚’è¿”ã™ãƒ•ィルタを返ã—ã¾ã™ã€‚
    特定ã®ãƒ•ィルタを起動ã—ã€ã‚¯ãƒ©ã‚¹ã«ã¤ã„ã¦UNDECIDEDã‚’REJECTEDã«ãƒžãƒƒãƒ—ã™ã‚‹ãƒ•ィルタを特殊ãªã‚±ãƒ¼ã‚¹ã¨ã¨ã‚‚ã«è¿”ã—ã€ãれ以外ã®å ´åˆã¯ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’è¿”ã—ã¾ã™ã€‚
  • メソッドã®è©³ç´°

    • checkInput

      クラスã€é…列ã®é•·ã•ã€ã‚ªãƒ–ジェクトå‚ç…§ã®æ•°ã€æ·±ã•ã€ã‚¹ãƒˆãƒªãƒ¼ãƒ ãƒ»ã‚µã‚¤ã‚ºã€ãŠã‚ˆã³ãã®ä»–ã®ä½¿ç”¨å¯èƒ½ãªãƒ•ィルタリング情報を確èªã—ã¾ã™ã€‚ ã“ã®ãƒ¡ã‚½ãƒƒãƒ‰ã®å®Ÿè£…ã§ã¯ã€ç›´åˆ—化復元中ã«ä½œæˆã•れるオブジェクト・グラフã®å†…容を確èªã—ã¾ã™ã€‚ フィルタã¯Status.ALLOWEDã€Status.REJECTEDã€ã¾ãŸã¯Status.UNDECIDEDã‚’è¿”ã—ã¾ã™ã€‚

      filterInfo.serialClass()ãŒnon-nullã®å ´åˆã€ãƒã‚§ãƒƒã‚¯ã™ã‚‹ã‚¯ãƒ©ã‚¹ãŒã‚りã¾ã™ã€‚ serialClass()ãŒnullã®å ´åˆã€ã‚¯ãƒ©ã‚¹ãŒãªãã€ã“ã®æƒ…å ±ã«ã¯ã€ç›´åˆ—化復元ã•ã‚Œã‚‹ã‚°ãƒ©ãƒ•ã®æ·±ã•ã€å‚ç…§ã®æ•°ãŠã‚ˆã³ã‚¹ãƒˆãƒªãƒ¼ãƒ èª­å–りサイズã«é–¢é€£ã™ã‚‹ãƒ¡ãƒˆãƒªãƒƒã‚¯ã®ã¿ãŒå«ã¾ã‚Œã¾ã™ã€‚

      APIã®ãƒŽãƒ¼ãƒˆ:
      checkInputを実装ã™ã‚‹å„フィルタã¯ã€ObjectInputFilter.Statusã®å€¤ã®ã„ãšã‚Œã‹ã‚’è¿”ã—ã¾ã™ã€‚ nullã‚’è¿”ã™ã¨ã€NullPointerExceptionã‚„ãã®ä»–ã®äºˆæœŸã—ãªã„動作ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚
      パラメータ:
      filterInfo - 直列化復元ã•れるç¾åœ¨ã®ã‚ªãƒ–ジェクト(存在ã™ã‚‹å ´åˆ)ãŠã‚ˆã³ObjectInputStreamã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã«é–¢ã™ã‚‹æƒ…報をæä¾›
      戻り値:
      å—ã‘入れられãŸå ´åˆã¯Status.ALLOWEDã€æ‹’å¦ã•れãŸå ´åˆã¯Status.REJECTEDã€æœªæ±ºå®šã®å ´åˆã¯Status.UNDECIDED。
    • allowFilter

      static ObjectInputFilter allowFilter(Predicate<Class<?>> predicate, ObjectInputFilter.Status otherStatus)
      クラスã®è¿°èªžãŒtrueã®å ´åˆã€Status.ALLOWEDã‚’è¿”ã™ãƒ•ィルタを返ã—ã¾ã™ã€‚ フィルタã¯ã€non-nullクラスã®è¿°èªžã«åŸºã¥ã„ã¦ALLOWEDã¾ãŸã¯otherStatusã‚’è¿”ã—ã€ã‚¯ãƒ©ã‚¹ãŒnullã®å ´åˆã¯UNDECIDEDã‚’è¿”ã—ã¾ã™ã€‚

      フィルタcheckInput(info)メソッドãŒèµ·å‹•ã•れるã¨ã€è¿°èªžãŒinfo.serialClass()ã«é©ç”¨ã•れã¾ã™ã€‚æˆ»ã‚Šã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯æ¬¡ã®ã¨ãŠã‚Šã§ã™:

      • UNDECIDED (serialClassãŒnullã®å ´åˆ)
      • ALLOWED(クラスã®è¿°èªžãŒtrueã‚’è¿”ã™å ´åˆ)
      • ãれ以外ã®å ´åˆã¯ã€otherStatusã‚’è¿”ã—ã¾ã™ã€‚

      ãŸã¨ãˆã°ã€ãƒ—ラットフォームã¾ãŸã¯ãƒ–ートストラップ・クラス・ローダーã‹ã‚‰ãƒ­ãƒ¼ãƒ‰ã•れãŸã‚¯ãƒ©ã‚¹ã‚’許å¯ã™ã‚‹ãƒ•ィルタを作æˆã—ã¾ã™ã€‚

          ObjectInputFilter f
              = allowFilter(cl -> cl.getClassLoader() == ClassLoader.getPlatformClassLoader() ||
                            cl.getClassLoader() == null, Status.UNDECIDED);
      

      パラメータ:
      predicate - nullã§ãªã„クラスをテストã™ã‚‹æ¡ä»¶
      otherStatus - 述語ãŒfalseã®å ´åˆã«ä½¿ç”¨ã™ã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
      戻り値:
      クラスã®è¿°èªžãŒtrueã®å ´åˆã€ALLOWEDã‚’è¿”ã™ãƒ•ィルタ
      å°Žå…¥ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³:
      17
    • rejectFilter

      static ObjectInputFilter rejectFilter(Predicate<Class<?>> predicate, ObjectInputFilter.Status otherStatus)
      クラスã®è¿°èªžãŒtrueã®å ´åˆã€Status.REJECTEDã‚’è¿”ã™ãƒ•ィルタを返ã—ã¾ã™ã€‚ フィルタã¯ã€non-nullクラスã®è¿°èªžã«åŸºã¥ã„ã¦REJECTEDã¾ãŸã¯otherStatusã‚’è¿”ã—ã€ã‚¯ãƒ©ã‚¹ãŒnullã®å ´åˆã¯UNDECIDEDã‚’è¿”ã—ã¾ã™ã€‚ フィルタcheckInput(info)メソッドãŒèµ·å‹•ã•れるã¨ã€è¿°èªžãŒserialClass()ã«é©ç”¨ã•れã¾ã™ã€‚æˆ»ã‚Šã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯æ¬¡ã®ã¨ãŠã‚Šã§ã™:
      • UNDECIDED (serialClassãŒnullã®å ´åˆ)
      • REJECTED(クラスã®è¿°èªžãŒtrueã‚’è¿”ã™å ´åˆ)
      • ãれ以外ã®å ´åˆã¯ã€otherStatusã‚’è¿”ã—ã¾ã™ã€‚

      ãŸã¨ãˆã°ã€ã‚¢ãƒ—リケーション・クラス・ローダーã‹ã‚‰ãƒ­ãƒ¼ãƒ‰ã—ãŸã‚¯ãƒ©ã‚¹ã‚’æ‹’å¦ã™ã‚‹ãƒ•ィルタを作æˆã—ã¾ã™ã€‚

          ObjectInputFilter f = rejectFilter(cl ->
               cl.getClassLoader() == ClassLoader.ClassLoader.getSystemClassLoader(), Status.UNDECIDED);
      

      パラメータ:
      predicate - nullã§ãªã„クラスをテストã™ã‚‹æ¡ä»¶
      otherStatus - 述語ãŒfalseã®å ´åˆã«ä½¿ç”¨ã™ã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
      戻り値:
      クラスã®è¿°èªžãŒtrueã®å ´åˆã€REJECTEDã‚’è¿”ã™ãƒ•ィルタを返ã—ã¾ã™
      å°Žå…¥ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³:
      17
    • merge

      static ObjectInputFilter merge(ObjectInputFilter filter, ObjectInputFilter anotherFilter)
      フィルタã¨åˆ¥ã®ãƒ•ィルタã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’マージã™ã‚‹ãƒ•ィルタを返ã—ã¾ã™ã€‚ anotherフィルタãŒnullã®å ´åˆã€filterãŒè¿”ã•れã¾ã™ã€‚ ãれ以外ã®å ´åˆã¯ã€non-nullフィルタã®ãƒšã‚¢ã‚’マージã™ã‚‹ãŸã‚ã«filterãŒè¿”ã•れã¾ã™ã€‚ è¿”ã•れるフィルタã¯ã€æ¬¡ã®ã‚ˆã†ã«checkInput(FilterInfo)メソッドを実装ã—ã¾ã™:
      • FilterInfoã§filterを呼ã³å‡ºã—ã¦statusã‚’å–å¾—
      • statusãŒREJECTEDã®å ´åˆã€REJECTEDã‚’è¿”ã—ã¾ã™
      • anotherFilterを呼ã³å‡ºã—ã¦otherStatusã‚’å–å¾—
      • otherStatusãŒREJECTEDã®å ´åˆã€REJECTEDã‚’è¿”ã—ã¾ã™
      • statusã¾ãŸã¯otherStatusã®ã„ãšã‚Œã‹ãŒALLOWEDã®å ´åˆã¯ã€ALLOWEDã‚’è¿”ã—ã¾ã™ã€‚
      • ãれ以外ã®å ´åˆã¯ã€UNDECIDEDã‚’è¿”ã—ã¾ã™
      パラメータ:
      filter - フィルタ
      anotherFilter - フィルタã¨ãƒžãƒ¼ã‚¸ã™ã‚‹ãƒ•ィルタ(null)
      戻り値:
      フィルタã¨åˆ¥ã®ãƒ•ィルタã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’マージã™ã‚‹ObjectInputFilter
      å°Žå…¥ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³:
      17
    • rejectUndecidedClass

      static ObjectInputFilter rejectUndecidedClass(ObjectInputFilter filter)
      特定ã®ãƒ•ィルタを起動ã—ã€ã‚¯ãƒ©ã‚¹ã«ã¤ã„ã¦UNDECIDEDã‚’REJECTEDã«ãƒžãƒƒãƒ—ã™ã‚‹ãƒ•ィルタを特殊ãªã‚±ãƒ¼ã‚¹ã¨ã¨ã‚‚ã«è¿”ã—ã€ãれ以外ã®å ´åˆã¯ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’è¿”ã—ã¾ã™ã€‚ クラスãŒãƒ—リミティブ・クラスã§ã¯ãªãé…列ã®å ´åˆã€è¿”ã•れるステータスã¯REJECTEDã§ã™ã€‚ クラスãŒãƒ—リミティブ・クラスã¾ãŸã¯é…列クラスã®è¿½åŠ ãƒã‚§ãƒƒã‚¯ãŒå®Ÿè¡Œã•れる場åˆã¯ã€æ¬¡ã®ãƒªã‚¹ãƒˆã‚’å‚ç…§ã—ã¦ãã ã•ã„。

      フィルタãŒUNDECIDEDã‚’è¿”ã™å ´åˆã€ã‚ªãƒ–ジェクトã®ç›´åˆ—化復元ã¯ã‚¯ãƒ©ã‚¹ã‚’å—ã‘入れã¾ã™ã€‚ 許å¯ã¾ãŸã¯æ‹’å¦ã•れã¦ã„ãªã„クラスã«å¯¾ã—ã¦æ±ºå®šã•れã¦ã„ãªã„çµæžœã‚’æ‹’å¦ã™ã‚‹ãƒ•ィルタを追加ã™ã‚‹ã¨ã€ã‚¯ãƒ©ã‚¹ãŒãƒ•ィルタを通éŽã—ãªã„よã†ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚

      実装è¦ä»¶:
      è¿”ã•れるフィルタã¯ã€æ¬¡ã®ã‚ˆã†ã«checkInput(FilterInfo)メソッドを実装ã—ã¾ã™:
      • FilterInfoã§ãƒ•ィルタを起動ã—ã¦ã€ãã®statusã‚’å–å¾—
      • ステータスãŒREJECTEDã¾ãŸã¯ALLOWEDã®å ´åˆã€statusã‚’è¿”ã—ã¾ã™
      • filterInfo.getSerialClass() serialClassãŒnullã®å ´åˆã€UNDECIDEDã‚’è¿”ã—ã¾ã™
      • クラスãŒã€Œé…列ã€ã§ãªã„å ´åˆã€REJECTEDã‚’è¿”ã—ã¾ã™
      • serialClassãŒã€Œé…列ã€ã®å ´åˆã€ãƒ™ãƒ¼ã‚¹ãƒ»ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆãƒ»ã‚¿ã‚¤ãƒ—を決定
      • ベース・コンãƒãƒ¼ãƒãƒ³ãƒˆãƒ»ã‚¿ã‚¤ãƒ—ãŒã€Œãƒ—リミティブ・クラスã€ã®å ´åˆã¯ã€UNDECIDEDã‚’è¿”ã—ã¾ã™
      • base component typeã§ãƒ•ィルタを起動ã—ã¦ã€ãã®component statusã‚’å–å¾—
      • コンãƒãƒ¼ãƒãƒ³ãƒˆãƒ»ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒALLOWEDã®å ´åˆã¯ã€ALLOWEDã‚’è¿”ã—ã¾ã™
      • ãれ以外ã®å ´åˆã¯ã€REJECTEDã‚’è¿”ã—ã¾ã™ã€‚
      パラメータ:
      filter - フィルタ
      戻り値:
      クラスã®ObjectInputFilter.Status.UNDECIDEDステータスをObjectInputFilter.Status.REJECTEDã«ãƒžãƒƒãƒ—ã™ã‚‹ObjectInputFilterã§ã€ãれ以外ã®å ´åˆã¯ãƒ•ィルタ・ステータスを返ã—ã¾ã™
      å°Žå…¥ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³:
      17