[Java] Java EE—the Most Lightweight Enterprise Framework?

原文はこちら。
https://community.oracle.com/docs/DOC-1008823

Recommendations for ensuring a productive development process

昔々、J2EE、特にアプリケーションサーバーは非常に肥大化しheavyweightと考えられていました。開発者がアプリケーション開発のためにその技術を使うのはかなり面倒で、落胆させるものでした。しかし、J2EEフレームワークからJava EEに名前が変わってから、この前提は正しいとは言えません。Java EEが他のエンタープライズ・フレームワークと比較してどうなのか、フレームワークが軽量であるといえる条件はいったい何なのでしょうか。

テクノロジーを選択する際、重要な考慮点の一つは、開発プロセスにおける開発者の生産性です。エンジニアはユースケースの実装や収益を生み出す機能を実装することに最大限の時間を割きます。それが、企業がそのゴールへ向かうために必要だからです。

選択されたテクノロジとメソッドは、開発者がビルド、テスト、およびデプロイ、さらにアプリケーションの設定、ビジネスユースケースに関係のない部分の実装、ビルド環境や外部依存関係の構成といった部分で必要な時間を最小限に抑える必要があります。しかしながら、利用可能なテクノロジーのうち、大部分はこういったことに対応していません。

Why Standards?

他のフレームワークと比較した場合、Java EEの最大のメリットの一つは、利用するAPIが標準化されていることです。標準化と聞くとうんざりさせられたり、あまりイノベーティブでないように見えますが、これらの標準を使うことにはいくつかの利点があります。

Integration of Specifications

Java EEの特定のAPI、例えばContexts and Dependency Injection (CDI)やJAX-RS、JSON Processing (JSR 353)、Bean ValidationといったAPIは、協調して動作し、シームレスに繋がっています。特にCDIはアプリケーション・コンポーネント間の「糊」として利用されます。この仕様には、以下のような言葉で記載されています。
"If the container does support specification A and B, then A has to integrate and work well with B seamlessly."
(コンテナが仕様AとBをサポートする場合、AはBと統合し、シームレスに動作する必要がある)
例えば、JAX-RSはリクエストやレスポンス・エンティティとして利用されるJsonObjectのようなJSONP型をサポートします。そして、Validationが失敗した場合には正しいHTTPステータスコードを含めてBean Validation機能の呼び出しをサポートしています(Listing 1)。
@Path("duke") 
public class DukeResource {
     @GET
     public JsonObject getDuke() {
          return Json.createObjectBuilder()
                  .add("name", "Duke")
                  .build();
     }
     @POST
     public void create(@Valid @NotPlayedYet Game game) {
          // game object has been validated at this point
     }
}
Listing 1. JSONP and Bean Validation integration of JAX-RS

JSONP型の利用はcontent-typeがapplication/jsonであることを暗示し、Validationに失敗した場合には、HTTPステータスコード400 Bad Request が送信されることでしょう。これは設定コードを一切書かなくても自動的にやってくれます。
別の例として、CDIを使うと開発者が任意のBeanやユーザー定義オブジェクトをJava EE管理対象コンポーネントに対して@Injectを使って注入することができます。Listing 2は、別のCDI Managed Beanをすぐに使うBean Validation Validatorの例です。
public class GameNotPlayedValidator implements ConstraintValidator<Notplayedyet, Game> {
     @Inject
     GameHistory history;
     public void initialize(NotPlayedYet constraint) {
          // no initialization needed
     }

     public boolean isValid(Game game, ConstraintValidatorContext context) {
          return !history.exists(game);
     }
}
Listing 2. CDI integration of bean validation

統合は仕様の主要な側面で、統合があるおかげで直接的な開発者体験を実現します。開発者は統合や構成作業を実施するアプリケーションサーバーに任せることができ、そのおかげえアプリケーションの業務ロジックに集中することができるのです。

Convention-over-Configuration Driven Development

Java EEのconvention-over-configuration(設定より規約、以下CoC)ドリブンなアプローチゆえに、ほとんどの現実世界のアプリケーションはそれほど多くの設定は必要ありません。厄介なXMLディスクリプタの時代は終わりました。単純なJava EEアプリケーションの場合、XMLファイルは必要ありません。

宣言的アノテーションのおかげで、アノテーションが付いたシンプルなPOLOがHTTPリクエスト(@Path)を処理したり、トランザクション、監視、インターセプタを含む、Enterprise JavaBeans (EJB) Bean(@Stateless)として機能します。こうしたアプローチはこれまでに様々なフレームワークで検証済みであり、Java EEで標準化されてきました。

XMLディスクリプタは今でもデプロイ時の構成のために利用することができますが、 CoCは開発者の生産性を最大化することに有用です。

External Dependencies

デプロイメント・アーティファクトに付属する特別な依存関係がなくても動作する現実世界のエンタープライズプロジェクトはごくまれです。しかし、これらの依存関係が必要な理由は、主として、ロギングやエンティティマッピングフレームワークや、Apache CommonsやGoogle Guavaなどの一般的なライブラリなど、ユースケースではなく、テクノロジーによってもたらされます。

Java EE 7、特にJava 8とともに利用する場合は、たいていのユースケースをカバーする機能を備えているので、他の依存関係を必要としません。標準状態で備えていないものは、最小限のコードで実現できます。例えば、CDIプロデューサによる注入可能な設定、インターセプタによるサーキットブレーカ(Adam Bienのオープンソースライブラリを見てください)、Java 8のLambdaやStreamsを使った洗練されたコレクション操作といったものです。

もちろん、ここで車輪の再発明をしないことを主張することができますが、実際には、数行のカスタムコードを保存するためだけに、メガバイトの外部依存関係をデプロイメント・アーティファクトに含めることは意味がありません。

最大の問題は直接導入された依存性ではなく、推移的な依存性であることを経験上わかっています。推移的な依存関係は、アプリケーションサーバー上の既存のライブラリのバージョンと衝突し、激しい競合を引き起こすことが多々あります。 最終的に、開発者はプロジェクトに小さな機能を実装するよりも、競合の管理に多くの時間を費やします。これは、主としてユースケースドリブンの依存関係ではなく、テクノロジードリブンの依存関係の場合に当てはまります。

Listing 3は、Adam BienのJava EE 7 Essentials Archetypeにインスパイアされた、シンプルなJava EEプロジェクトのMaven POM(project object model)ファイルの例です。
AdamBien/javaee7-essentials-archetype - A quickstart maven archetype for creating greenfield JavaEE 7 projects
https://github.com/AdamBien/javaee7-essentials-archetype
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.sebastian-daschner</groupId>
 <artifactId>game-of-duke</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>war</packaging>

 <dependencies>
     <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-api</artifactId>
          <version>7.0</version>
          <scope>provided</scope>
     </dependency>
 </dependencies>

 <build>
     <finalName>game-of-duke</finalName>
 </build>

 <properties>
     <maven.compiler.source>1.8</maven.compiler.source>
     <maven.compiler.target>1.8</maven.compiler.target>
     <failOnMissingWebXml>false</failOnMissingWebXml>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
</project>
Listing 3. Java EE 7 Maven POM file

もちろん、アプリケーションによっては、ソフトウェアの目的を達成するために重要なライブラリの統合が必要な場合もありますが、それは、ビジネス要件によってこれらの依存関係を正当化されるべきです。 一般に、外部のライブラリを最小限に抑えるための時間と労力を節約することに多大な意味があります。


テストに関する依存関係では、JUnit、Mockito、または場合によってはArquillianなどのライブラリは重要で包含されているため、別の話ではありますが、テストについても依存関係に注意を払うことは理にかなっています。

Thin Deployment Artifacts

アプリケーションサーバーはJava EE APIを認識しているため、デプロイメント・アーティファクトにそれらを含める必要はなく、ビジネスロジックのみを最小のグルーコードと横断的関心事(cross-cutting-concerns)と共に含めればよいのです。

従って、ビルドプロセスでたくさんの依存関係をコピーする必要がないため、こうしたキロバイトサイズのアーティファクトは非常に短いビルド時間ですみます。これは各ビルドごとに数秒の差が発生する可能性があります。開発者とContinuous Integration (CI) サーバーが費やしている余分な時間を合計すると、かなりの差になります。より頻繁にプロジェクトをビルドすればするほど、その影響はますます大きくなります。特にContinuous Delivery (CD) シナリオでは影響が大きくなります。

短いビルド時間に加えて、小さいサイズのデプロイメント・アーティファクトは公開とデプロイメントの時間を短縮します。実装が既にランタイムに含まれているため、可動部分は常に最小です。

The Ideal Framework for Docker

これこそがJava EEがDockerなどのコンテナテクノロジで使用されるべき、完璧なフレームワークである理由です。 Dockerイメージはレイヤー構造で、イメージが構築される際、ベースイメージにはすでにOS、Javaランタイム、およびアプリケーションが含まれています。 したがって、ビルドごとに追加されるのは、デプロイメント・アーティファクトの最後の1キロバイトの薄いレイヤーだけです。この構造のおかげで、各ビルド時だけでなく、イメージのバージョン化や出荷時においても、大量のWARまたはスタンドアロンJARを使うアプローチに比べて時間とストレージを節約します。

どの段階でも、デプロイメント・アーティファクトが小さいサイズであれば、非常に高速で生産的なデプロイメント・パイプラインを可能にします。

Modern Application Servers

J2EEアプリケーションサーバーは、開始時間やデプロイメント時間、インストールサイズ、およびリソースフットプリントに関して、重量級ソフトウェアの実行形態でしたが、Java EEという新しい世界では、これはもはや真実ではありません。

WildFly、Payara、WebSphere Liberty、Profile、TomEEなどの最新のJava EE 7アプリケーション・サーバーはすべて数秒で起動してデプロイできます。内部が包括的にモジュール化されているため、必要なコンポーネントだけをロードし、可能な限り迅速に薄いアプリケーション・アーティファクトをデプロイすることができます。

昨今のインストールサイズとフットプリントは非常に合理的です。アプリケーションサーバーは単純なサーブレットコンテナほど多くのリソースを消費しませんが、本格的なJava EE機能を備えています。面白いことに、実行中のブラウザインスタンスのほうが、より多くのメモリを消費します。

そうは言っても、コンテナやオンプレミスであっても、サーバー毎にアプリケーションを1個のみデプロイすることができ、それが合理的である場合があります。その "one application per application server per container"(コンテナ毎にアプリケーションサーバ1つに対し1個のアプリケーション)のアプローチを使うと、最新のマイクロサービス・アーキテクチャに対する非常に生産的で柔軟性のあるソリューションを得ることができます。

Packaging

パッケージングについては、もはやEARファイルを使用する理由はありません。単一の専用サーバー上にアプリケーション全体を配置する方法では、その環境にすべてのコンポーネントをインストールする必要があります。これにより、ビルドとデプロイメントの時間がさらに短縮されます。それに加えて、この方法はEARファイルが引き起こしがちなクラスローディング階層の問題も回避します。

大部分のクラウドとマイクロサービスのデプロイメントでは、スタンドアロンのJARパッケージを使用します。これらのJARパッケージには、アプリケーションとランタイム実装の両方が含まれます。 Java EEの世界では、WildFly Swarm、Payara Micro、TomEE Embeddedなどのベンダー固有のツールチェーンを使用してこのアプローチを実現できます。

しかしながら、上述の理由により、可能であればビジネスロジックをランタイムから分離することを強く推奨します。これはつまりアプリケーションのコードのみを含むWARファイルにアプリケーションをパッケージングする、ということです。

私見ですが、スタンドアロンのJARファイルは、技術的な理由ではなく、企業の「政治的」な問題のために、インストールや操作のプロセスを制御できない場合に便利な回避策と考えます。この方法であれば、デプロイメント・アーティファクトに必要なものすべてをまとめ、必要とするJavaランタイムを使い、かなりの技術的ではない問題を回避することができます。

Recommendation for a Productive Development Process

エンタープライズプロジェクトで最も生産的なソリューションは以下のようなものです。One of the most productive solutions for enterprise projects is the following:
  • Java EE 7とJava 8を提供されたAPIのみと共に使う
  • JAX-RSリソースやJPAといった最小限の配管を伴う、ビジネスロジックのみを含むキロバイトサイズのWARファイルをビルドする
  • Dockerイメージの構築 - 構成済みのアプリケーションサーバを含むベースイメージにWARファイルのみを追加
  • コンテナを使ってアプリケーションをデプロイするCD (Continuous Delivery) パイプラインによってリリース

Conclusion

”heavyweight Java EE”の時代は確かに終わりました。Java EEの傘に含まれるAPIは、生産性が高く、楽しめる開発者体験と、標準内でのシームレスな統合を提供します。特に、アプリケーションコードをランタイムから分離するアプローチは、迅速かつ生産的な開発プロセスを可能にします。

いくつかのベンダーによって始まった新しいMicroProfileイニシアチブにより、今後、Java EEの必要なコンポーネントがさらに少なくなる可能があります。
MicroProfile.io - Optimizing Enterprise Java for a microservices architecture
https://microprofile.io/

See Also

About the Author

Sebastian Daschner (@daschners) はフリーランスのJavaコンサルタント、ソフトウェア開発者、アーキテクトです。彼はプログラミングとJava EEに熱心で、JCPに参加し、JSR 370のExpert Groupに参加し、GitHubのさまざまなオープンソースプロジェクトをハッキングしています。彼は6年以上Javaに取り組んでいます。Java以外にも、LinuxやDockerなどのコンテナテクノロジのヘビーユーザーです。自分のブログやTwitterでコンピュータサイエンスの実践を伝えています。
sebastiandaschner blog
https://blog.sebastian-daschner.com/

[Cloud] Sales CloudにProcess Cloud Serviceの画面を埋め込む

このエントリは、JPOUG Advent Calendar 2016の12月23日分です。
JPOUG Advent Calendar 2016
https://jpoug.doorkeeper.jp/events/53797
昨日は@mutatsuさんでした。
分割読み込みでフラッシュバック問合せの利用
https://mutatsu.wordpress.com/2016/12/22/%E5%88%86%E5%89%B2%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%81%A7%E3%83%95%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%83%90%E3%83%83%E3%82%AF%E5%95%8F%E5%90%88%E3%81%9B%E3%81%AE%E5%88%A9%E7%94%A8/
今年は仕事色の薄い内容を書きたかったのですが、色々ありまして、「OracleのSaaSとPaaSを組み合わせる」という、昨年に引き続き非常に仕事色の濃いエントリでございます……。

ユースケースと要求事項

見積作成にあたり値引き率が高い場合、その値引率に対し上長から承認を得る必要がある、という業務上のルールは多くの企業で存在します。商談を管理するシステムであれば、そういった要求に対応するため、基本的な承認ワークフロー機能を有していることがほとんどです。ところが、20%までは上長の承認不要、20~40%は1段(直接の上長のみ)、40~60%までは2段、それ以上は3段、4段…といった具合に、値引き率に応じて承認階層を増やす仕組みまで備わっていることは少ないようです。
こういった多段階承認の要求を実現する場合、別の汎用ワークフロー製品を組み合わせることがよくありますが、今度は、以下のような要求が出てきます。
  • 承認申請をあげるために別システムのUIを開き、コピー&ペーストするなんて論外でしょ
  • 情報転記を自動化できたとしても、やはり明示的に別システムにログインするのではなく、ワークフローのUIが組み込まれていて欲しいなぁ
  • ワークフロー製品とのために別のIDを使ってログインしたくないので、Single Sign-onは必須ですな
このような要求事項を解決するにはどうすればよいでしょうか。

今回利用するもの

今回は、Oracle Sales CloudとOracle Process Cloud Service (PCS) を組み合わせた例をご紹介します。PCSで作成した承認申請アプリケーションの開始フォームを、Oracle Sales CloudのUIに埋め込み、Sales Cloudのデータを初期値としてPCSのUIに設定できれば、要求事項は解決できそうに見えます。具体的には、以下のような感じです。
  • Sales Cloudの営業>商談に新しいタブを追加する
  • 当該タブにPCSで作成したアプリケーションのUIを埋め込む
  • タブをクリックすると、Sales Cloudのデータを初期値として利用したPCSの開始フォームが開く
その前に、PCSとSales Cloudについて…。

Oracle Process Cloud Service (PCS)って?

Oracle Cloud Platformの一つのサービスで、クラウド上で利用可能なBPM (Business Process Management) ツールです。PCSはワークフローに必要な機能だけでなく、ビジネスルール機能も備えています。そのため、先ほどのユースケースのように、ビジネスルールを使って値引率に応じて承認階層を算定したり、値引き率が低い場合には上長の承認無しでプロセスを進めたり、といった判断のロジックをプロセスに埋め込まずに、後から変更できるよう外出しすることができます。
PCSの詳細は以下のURLからどうぞ。ただ、Java Cloud ServiceやDatabase Cloud Serviceと異なり、試使用のリクエストはWebページからできませんので、ご所望の方は、貴社担当の日本オラクルの営業にお問合せください。
Process Cloud Service
http://cloud.oracle.com/ja_JP/process

Oracle Sales Cloudって?

今風に言えば、Customer Experienceの向上を支援するためのSaaSです。昔風に言えば、顧客管理・営業支援のアプリケーションです。
Sales Cloud
https://cloud.oracle.com/ja_JP/sales-cloud

    Single sign-onはどうやって実現する?

    PCSとSales Cloudが同一アイデンティティドメインに所属していれば、同じユーザーID、パスワードでアクセスできます。さらに、Federated Single Sing-On使えば、オンプレミスで使っているLDAP、例えばActive Directoryに登録されたユーザーとパスワードでアクセスできます。Federated Single Sing-Onに関しては、詳しくは以下のドキュメントをご覧ください。
    Oracle Sales Cloud Securing Oracle Sales Cloud Release 11
    Implementing Federated Single Sign-On
    https://docs.oracle.com/cloud/latest/salescs_gs/OSCUS/OSCUS1728626.htm#OSCUS1728626

    Oracle® Cloud Using Oracle Process Cloud Service 16.4.5
    Configuring Federated SSO and Authentication
    https://docs.oracle.com/cloud/latest/process_gs/CPRCW/GUID-02911F68-A3E1-4E69-A1F5-06E65FB936F0.htm#CPRCW-GUID-02911F68-A3E1-4E69-A1F5-06E65FB936F0

    PCSで実施しておくこと

    まず、アプリケーションを作成します。今回は、単純にSales CloudにUIを貼り付けられればよいので、以下のようなプロセスにしています。


    実際に運用する場合は、UIからプロセスを開始し、値引き率で承認階層を判定、結果を起票者に通知するとともに、承認されたものについては、Sales Cloudの情報を更新するようなアプリケーションにする必要があるでしょう。


    フォームは、今回はシンプルにSales CloudのOpportunity IDとOpportunity Nameを表示するだけにしていますが、実際に利用するなら、Sales Cloudの情報を色々表示することになるでしょう。


    Sales CloudにUIを埋め込むためには、PCSのEmbeddable Process UI Componentsを使います。
    Oracle® Cloud Using Oracle Process Cloud Service 16.4.5
    Embedding Process UI Components in Other Applications
    http://docs.oracle.com/cloud/latest/process_gs/CPRCW/GUID-66587F65-C081-4961-BE92-6B1766586C14.htm#CPRCW-GUID-66587F65-C081-4961-BE92-6B1766586C14
    IFRAMEで取り出すためのコンポーネントがあるので、今回はそれを使います。URLは以下のようです。
    https://{PCSのURL}/bpm/components/pages/startform.html
    例えば、こんな感じです。
    https://process-xxxx.process.yyy.oraclecloud.com/bpm/components/pages/startform.html
    JSON形式でパラメータを設定すると、起動対象のPCSアプリケーションを指定することができます。以下はその例です(見やすくするため改行を入れていますが、実際には当然ながら1行で指定します)。
    https://process-xxxx.process.yyy.oraclecloud.com/bpm/components/pages/startform.html?startformData=
    {
      "processDefId":"default~Application!1.0~Process",
      "serviceName":"Process.service",
      "processName":"Process",
      "title":"てすと",
      "operation":"start",
      "startType":"START_PCS_FORM",
      "isDocsEnabled":true
    }
    [注意]
    ここで出てくるstartTypeには、旧来のBasic FormであればSTART_FORMを、新しいWeb Formの場合は、START_PCS_FORMを指定する必要があります。
    processDefId、serviceName、processName、operationなどは、以下のPCSのREST APIを使って取得した結果を設定します。
    REST API for Oracle Process Cloud Service
    Retrieve Process Definitions
    http://docs.oracle.com/cloud/latest/process_gs/CPRRA/op-process-definitions-get.html
    以下は取得結果の例です。
    {
      "levels": 0,
      "links": [
        {
          "href": "https://process-xxxx.process.yyy.oraclecloud.com/bpm/api/3.0/process-definitions",
          "length": 0,
          "rel": "self"
        },
        {
          "href": "https://process-xxxx.process.yyy.oraclecloud.com/bpm/api/3.0/",
          "length": 0,
          "rel": "parent"
        }
      ],
      "items": [
        {
          "processDefId": "default~Application!1.0~Process",
          "processName": "Process",
          "application": "default",
          "revision": "1.0",
          "domain": "default",
          "interfaces": [
            {
              "title": "Start from OSC(1.0)",
              "serviceName": "Process.service",
              "operation": "start",
              "startType": "START_PCS_FORM",
              "category": "",
              "args": [
                {
                  "name": "formArg",
                  "type": "{http://xmlns.oracle.com/bpm/forms/schemas/DemoForm}DemoForm",
                  "location": "https://process-xxxx.process.yyy.oraclecloud.com/soa-infra/services/default/Application!1.0*soa_ad130b2e-fdf1-403f-9f88-552345f0e06b/forms/schemas/DemoForm.xsd",
                  "schema": null,
                  "primitive": false
                }
              ],
              "formMetadata": "webform://appId=;formId=;oId=;service=Process.service;operation=start;dn=default/Application!1.0*soa_ad130b2e-fdf1-403f-9f88-552345f0e06b/Process;formName=DemoForm;ns=http://xmlns.oracle.com/bpmn/bpmnCloudProcess/Application/Process;href=https://process-xxxx.process.yyy.oraclecloud.com/bpm/api/3.0/webforms/default~Application!1.0~Process~80a9e329-9f29-4052-9f38-fc5856a21ca1~a0d16f69-77e8-4431-97a6-97b5015d9100"
            }
          ],
          "processIcon": {
            "initials": "A",
            "colorCode": "rgb(197,182,79)"
          },
          "isDocsEnabledFlag": true,
          "isConversationEnabledFlag": false
        }
      ]
    }
    
    開始フォームに初期値を設定するためには、startform.htmlのパラメータとして、payloadを付けます。今回の場合は、opportunityIDとnameというテキストフィールドに初期値を設定するため、以下のような感じです(見やすくするため改行を入れていますが、実際には当然ながら1行で指定します)。
    https://process-xxxx.process.yyy.oraclecloud.com/bpm/components/pages/startform.html?startformData=
    {
      "processDefId":"default~Application!1.0~Process",
      "serviceName":"Process.service",
      "processName":"Process",
      "title":"てすと",
      "operation":"start",
      "startType":"START_PCS_FORM",
      "isDocsEnabled":true
    }
    &payload=
    {
      "opportunityID":"300000130602218",
      "name":"なまえ"
    }
    [注意]
    この開始フォームに初期値を設定する方法は、Web Formでのみ利用可能で、Basic Formでは使えません。

    できあがったら、アプリケーションをデプロイしておきます。

    Sales Cloudで実施しておくこと

    Sales Cloudには、サンドボックスという機能があり、これを使うと実運用中のサービスに影響を与えずに、カスタマイズの実施および動作確認することができます(もちろんカスタマイズが完了後、そのカスタマイズ内容を公開することもできます)。今回はサンドボックス環境で動作確認しています。
    カスタマイズのライフサイクルについては、以下のドキュメントをご覧ください。
    Oracle Sales Cloud Customizing Sales Release 11
    Customization Life Cycle
    https://docs.oracle.com/cloud/latest/salescs_gs/OACEX/OACEX1607004.htm#OACEX1607004
    ページにタブを追加するといったカスタマイズ手順は、以下ドキュメントをご覧下さい。
    Oracle Sales Cloud Customizing Sales Release 11
    Extending Simplified Pages
    Working with Subtabs
    https://docs.oracle.com/cloud/latest/salescs_gs/OACEX/OACEX1078865.htm#OACEX1906352
    Sales Cloudの設定の肝は、WebコンテンツのURLです。
    URLとして、上記のEmbeddable Process UIのstartform.htmlを指定するわけですが、下図の[URL定義]>[スクリプトの編集]に文字列として指定します。つまり、ダブルクォートで囲む必要があります。そのため、必然的にJSONのダブルクォートはエスケープする必要があります。

    Sales Cloudからのデータを初期値として渡したいので、Opportunityオブジェクトの内部IDであるOpportunity ID (OptyId) と、Opportunity Name (Name) を使い、文字列を連結してURLを作成していきます。最終的なURL文字列は以下のようになります(見やすくするため改行を入れていますが、実際には当然ながら1行で指定します)。
    "https://process-xxxx.process.yyy.oraclecloud.com/bpm/components/pages/startform.html?startformData=
    {
      \"processDefId\":\"default~Application!1.0~Process\",
      \"serviceName\":\"Process.service\",
      \"processName\":\"Process\",
      \"title\":\"てすと\",
      \"operation\":\"start\",
      \"startType\":\"START_PCS_FORM\",
      \"isDocsEnabled\":true
    }
    &payload=
    {
      \"opportunityID\":\"" + OptyId.toString() + "\",
      \"name\":\"" + Name + "\"
    }"
    URLを指定後、設定を保存しておきます。

    動作確認

    [営業]>[商談]を開きます。


    任意の商談をクリックします。この例ではTecra Data Inc.をクリックしています。このTecra Data Inc.がOpportunityオブジェクトのOpportunity Nameに相当します。


    作成したSub Tabをクリックします。


    無事にPCSアプリケーションのフォームが開き、Sales CloudのUIに埋め込まれていることがわかります。初期値として、Tecra Data Inc.も確認できます。


    コードらしいコードをほとんど書かずにUIを埋め込むことができました。開発者の立場からすると、コードを書きたくなるのですが、要望が各ツールの標準機能で賄え、さくっと作ることが求められるのであれば、こういうしくみを積極的に使うのもありですね。

    明日12月24日は吉田もとたかさんです。
    Happy holidays and have a great weekend!

    [Java] Java EE 8 - Community Survey Results and Next Steps

    原文はこちら。
    https://blogs.oracle.com/theaquarium/entry/java_ee_8_community_survey2

    Java EE Community Surveyにご協力いただきありがとうございます。1693件の回答があり、その結果をもって、JavaOne 2016でのOracleが提案したJava EEロードマップの提案を含む、21個の異なるコンポーネント・テクノロジーの重要性をランク付けしました。ロードマップの詳細は以下のAnil GaurのJavaOne 2016キーノートの動画をご覧ください。


    アンケートの結果の詳細、および分析は以下のリンクからどうぞ。
    Java EE Survey Results and Java EE 8
    https://java.net/projects/javaee-spec/downloads/download/Java%20EE%20Survey%20Results%20December%202016.pdf 
    下図は、コミュニティからのフィードバックを受けてランク付けしたものをまとめたもので、左から右へ最も重要と回答があったものから順に並んでいます。
    Score ranking

    Conclusions

    このアンケート結果を基にしてJava EE 8提案を見直し、実装上の考慮事項について、追加でレビューしました。その結果、以下のように結論付けました。
    • REST (JAX-RS 2.1) と HTTP/2 (Servlet 4.0) の2つは、アンケートの結果最も重要なテクノロジーということがわかりました。この2つとJSON-Bで、上位6個のテクノロジーの3個を占めています。Java EE 8向けのこれらのテクノロジーの新しいAPIの多くが既に完成しています。これらのテクノロジー、および関連するJSON-Pアップデートを使いJava EE 8をできるだけ早く提供することは大きな価値があります。
    • CDI 2.0、Bean Validation 2.0、JSF 2.3は直接的に調査しませんでしたが、これらのテクノロジーは大幅に進歩しており、Java EE 8に含められる予定です。
    • アンケート結果に基づき、OAuth と OpenID Connect に対するJava EE標準の作成を加速することを検討しました。これはJava EE 8のタイムフレームでは実現できないでしょうが、引き続きJava EE 8のSecurity 1.0の作業を進めていきます。
    • JavaOneで、ConfigurationとHealth CheckingをJava EE 8に加える提案をしたところ、アンケート結果では高いランクに位置づけられています。しかしながら、更なるレビューの結果、この取り組みのスコープはJava EE 8の提供全体を遅らせる可能性があるため、Java EE 8をできる限り速やかに完成させるためには、これらのテクノロジーをJava EEに含めることを延期するのが最善であると結論づけました。
    • Management、JMS、MVCはアンケート結果では優先度が高くないという評価でした。このランキングはJava EE 8からのこれらの領域の新しいAPIを取り下げるという我々の提案を補強するものです。したがってManagement 2.0 (JSR 373)、 JMS 2.1 (JSR 368) を取り下げることにしました。MVCについては、JSR 371をスタンドアロン・コンポーネントとして完成させるため、別のコミュニティメンバーもしくは組織に移転する可能性を検討中です。

    こうした結果にあわせ、Java EE 8提案を改定しようとしています。下表はOracleの当初のJava EE 8提案と改訂したJava EE 8提案を、特に新規API開発に焦点を絞ってまとめたものです。


    Next Steps

    上記アンケート結果と実装上の考慮事項を基に、改訂されたJava EE 8提案を進めていきます。Java EE 8に関する更なるフィードバックをお寄せになる場合は、まだプロジェクトメンバーでない場合はプロジェクトに参加していただいた上で、更に議論するためにメーリングリストに投稿してください。

    [Java] Java SE Offerings

    原文はこちら。
    https://blogs.oracle.com/java-platform-group/entry/java_se_offerings

    Javaエコシステムは非常に多様です。無数のデバイスやサーバーに能力を供給しています。世界中のクラウドインフラストラクチャにとって重要なものです。Java Platform Standard Edition (Java SE) は汎用コンピューティングにとっての中核となるJavaプラットフォームであり、それ自体が多様です。
    Oracle Java Platform Groupが考える、Java SEに関するOracleの主要な4領域での取り組みについて以下で説明します。

    1) OpenJDK http://openjdk.java.net/
    OpenJDKは、Java Platform Standard Editionおよび関連プロジェクトのオープンソース実装で協力する場です。OpenJDKへの強いコミットメントはこれまでと変わらず、先頃JDK 10プロジェクトを開始しました。
    JDK 10
    http://openjdk.java.net/projects/jdk10/
    OpenJDKには、エコシステム全体にわたって幅広く参加いただいています。
    The OpenJDK Open Source Project on Open Hub
    https://www.openhub.net/p/openjdk
    OracleはSunを買収して以来、一貫して活動を続け、広がってきました。 たとえば、Red Hat、Canonical、SUSEなどの主要なLinuxディストリビューターやその他の当事者は、このオープンソースコード・ベースのバイナリを生成して出荷します。ソースコードは一般的なGNU General Public License v2の下で入手できます。つまり、完全に無償です。
    また、数多くの目的のためにソースコードをライセンス供与したいと考えている企業は商用ソースライセンスも入手できますし、そうしている企業は数多くあります。例えばHP、SAP、IBMなどなどの企業は、自身のハードウェアやOS製品を生産しており、そういった製品向けに商用グレードのJava SEを利用できるようにするために商用ソースライセンスを利用しています。

    2) OracleのJava SE実装(Oracle JDKおよびOracle JRE)
    Oracle JRE/JDKはOracleによるJava SEの実装です。SAPやRed Hat、IBM、HPなどの多くの企業が自身の顧客に対して自身の実装を提供しているのと同様に、OracleもOracleの実装を提供しています。バイナリ配布には主要な2個のチャネルがあります。


    これらのバイナリは、java.com/licenseに記載されているように、大部分のユースケースについては無償です。
    Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX
    http://www.oracle.com/technetwork/java/javase/terms/license/index.html

    3) Oracle Java SE Advanced / Java SE Advanced Desktop / Java SE Suite
    Oracleは、Java SE実装とは別に、企業ユーザーをターゲットとする高度なツールと機能も提供しています。
    Oracle Java SE Advanced and Oracle Java SE Suite
    http://www.oracle.com/us/technologies/java/java-se-suite-394230.html
    これらの機能には、企業内でのJavaの監視、管理および展開に役立つツール、高度なランタイム診断と監視のためのツールだけでなく、Java SE 6やJava SE 7といった古いバージョンのJava SEへのサポートやアップデートへのアクセスも含まれます。これらの商用機能は、My Oracle SupportもしくはOTNから個別のダウンロードとして提供されます。Oracle JREと対話する必要がある場合、商用機能はデフォルトでオフになっており、 -XX:+UnlockCommercialFeatures フラグをJVM実行時に指定して有効化できます。
    Java Platform, Standard Edition Tools Reference
    Advanced Runtime Options
    http://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html#BABCBGHF
    この特定の商用機能に関する詳細は、以下のURLにある表1-1を参照してください。
    Oracle Java SE and Oracle Java Embedded Products
    http://www.oracle.com/technetwork/java/javase/terms/products/index.html

     4) Java SE embedded
    (2) での記載通り、Oracle JRE/JDKはたいていのユースケース、汎用目的のデスクトップやサーバー上で実行している場合はでは無料です。お客様がOracle JDK/JREをある種のデバイス(例えばレジ)に組み込みたい場合、無料のBCLライセンスは適用されません。
    Oracle Java SE Embedded
    http://www.oracle.com/technetwork/java/embedded/embedded-se/overview/index.html
    このような場合は商用のJava SE embeddedライセンスを交渉する必要があります。Java SE embeddedでは、リソース制限のあるデバイスや、組み込み向けのチップセットのための追加のバイナリオプションも提供しています。

    [WLS] Configuring Datasource Fatal Error Codes

    原文はこちら。
    https://blogs.oracle.com/WebLogicServer/entry/cofiguring_datasource_fatal_error_codes

    JDBCの操作に関するよく知られたエラーコードは、データベースがシャットダウン中もしくはすでに停止しているとか、構成の問題であると解釈されます。このエラーが発生した場合、後続の操作が失敗し、ハングアップするか、完了までに時間がかかるため接続を維持したくありません。こうしたエラーコードは、"fatal-error-codes"という値を接続プールのパラメータで利用しデータソース構成で構成することができます。この値はエラーコードをカンマで区切ったリストです。SQLExceptonがJDBCの操作で見られたり、sqlException.getErrorCode()が構成済みのコードのいずれかに一致したりする場合、接続を接続プールに返さずに接続を閉じます。
    以前のOC4Jアプリケーション・サーバー(Oracle Internet Application Server)の場合、任意の接続でこれらのエラーのいずれかが発生した場合には、接続プール中の全ての接続を閉じましていましたが、WebLogic Serverでは、致命的なエラーが発生した接続を閉じるだけにしました。これにより、使用できないデータベースの場合に加え、問題のある接続に固有のエラーコードを追加することができます。
    Oracle® Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの管理 12c (12.2.1.1)
    致命的エラー・コードの定義
    http://docs.oracle.com/cd/E80149_01/wls/JDBCA/jdbc_datasources.htm#CJAIGEAAOracle® Fusion Middleware Administering JDBC Data Sources for Oracle WebLogic Server 12c (12.2.1.2.0)
    Define Fatal Error Codes
    http://docs.oracle.com/middleware/12212/wls/JDBCA/jdbc_datasources.htm#JDBCA520
    以下のエラーコードは事前構成済みで、無効化することはできません。個々のデータソースについて、これらのドライバや別のドライバに対応したエラーコードを追加することができます。
    ドライバの種類デフォルトの致命的エラーコード
    Oracle Thin Driver3113, 3114, 1033, 1034, 1089, 1090, 17002
    WebLogic or IBM DB2 driver-4498, -4499, -1776, -30108, -30081, -30080, -6036, -1229, -1224, -1035, -1034, -1015, -924, -923, -906, -518, -514, 58004
    WebLogic or IBM Informix driver-79735, -79716, -43207, -27002, -25580, -4499, -908, -710, 43012
    以下は致命的なエラーコード文字列を既存のデータソースに追加するためのWLSTスクリプトです。
    # java weblogic.WLST fatalerrorcodes.py import sys, socket, os hostname = socket.gethostname() datasource="JDBC GridLink Data Source-0" connect("weblogic","welcome1","t3://"+hostname+":7001") edit() startEdit() cd("/JDBCSystemResources/" + datasource ) targets=get("Targets") set("Targets",jarray.array([], ObjectName)) save() activate() startEdit() cd("/JDBCSystemResources/" + datasource + "/JDBCResource/" +  datasource + "/JDBCConnectionPoolParams/" + datasource ) set("FatalErrorCodes","1111,2222") save() activate() startEdit() cd("/JDBCSystemResources/" + datasource ) set("Targets", targets) save() activate()
    
    実験的に、RESTで試してみました。
    localhost=localhost
    editurl=http://${localhost}:7001/management/weblogic/latest/edit
    name="JDBC GridLink Data Source-0"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -X GET ${editurl}/JDBCSystemResources/${name}/JDBCResource/JDBCConnectionPoolParams?links=none"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json -d "{}" -X POST "${editurl}/changeManager/startEdit"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json -d "{ targets: [] }" -X POST "${editurl}/JDBCSystemResources/${name}"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json -d "{ fatalErrorCodes: '1111,2222' }" -X POST "${editurl}/JDBCSystemResources/${name}/JDBCResource/JDBCConnectionPoolParams"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json -d "{ targets: [ { identity: [ servers, 'myserver' ] } ] }" -X POST "${editurl}/JDBCSystemResources/${name}"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -H Content-Type:application/json -d "{}" -X POST "${editurl}/changeManager/activate"
    
    curl -v --user weblogic:welcome1 -H X-Requested-By:MyClient -H Accept:application/json -X GET "${editurl}/JDBCSystemResources/${name}?links=none"
    

    [Java] Get Ready and Contribute to JDK 9

    原文はこちら。
    https://blogs.oracle.com/java/get-ready-and-contribute-to-jdk-9

    JDK 9への貢献方法を知って、早期アクセスリリースを使ってみなさんのコードをテストしてください。今回は、HTTP/2、JShell、Java 9モジュールシステムについてご紹介します。これは、2017年7月のJava 9リリースに向けてのアウトリーチ活動の一環で実施している一連のセッションの最初のセッションで、vJUGとIceJUGが主催しています。

    Java Community Process (JCP) プログラムへの参加方法を理解し、個人、企業、JUG (Java user group) のような非営利団体として参加してください。
    Adopt-a-JSR プログラムやAdopt OpenJDKプログラムへの参加方法を理解してください。現在、新しいJSRが提出されており、Java EE 8やJava SE 9プラットフォーム用に開発されています。Java標準に貢献できる方法を見つけてください。

    Mani Sarkar と Hendrik Ebbersが数多くのデモを実施しています。
    これらのプレゼンテーションで言及されているリンクは以下の通りです。

    [Java, Security] Oracle JRE will no longer trust MD5-signed code by default (Updated)

    以前、以下のエントリをご紹介しました。

    Oracle JRE will no longer trust MD5-signed code by default
    https://blogs.oracle.com/java-platform-group/entry/oracle_jre_will_no_longer
    [Java, Security] Oracle JRE will no longer trust MD5-signed code by default
    https://orablogs-jp.blogspot.jp/2016/10/oracle-jre-will-no-longer-trust-md5.html
     当初、1月のCPUで実施する予定でしたが、多くのご要望を受け、4月のCPUで実施する予定です。そのため、原文は1月ではなく、4月に変更されています(上記内容も原文の記述に合わせて変更済みです)。
    パブリックなJava Cryptographic Roadmapも更新されています。
    Oracle JRE and JDK Cryptographic Roadmap
    https://www.java.com/en/jre-jdk-cryptoroadmap.html
    暗号強度の変更点や開始時期などは、上記ページを参照してください。

    [Database] Transportable Tablespaces and READ ONLY in Oracle Database 12c

    原文はこちら。
    https://blogs.oracle.com/UPGRADE/entry/transportable_tablespaces_and_read_only

    先日、トランスポータブル表領域を使って、同じ表領域のデータファイルを2個のデータベースに同時に接続することができない(表領域をSQL*PlusでREAD ONLYにした後にもかかわらず、です)ことに気付いたお客様と一緒に作業しました。これは12cでの新しい挙動であり、多くのお客様がまだこの変更に気付いていないことでしょう。以下に変更点とその理由、そしてこの変更が貴社の環境に影響する場合の対処法について説明します。

    What Changed?

    12cR1から、トランスポータブル表領域の移行のインポートフェーズの間、data pumpは表領域をread writeに設定します。これはつまり、トランスポータブル表領域を使用して、表領域を2つの異なるデータベースに同時にフックすることはできない、ということです。

    Why Was This Change Made?

    以下のようないくつかの要因があって変更されました。

    まず第一に、データベースが増加するにつれて、多くのパーティションやサブパーティションを含む表または索引のための多くのパーティションやサブパーティションを含む表領域を処理する場合にパフォーマンスが低下することがありました。この理由(あまりにひどい場合はお詫びします)は、表領域を移動しているけれども当該表領域内の全ての表が操作の対象ではない場合には、空き領域を再利用できるようにしているためです。たとえば、5個の表のパーティションを含む表領域データファイルを移動することはできますが、それらの表のうち2個しか関心がない場合があります。その場合、別の3個の表が使用するセグメントは再利用対象のデッドスペースになります。

    12c以前は、エクスポート・フェーズで最初にエクスポート対象の全てのセグメントを記録し、インポート・フェーズで当該セグメントをインポートすることで、この領域を再利用していました。これにより、インポート対象外のセグメントのスペースをすべて解放することができました。これは確かにうまくいきましたが、bigfile表領域が数十テラバイトにまで達するにつれ、パフォーマンスの劣化が激しくなりました。文字通り数日かかることもありました。そのため、12cでは異なる方式を実装しました。もうエクスポート時にセグメントを記録せず(これは11gへのバックポートとしても利用できます)、インポート時に表領域のビットマップを再計算します。ビットマップの再計算にあたっては、DBMS_SPACE_ADMIN.TABLESPACE_REBUILD_BITMAPSを呼び出し、数時間を要する可能性があった以前の方法に比べてあっという間で終了します。
    したがって、多数のデータセグメントを含む場合、トランスポータブル表領域のエクスポート、インポートの両方でこの変更により、非常にパフォーマンスが改善されます。

    この変更を実施した2番目の理由は、トランスポータブル表領域を使って、Timezone(TSTZ)データを持つ異なるバージョンのTimestampを使うデータベースに対し、表領域のデータベースへのインポートを実現するためです。12cより前では、データベース間でTSTZデータを移動するにあたり多くの制限がありましたが、徐々にこれらの制限を緩和して制限を取り除くことができました。ここでDatabaseユーティリティガイド (11.2.0.4) から引用してみます。
    Oracle® Database Utilities 11g Release 2 (11.2)
    Considerations for Time Zone File Versions in Transportable Tablespace Mode
    https://docs.oracle.com/cd/E11882_01/server.112/e22490/dp_import.htm#SUTIL3777
    Oracle® Databaseユーティリティ 11gリリース2 (11.2)
    トランスポータブル表領域モードでのタイムゾーン・ファイルのバージョンに関する考慮点
    http://docs.oracle.com/cd/E16338_01/server.112/b56303/dp_import.htm#SUTIL3777
    12cR1から、より高いtimezoneバージョンを持つデータベースに表領域を移動する際にもTSTZデータを取り扱うことができます。これは、表領域データファイルを開き、この目的のために12cで作成された機能を使ってTSTZデータを修正することによって実現しています。つまり、12cを使うとトランスポータブル表領域をより多くのシナリオで利用でき、さらにTimezoneデータを含むTimestampがある場合に、結果として得られるインポートがより完全になることを意味します。

    まとめると、トランスポータブル表領域のインポート時にデータファイルをread writeで開くように変更した結果、処理はより高速になり、このテクニックがより幅広く適用できるようになった、ということです。

    But Neither of those Benefits Affect Me, and I Like the Old Behavior!

    当該目的のために明示的にパラメータを実装することで、旧バージョンの挙動を許可することが可能な場合がありますが、このパラメータを使用する場合、次のような欠点があります。我々が旧バージョンの挙動を許すことができる可能性があります。
    1. 比較対照とすべきエクスポートされたセグメントのリストがないため、トランスポータブル表領域をimpdp操作中にインポートされたセグメントを構成することはできません。ユーザーが明示的にプロシージャDBMS_SPACE_ADMIN.TABLESPACE_REBUILD_BITMAPSを呼び出すまで、当該セグメントはデッドスペースになります。
    2. インポート対象の任意の表領域にTSTZデータが含まれている場合、
      • インポートするデータベースのtimezoneバージョンが正確にエクスポートされたデータベースのそれと一致する必要があります。
      • 一致しない場合、インポートは失敗します。
      しかしながら、旧バージョンの挙動を残すという目的を達成するために、新しいパラメータを必要としていません。
      もしファイルをOSレベル(もしくはASM)でREAD ONLYに設定すると、その設定により、データベースレベルでread writeに設定することはできなくなります。これはつまり、未使用のセグメントを空き領域に再利用しないということを意味し、結果としてTSTZの修正は実行されません。この場合、移行先のデータベースのTimezoneバージョンがインポート対象のデータのそれと一致しなければ、TSTZデータを持つ任意の表はインポート時に削除されます。

      データ・ポンプ開発チームはこの変更によって得られるメリットが、機能の損失よりもはるかに上回るものと見てしまいがちですが、たくさんのお客様がデータ・ポンプの様々なユースケースをもち、データ・ポンプに対する位置づけが千差万別であることを認識しています。そのため、前述のようにオプションの提供を希望される場合は、是非エンハンスメント・リクエストを検討くださると幸甚です。

      [Database] Questions You Asked: I installed the latest PSU, why am I still getting this error?

      原文はこちら。
      https://blogs.oracle.com/In-Memory/entry/questions_you_asked_i_installed

      Database In-Memoryチームはこの数ヶ月Database In-Memoryの新機能について知らせるためにコンファレンスへ数多く参加してきました。これらのコンファレンスにはOpen World、East Coast Oracle Users Conference (ECO)、Bulgarian Oracle User Group (BGOUG) コンファレンス、German Oracle User Group (DOAG) コンファレンス、SANGAM16(All India Oracle Users Group (AIOUG) conference)が含まれますが、ご参加いただいたり、ご質問いただいた皆様に感謝申し上げます。
      引き続き尋ねられる質問の一つにPatch Set Updates (PSUs)があります。現在も引き続きPSU(MOS Note 854428.1を参照)やCritical Patch Updates (CPUs) をインストールし、Database In-Memoryの修正を得ようとしている人を探しています。
      Patch Set Updates for Oracle Products (Doc ID 854428.1)
      https://support.oracle.com/rs?type=doc&id=854428.1
      Critical Patch Updates, Security Alerts and Third Party Bulletin
      http://www.oracle.com/technetwork/topics/security/alerts-086861.html 
      この件について以前エントリをUpしましたが、重要なので繰り返します。
      Oracle Database In-Memory Bundle Patch 10 Released
      https://blogs.oracle.com/In-Memory/entry/oracle_database_in_memory_bundle3
      Database In-Memoryは2014年6月のOracle Database 12c Release 1 Patch Set (12.1.0.2) からご利用いただけるようになりました。以後、多くの機能強化と修正を加えましたが、こうした変更を全て取得する唯一の方法は、Database Proactive Bundle Patch(MOS Note 1937782.1を参照)として知られるものを入手することです。
      12.1.0.2 Database Proactive Bundle Patches / Bundle Patches for Engineered Systems and DB In-Memory - List of Fixes in each Bundle (Doc ID 1937782.1)
      https://support.oracle.com/rs?type=doc&id=1937782.1
      多くの人がDatabase Proactive Bundle PatchはEngineered Systemsのためのみにあると考えてらっしゃいますし、他の方はPSUsやCPUsに全ての修正が含まれていないと考えてらっしゃいます。MOS Note 1937782.1に記載されているように、各Bundle Patchには追加の予防的な修正とともに全てのDatabase PSUでの修正が含まれています。これらの予防的な追加修正のいくつかは全てのDatabase In-Memoryの修正を含んでいます。

      基本的に、Database In-Memoryを利用する場合には、最新のDatabase Proactive Bundle Patchを適用してください。

      結局のところ、車輪を再発明したり、既に修正されている問題を発見したり、既に提供済みの改善機能を利用しなかったりするのは意味がありませんから。

      [Database] Upgrade to Oracle Database 12.2 - Slides are available

      原文はこちら。
      https://blogs.oracle.com/UPGRADE/entry/upgrade_to_oracle_database_12

      ブリュッセルとユトレヒトでのワークショップにはたくさんの方に参加いただき、非常に楽しかったです。ブリュッセルでのワークショップのうち、午前中はマイクの問題で聞きづらくなってしまい申し訳ありませんでした。
      お約束の通り、ワークショップで利用したスライドがダウンロードいただけるようになっています。
      Upgrade, Migrate and Consolidate to Oracle Database 12.2 and the Cloud
      Slides Oracle 12.2 Upgrade Migrate Consolidate
      [注意]
      このスライドは初版なので、Oracle Database 12cR2用にアップデートが完了していない箇所があります。もちろん12cR2の顧客事例はスライド内にはありません。しかしながら、いつも通りOracle Database 12cR2を早期に導入しようとしているのであれば、既にOracle Cloudで利用できますし、まもなくオンプレミスでもご利用いただけるようになりますので、その際には将来の顧客事例ということで、是非ご連絡ください。

      [Database] Introducing PGX - Parallel Graph Analytics - 2.2.1

      原文はこちら。
      https://blogs.oracle.com/labs/entry/introducing_pgx_parallel_graph_analytics

      OracleのR&D LabsからParallel Graph Analytics (PGX) 2.2.1がリリースされました。
      Oracle Labs PGX Downloads
      http://www.oracle.com/technetwork/oracle-labs/parallel-graph-analytics/downloads/index.html
      これは、透過的に並列化可能なアルゴリズムをフレームワークが記述するためのDSLを使ってグラフのアルゴリズム的解析と、SQLライクなクエリ言語を使ったグラフのパターンマッチング、その両方のグラフ解析を実施するための高性能なツールキットです。
      PGQL · Property Graph Query Language
      http://pgql-lang.org/
      Groovyシェルを使って対話的に利用することも、様々なAPIを使った自動化ワークフローに統合することもできます。
      既にPGXのことをご存知であれば、PGX 2.2.1の新機能をご覧ください。
      PGX 2.2.1 Documentation
      What is New in PGX 2.2
      https://docs.oracle.com/cd/E56133_01/2.2.1/whatsnew/whatsnew.html
      グラフ解析は、あなたが持っているデータで明示的に表現されるものではなく、既に持っているデータ要素間の関係のネットワークで表現される潜在情報を明らかにします。

      Who Has A Graph?

      みんな持っています。あるフィールドを共有するデータがある場合(リレーショナルデータベースを使用している場合)、知っているかどうかに関わらず、グラフを持ちます。
      ソーシャルネットワークのおかげでグラフ分析が知られています。最も明白でアクセス可能なグラフの例が、ソーシャルネットワークが生成する友人間のネットワークです。この例は非常に鮮明ゆえに、ソーシャルネットワーク分析はこの種の技術が適しているという印象を作り出します(とはいえ、真実以上のものはないのですが)。グラフ分析のパワーは、グラフの頂点がすべて同じ種類のものではない場合に顕著に現れます。 例えば次のような場合です。
      • ある頂点が人で、ある頂点が評価した動画であるグラフを作成します(マトリックス因数分解や、アルゴリズム技術を使うと、推奨エンジンを作成することができます)。そして実際、これはNetflixが実施している推奨方法です。
        Using PGX as a Recommendation Engine
        https://docs.oracle.com/cd/E56133_01/2.2.1/use-cases/recommendation/index.html
        • リコメンデーションとは予測です。既存データを使って存在しないデータを外挿したり、データ内の潜在的な関係を予測したいどんな領域にも、このテクニックだけを応用することができます。
      • 異常検出
        どのような関係がデータセット内で典型的であるかを検出します。例えば、特定の専門分野の医師がどんな薬をどのようなランクで処方しているのかを基にして、典型的ではない医師を特定します。また、保険の請求や保険金請求者、車両事故をグラフでモデリングし、地理的に近い複数の請求の両方の立場の関係者を見つけ出して、保険金の搾取高位を検出します。
        Detect Anomalies in a Healthcare System
        https://docs.oracle.com/cd/E56133_01/2.2.1/use-cases/healthcare-fraud/index.html
      • 電力グリッドのモデリングや、オフラインのグリッド個々の要素のダウンストリーム効果を判断して、脆弱性の識別やメンテナンスを計画します。
        Modeling an Electric Network With PGX
        https://docs.oracle.com/cd/E56133_01/1.2.0/use-cases/electric-network/index.html
      これらはグラフ解析の利用例の一例に過ぎません。別の興味深い例として、どうやってAmerican Revolutionが利用可能なメタデータやこうしたテクニックを使えなくさせたのか、という以下の記事です。
      Using Metadata to find Paul Revere
      https://kieranhealy.org/blog/archives/2013/06/09/using-metadata-to-find-paul-revere/
      ここがポイントです。テクノロジ業界はグラフ解析のアプリケーションの表面をほとんど傷つけず、PGXによって、これまで政府にのみ利用可能になっていた数学のツールがすぐ使えるようになりました。

      Using PGX

      たくさんのチュートリアルがご利用いただけますが、PGXを操作するにあたって主要な手順はシンプルです。
      Tutorials
      https://docs.oracle.com/cd/E56133_01/2.2.1/tutorials/index.html
      PGXツールキットをダウンロード、インストールしてから、コマンドラインで実行するのはプログラムpgxを実行するのと同じぐらい簡単です。pgxはPGXシェルとグラフ・エンジン(リモートにデプロイされているものでもOK)の組み込みインスタンスを始動します。

      一般的な利用パターンはシンプルです。
      1. (SQLデータベース、Oracle NoSQL、フラットファイル、Hadoop、Apache Sparkなどから)グラフをロードする
      2. 多くのビルトインされている(もしくはカスタム開発した)アルゴリズムのうちの一つもしくは複数をグラフに対して実行する。アルゴリズムは通常新しいプロパティをグラフの頂点やエッジに追加する。
        Algorithms
        https://docs.oracle.com/cd/E56133_01/2.2.1/reference/algorithms/index.html
      3.     PGQLを使ってアルゴリズムを用いたパターンマッチを実行する
      このプロセスの手順を必要に応じて繰り返すことができ、結果を使ってレポートの生成やCSVファイルの出力ができます。PGXのJava APIやNode.jsのAPIを使っている場合、自動化されたワークフローに参加させることもできます。これらの手順全てをGroovyスクリプトとして保存し、再実行することができます。グラフ解析の重要な要素の一つは、再生産できること、アップデートされたデータに対して後で適用できることです。

      Examples

      Groovy Shell

      PGXを手早く動かすにあたっては、Groovyシェルが最も簡単です。これを使うと対話的にグラフ解析ができます。例えば以下のような感じです。
      graph = session.readGraphWithProperties(
        "../gameofthrones/stormofswords.json").undirect();
      
      prop = analyst.eigenvectorCentrality(g);
      graph.queryPgql(
        "SELECT v.id(), v.eigenvector WHERE (v)
                  ORDER BY DESC(v.eigenvector)")

      PGQL

      Property Graph Query Language(PGQL)はオープンソースのSQLライクなグラフをクエリするための言語です。特に、値による制約(例:eigenvector > 0.9)とともに、トポロジーの制約を指定することができます。これらを使って、グラフの接続内で探索するパターンを指定することができます。
      SELECT v.id() WHERE (t WITH t.id() = 'Tyrion') -[]-> () -[]-> (v)
      
      この例では、TyrionというIDを持つ頂点に間接的に接続されている全ての頂点を検索しています。

      Recursive topological constraints

      パスクエリを定義し利用すると、再帰的にパターンを適用することもできます。以下は2人の共通の祖先を全て探す例です。
      PATH has_parent := () -[:has_father|has_mother]-> ()
      SELECT ancestor.name
      WHERE
        (:Person WITH name = 'Mario') -/:has_parent*/-> (ancestor:Person),
        (:Person WITH name = 'Luigi') -/:has_parent*/-> (ancestor)
      
      上記の例では、Marioのクエリは、ancestorという名前のMarioの祖先のある場所で頂点を定義しています。第2のLuigiの制約では、ancestorが、Mario用に定義された同じ頂点がある(つまり両方の祖先と同じ人物)ことを発見することを求めています。出力は、SQLの結果セットとは似ていない結果セットですが、これをレポートの生成や後続の処理に使用できます。

      Green-Marl

      Green-Marlは、ファーストクラスの言語要素として、頂点、エッジ、プロパティ、幅優先、深さ優先の検索を持つグラフアルゴリズムを記述するための言語です。特に、ループ構造は、同時実行性を管理するコードを記述しなくても、ランタイムによって透過的に並列化されるため、記述したアルゴリズムは自動的に利用可能な処理能力の全てを利用します。

      PGXには多数のアルゴリズムが組み込まれていますが、自身でアルゴリズムを記述しコンパイルすることができるため、必要な分析タスクを柔軟に実行することができます。
      proc weighted_degree_centrality( g: graph,
        weightProp: E_P<double>; outputProperty: N_P<double> ) {
      
          // Get the range of weight values
          int minWeight = min( curr_edge : g.edges ) { curr_edge.weightProp }; // find the lowest weight value
          int maxWeight = max( curr_edge : g.edges ) { curr_edge.weightProp }; // find the highest weight value
      
          foreach ( vtx : g.nodes ) { // iterate every node
              double weight = 0;
              for ( curr_edge : vtx.outEdges ) { // sum the weights
                  weight += curr_edge.weightProp;
              }
              // Compute and assign the weighted result for this vertex
              vtx.outputProperty = vtx.degree()  * ( ( weight - minWeight ) + 1 );
          }
      }
      

      Using PGX with Apache Zeppelin

      PGXのこのリリースには、Apache Zeppelinのインタープリタが含まれています。これは"notebook"サーバと言われるもので、解析のステップ、これらのステップの説明、インタラクティブかつ協働して分析を実施したり、インタラクティブなレポートの形で結果を保持する方法を取得するための簡便な方法を提供します。
      Apache Zeppelin
      https://zeppelin.apache.org/
      利用にあたっては、Zeppelinをインストールし、Zeppelinインタープリタをダウンロードして、Zeppelinのinterpreterディレクトリにインストールして、新しいnotebookを構成する必要があります。
      Oracle Labs PGX Downloads
      http://www.oracle.com/technetwork/oracle-labs/parallel-graph-analytics/downloads/index.html

      Performance

      グラフはPGXのメモリ上にあるため、パフォーマンスはメモリの容量と利用可能なCPUの個数によってのみ制限を受けます。Javaエンジンはオフヒープストレージと非常に効率的なデータ構造を使うため、サーバークラスのハードウェアが有用ではあるにせよ、驚くほど大きなグラフをラップトップで分析することができます。そして、アルゴリズム分析、パターンマッチング分析の両方を並列化するので、どんなコンピュート・リソースも十分に活用することができます。
      大量のデータがある場合、データを他の場所にあるメモリに取り込むインメモリ解析が不便になる可能性があります。 ただし、次の点を考慮してください。
      • グラフ解析の特徴の1つとして、指定された任意のアルゴリズムで、頂点を任意の順序で何回も訪れることができます。
      • HadoopやSparkのような環境では、データが複数のマシンに分散しており、それらのマシンでHadoopやSparkが動作するため、共有コンピュート・リソースで利用される変数の単純なアップデートでさえもネットワークI/Oが発生します。そして変数は何度も更新される可能性があり、ときにはグラフのノードの個数の倍になることがあります(ネットワークアクセスはネットワークI/Oに比べて数桁遅いのです)
      要約すると、グラフ解析の性質ゆえに、1回のグラフをロード(して、そしてメモリアクセスの速度で解析を実行できる)するI/Oコストは例えばSparkのGraphXよりもずっと低コストです。
      PGXには、単一のノードに収まらない大きなグラフを解析するための、複数のマシンにセットアップ可能な分散分析エンジンも含まれています。

      [Integration] Processing high volumes of updates to a single row using OSA

      原文はこちら。
      https://blogs.oracle.com/integration/entry/processing_high_volume_updates_using

      今日の世界では、指数関数的にデータが生成されています。このような情報をすべて収集して処理して興味深い傾向を発見するための新しいビッグデータ・テクノロジーが利用できますが、即時対応する必要があったり、特定の項目の現在の状況を知りたいという場合もあります。このような要求を実現するために、すべての着信データを保存することもできますが、トレードオフとして、不要なデータを大量に保持し、ユーザーが最初に最新のレコードを決定するクエリを作成する必要があります。別の手法として、データベースの更新を行うこともできますが、デバイスが頻繁にステータスメッセージを送信する可能性があるIoT領域のような、単一の行が頻繁に更新されるシナリオでは、データベースの競合が発生する可能性があります。
      この問題を解決する方法の一つとして、あまり知られていませんが、Oracle Stream Analytics(OSA)の利用があります。OSAは、SQLに類似しSQL-99に準拠しつつも、インメモリでの操作と問題を非常に効率的な解決のために、追加の構文を備えた、Continuous Query Language(以下CQL)という非常に洗練された言語を利用することができます。不要なデータベースの更新を避けるという課題は、OSAが十分に、しかもたった1個のクエリでとても簡単に解決します。
      はじめにOSAランタイムの基本情報を説明します。非常に使い安いOSAのユーザーインターフェースを使い、わずかな時間でアプリケーション全体を開発することができるだけでなく、JDeveloperを使用した従来の方法でもアプリケーションを開発することができます。JDeveloperを使用して開発する場合、「イベント処理ネットワーク(Event Processing Network、以下EDN)」と呼ばれるアプリケーション・モデルを理解する必要があります。
      EPN
      EPNは、アプリケーションからのデータフローを処理します。EPNには実行させたいCQLを保持するCQLプロセッサノードが含まれます。今回のケースでは、数十行のJavaコードを使って書き込むという比較的複雑なタスクを実行するためのCQLを、下図のような非常にシンプルな文を使い、非常に簡単かつ効率的にメモリ内で実行します。
      CQL
      このクエリでは、必要な属性(SELECT * FROM InputChannelも使用できます)のみを選択し、CQL構文を使用してストリームをデバイスIDで"ROWS 1"を使ってパーティション化します("ROWS 1"は、各デバイスID毎に1個の行だけという意味です)。このデバイスIDごとの1行を"RANGE 2 SECONDS"で指定した2秒間保持し、結果を2秒毎(SLIDE 2 SECONDS)に出力します。ここで、"RANGE"と"SLIDE"で指定した値が同じ時間間隔の場合、本質的には2秒ごとに(クエリに状態を持たずに)最初からやり直すことになります。

      [注意]
      2秒が長いという場合には、1秒もしくはミリ秒単位で時間を指定してください。

      このテストでは、データはランダムに生成されますが、データと結果が正確かどうかを確認します。今回は、Oracle BAM 12cにデータを送信します。JMS Mapメッセージとしてデータを自動的に書き出すJMSアダプタを使用してOSAアプリケーションからデータを出力するようにします(設定はイベント・タイプ名をOSA JMS構成に指定するだけです。標準のJMSアダプタはコンバータクラスを使わずにJMSメッセージを作成します)。今回こうした理由は、以下の点で便利だからです。
      • BAMのEnterprise Message Sources(以下EMS)をBAM 12c管理者ページで簡単に構成でき、Mapメッセージ属性をデータオブジェクトへ割り当てることができる。
      • OSAおよびBAMで全て完結し、Javaコードを一切各必要がない


      このテストのために、空のデータオブジェクトから始め、EMSメトリックをリセットすることをお忘れなく。

      私たちのBAM EMSは "Upsert" で構成されています。これは、レコードが存在しない場合は、(deviceIDとして定義されているキーに基づいて)レコードを挿入し、当該デバイスIDを持つ行がデータオブジェクト(つまりデータベース表)に既に存在する場合には、更新することを意味します。

      まず、管理した状態で少量のデータセットを送信し、期待どおりに動作することを確認しましょう。たった10個の一意のデバイスIDに対応する30個のイベントを送信し、各イベント間には意図的にわずかな遅延を挟むことにします。


      10個の異なるデバイスIDがサンプル中にあり、10個のメッセージが永続化されているため、10個のメッセージのみが送信されたというBAM EMSのメトリックが正しいことがわかります。

      デバイスID毎にdeviceCodeとcodeValueを調査すると、これらのメッセージがBAMダッシュボードでユーザーに見てもらいたい直近10メッセージ(各デバイスから送信された最新のメッセージ)であることがわかります。

      ”Upsert”の操作のためのキーフィールドが2個ある場合、次のようにコンマで区切られたpartition by句の両方にそれらを並べることができます。

      データオブジェクトにはもっと多くの行の組み合わせがあるかもしれませんが、Device ID、Device Codeの組み合わせの1エントリだけにしておきます。

      是非ご自身で試してください。そうすれば、デバイスの最新の状態を非常に迅速かつ簡単に提供するという目標を達成していることを目の当たりにされることでしょう。同じ行を何度も更新するためにデータベースの競合を潜在的に発生させる可能性がある、不要なJMSメッセージを生成し、ネットワークを介して送信し、Queueに配置した後に、BAMのEMSがQueueから取り出し、処理する必要はなくなります。ユーザーにデバイスの最新状態のメッセージを配信するという目的を満足するためのソリューションの効率を非常に簡単に、大幅に向上しました。そして、追加ボーナスとして、迅速に上書きされるメッセージを生成しないために他の目的にCPU利用率を節約できたので、運用効率も向上しました。

      [Java] A quick update on Java EE

      原文はこちら。
      https://blogs.oracle.com/theaquarium/entry/a_quick_update_on_java

      OracleはJavaコミュニティに対し、Managemennt 2.0 (JSR 373) とJMS 2.1 (JSR 368) を取り下げる予定であることをお知らせしています。MVCについては、コミュニティからのフィードバックに対し、MVCを別のコミュニティメンバーもしくはコミュニティを構成する組織に可能な限り任せ、JSR 371をスタンドアロンコンポーネントとして完成してもらうことを目指して現在研究中です。

      こうした変更はJavaOne 2016で紹介した改訂版Java EEロードマップと一貫しています。ロードマップでは、OracleはこれらのJSR をJava EEに含めないことを提案していました。詳細はJavaOne 2016基調講演のAnil Gaurのパートと、Linda DeMichielのJava EE 8 Updateのプレゼンテーションをご覧ください。

      JavaOne基調講演


      Java EE 8 Update


      この変更は、OracleがJava EEコミュニティアンケートを受けて、上記テクノロジーの重要度の順位付けを反映したものです。Managemennt、JMS、MVCは調査対象のテクノロジーの中で最下位近辺の順位でした。近いうちにアップデートとして、調査結果の全体像とJava EE 8の次のステップを説明する予定です。

      [Database] Enabling ADAPTIVE Features of Oracle 12.2 in 12.1

      原文はこちら。
      https://blogs.oracle.com/UPGRADE/entry/enabling_adaptive_features_of_oracle

      Oracle Database 12.2では、新たな分割されたアダプティブ・パラメータであるOPTIMIZER_ADAPTIVE_FEATURES と OPTIMITER_ADAPTIVE_STATISTICS が導入されます。
      詳細は、以下のエントリをご覧ください。
      OPTIMIZER_ADAPTIVE_FEATURES obsolete in Oracle 12.2
      https://blogs.oracle.com/UPGRADE/entry/optimizer_adaptive_features_obsolete_in
      [Database] Optimizer Adaptive Features in the Exadata Express Cloud Service
      https://orablogs-jp.blogspot.jp/2016/10/optimizer-adaptive-features-in-exadata.html
      Optimizer Adaptive Features in the Exadata Express Cloud Service
      https://blogs.oracle.com/optimizer/entry/optimizer_adaptive_features_in_the
      [Database] OPTIMIZER_ADAPTIVE_FEATURES obsolete in Oracle 12.2
      https://orablogs-jp.blogspot.jp/2016/11/optimizeradaptivefeatures-obsolete-in.html
      しかし、オンプレミス版のOracle Database 12.2はまだ出ていません。では、Oracle Database 12.2にアップグレードする際にはどうしたらよいのでしょうか。Oracle Database 12.1のアダプティブ機能をどうすればよいのでしょうか。
      Recommendations for Adaptive Features in Oracle Database 12c Release 1 (12.1) (Doc ID 2187449.1)
      https://support.oracle.com/rs?type=doc&id=2187449.1
      Oracle Database 12.1からアップグレードする際にはOracle Database 12.2のデフォルトを採用することを推奨しています。これは以下の2個のパッチを適用することで実現できます。この方法を推奨アプローチと呼んでいます。
      • bug# 22652097 に対するパッチ(Patch 22652097: PROVIDE SEPARATE CONTROLS FOR ADAPTIVE PLANS AND ADAPTIVE STATISTICS FEATURES)
        OPTIMIZER_ADAPTIVE_PLANSOPTIMIZER_ADAPTIVE_STATISTICSという2個のパラメータを導入し、OPTIMIZER_ADAPTIVE_FEATURESというパラメータを削除します。
      • bug# 21171382 に対するパッチ(Patch 21171382: AUTO DOP COMPUTES A HIGH DOP UNNECESSARILY)
      • オプティマイザ・プリファレンスAUTO_STATS_EXTENSIONSONでない場合には、拡張統計の自動作成を無効化します。
      パッチ適用時には、以下の操作を実施して、OPTIMIZER_ADAPTIVE_FEATURESSPFILEから削除されていることを確認してください。
      alter system reset optimizer_adaptive_features;
      すでにOracle Database 12.1にアップグレードしているけれどもパフォーマンス上の問題が発生している場合には、どちらのパッチも効果があります。
      ご注意いただきたいのは、OPTIMIZER_DYNAMIC_SAMPLING をデフォルト値以外に設定することは必ずしも必要ではない、ということです。その理由は、新しい両パラメータをデフォルト設定で利用すると、パッチがアダプティブ動的サンプリング(adaptive dynamic sampling)の利用を無効化し、Oracle Database 12.2のデフォルトの挙動に一致するためです。

      [Database] OPTIMIZER_ADAPTIVE_FEATURES obsolete in Oracle 12.2

      原文はこちら。
      https://blogs.oracle.com/UPGRADE/entry/optimizer_adaptive_features_obsolete_in

      Oracle Database 12.1のパラメータであるOPTIMIZER_ADAPTIVE_FEATURESは、Oracle Database 12.2で廃止されました(つまり、アップグレードするとSPFILEから削除されます)。
      このパラメータに変わり、2個のパラメータが導入されます。そのうち1個はデフォルトで有効化、他方は無効化されています。
      • OPTIMIZER_ADAPTIVE_PLANS=TRUE (デフォルト値)
      • OPTIMITER_ADAPTIVE_STATISTICS=FALSE (デフォルト値)
      OptimizerのプロダクトマネージャであるNigel Baylissが既に詳細な説明とともにエントリをアップしています。
      Optimizer Adaptive Features in the Exadata Express Cloud Service
      https://blogs.oracle.com/optimizer/entry/optimizer_adaptive_features_in_the[Database] Optimizer Adaptive Features in the Exadata Express Cloud Service
      https://orablogs-jp.blogspot.jp/2016/10/optimizer-adaptive-features-in-exadata.html
      とはいえ、オンプレミス版Oracle Database 12.2はまだ利用できないので、この機能をOracle Database 12,1で取り扱うにはどうすればよいのでしょうか。

      詳細は以下のエントリでご紹介します。
      Enabling ADAPTIVE Features of Oracle 12.2 in 12.1
      https://blogs.oracle.com/UPGRADE/entry/enabling_adaptive_features_of_oracle
      [Database] Enabling ADAPTIVE Features of Oracle 12.2 in 12.1
      https://orablogs-jp.blogspot.jp/2016/11/enabling-adaptive-features-of-oracle.html

      [Databae] New Oracle Optimizer White Paper

      原文はこちら。
      https://blogs.oracle.com/optimizer/entry/new_oracle_optimizer_white_paper

      Oracle Optimizerの新しいホワイトペーパーがご覧いただけるようになりました。以下のリンクから、Optimizer with Oracle Database 12cをクリックしてダウンロードしてください。
      Query Optimization - Learn More
      http://www.oracle.com/technetwork/database/database-technologies/query-optimization/learnmore/index.html
      コンテンツやフォーマットをMariaのやり方に合わせたので、過去のバージョンをご覧になったことがあれば取っつきやすいかと思いますが、主要な相違点は、ホワイトペーパー内のスクリプトの個数を減らし、約30ページにまでページ数を削減した点です。そうしなければ、簡単に40ページ越えしていたことでしょう。その代わりに、サンプルをGitHubに挙げておきました。
      DW-VLDB - This is a top level repository for code examples related to Data Warehousing and Very Large Databases.
      https://github.com/oracle/dw-vldb
      ホワイトペーパーの内容に対するフィードバックは、このエントリ(もちろん原文にです!)のコメント欄にお願いします。もっとサンプルがほしい、という場合にはお知らせくだされば、ToDoリストに追加する予定です。当然ながら、より詳細に説明するため、他にもエントリを(スクリプトはGitHubに)投稿するつもりです。

      最後に、OTNには、Optimizerページで参照されているその他のホワイトペーパーが多数掲載されています。執筆時点では、これらはOracle Database 12c Release 1を対象にしていますが、当然ながら更新されていきます。

      [Java] Announcing: JDK 8 MOOC: Lambdas and Streams, December 2nd!

      原文はこちら。
      https://blogs.oracle.com/thejavatutorials/entry/announcing_jdk_8_mooc_lambdas

      Oracle Massive Open Online Courseに新たにコース「JDK 8 Lambdas and Streams」の追加を発表できうれしく思っています。12月2日からスタートです。
      JDK 8 Massive Open and Online Course: Lambdas and Streams Introduction, 2016
      https://apexapps.oracle.com/pls/apex/f?p=44785:145:10040796816707::NO:RP,145:P145_EVENT_ID,P145_PREV_PAGE:5067,2
      もし筆者と同じなのであれば、経験豊かなJavaプログラマーで、Javaをオブジェクト指向言語として理解していると思いますが、ラムダ式を見たことがあっても、すらすら書くのはまだちょっと、という感じではないでしょうか。

      そんな方は、たくさんの人たちと一緒に、ラムダ式とStreams APIを使ったJavaの関数型プログラミングを最新かつ無料のMassive Open Online Course(MOOC)で勉強していきましょう。コースは12月2日から開始し、たった3週間です。ですが、以下を含めてたくさんのことを学ぶことになるでしょう。
      • 日常の問題にラムダ式を適用する
      • 匿名クラスをラムダ式に書き換える
      • 並べ替え、最大・最小の識別、ならびに重複排除問題にStreams APIを適用する
      • ラムダ式を適用すべき場合(すべきでない場合)を判断する
      • Collectorsを使う
      • ParallelStreamsを使ってパフォーマンスを向上させる
      • ラムダ式のデバッグ
      是非参加のボタンをクリックし、コースの詳細を読んで、以下の動画をご覧ください(原文にはボタンがあります。この訳文では上記リンクをクリックして参加登録してください)。12月2日にお会いしましょう!

      [WLS, Database] AGL Datasource Support for URL with @alias or @LDAP

      原文はこちら。
      https://blogs.oracle.com/WebLogicServer/entry/agl_datasource_support_for_url

      Oracle JDBCドライバでは、接続URLに @alias を持つことができ、ホスト名やポート番号、サービス名といった情報を多数のデータソース間で共有する外部のtnsnames.oraファイルに配置することができます。筆者の知見では、(コンピュータ毎に1箇所で)接続情報をより簡単に管理するため、この機能は近年人気が出てきています。情報をさらに一箇所で集中管理するため、URLで @LDAP を使い、接続情報をLDAPサーバから取得することができます。詳細はデータベースのJDBC開発者ガイドをご覧ください。
      Oracle® Database JDBC Developer's Guide 12c Release 1 (12.1)
      Data Sources and URLs
      https://docs.oracle.com/database/121/JJDBC/urls.htm#JJDBC28267
      Oracle® Database JDBC開発者ガイド 12cリリース1 (12.1)
      データソースおよびURL
      http://docs.oracle.com/cd/E57425_01/121/JJDBC/urls.htm#JJDBC28267
      このURLフォーマットは汎用データソースならびにマルチ・データソースでサポートしていますが、Active GridLink  (AGL) データソースではサポートしていませんでした。その理由は、AGLデータソースURLは長形式フォーマットのURLの中で (SERVICE_NAME=value) を持つ必要があったためです。
      WebLogic Server 12.2.1.2.0 (PS2) より、URLは @alias@ldap 形式も利用できるようになりましたが、 @alias@ldap を含まない短形式フォーマットはまだサポートされておらず、エラーが発生し動作しませんので、エイリアスやLDAPエントリに格納されたデータベース・サービス名を利用することを強く推奨します(SIDは使わないでください)。AGLのパフォーマンスを最適化するには、エイリアスやLDAPストアで負荷分散やリトライ回数、遅延などの機能を持つ長形式フォーマットのURLを使う必要があります。

      ALIAS の例

      1. 以下の構成を持つtnsnames.oraファイルを作成します。
        tns_entry=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=RAC-scan-address)(PORT=port))(CONNECT_DATA=(SERVICE_NAME=service)))
        通常、$ORACLE_HOME/network/adminに作成されます。
      2. 以下ののようなURLを使ってWebLogic Serverのデータソース・ディスクリプタを作成します。
        jdbc:oracle:thin:@tns_entry
      3. 以下のシステムプロパティをWebLogic Serverコマンドラインに追加します。
        -Doracle.net.tns_admin=$ORACLE_HOME/network/admin

      LDAP の例

      1. LDAP/LDAPSのWebLogic Serverデータソース・ディスクリプタを以下のURLのように作成します。
        jdbc:oracle:thin:@ldap://ldap.example.com:7777/sales,cn=OracleContext,dc=com

      JDBC Driverの要件

      ちょっと落とし穴があります。この機能をサポートするより賢いucp.jarファイルを使う必要があります。そのための方法は2つあります。
      • 12.1.0.2のucp.jarに対するWebLogic Serverのパッチを入手する
        (Bug #2319035  - UCP DOESN'T SUPPORT ALIAS URL FOR RAC CLUSTER)
      • Oracle Database 12cR2のucp.jarファイルを待つ。GAになったタイミングでエントリを投稿する予定です。

      [Database] SPFILE Parameter: max_pdbs - a must for Single Tenant

      原文はこちら。
      https://blogs.oracle.com/UPGRADE/entry/spfile_parameter_max_pdbs_a

      時として、私の仕事は一日の最後に笑顔にする側面があります。
      オスロからキールへ向かう船上でのOUGN Conferenceの講演の中で、Johannes Ahrendsと同席しました。
      CarajanDB - Blog Johannes Ahrends
      http://www.carajandb.com/en/blogs/blog-jahrends-en
      その後、シングルテナントを指向するお客様に不可欠なPDBの個数を制限する公式の方法がなぜ存在しないのかを議論していました。ハンズオン環境を立ち上げ、休憩の間ちょっと試してみましたが、DROP PLUGGABLE DATABASEを実行しない限り、unplug/plugオペレーションでCONTAINER$中に残ってしまうため、CONTAINER$の制限は正しいソリューションではないことがわかりました。たとえ残りを削除したとしても、COTAINER$への制約をつける方法は上手くいきません。
      翌朝の朝食でヨハネスはトリガーについて言及し、すぐにトリガーを発行しました。しかしながら、データ・ディクショナリを使いこなす場合にデータベースのサポートを維持することはよい考えではありません。
      そのため、私は社内に問合せ、はっきりと「これを望んでいない人がいる」というメッセージを受け取りました。
      オラクルで長く働いているので、この意味がわかります、物事をさらに議論したくないときは、「誰か」を責めるのが一般的です。 「誰か」の背後に完全に隠れることができますからね。
      Oracle Database 12.2のテストおよび試用を開始し、リリースラベル間のinit.oraパラメータを収集し、変更点や追加箇所を検出していたときに大きな驚きがありました。そして明らかに、その驚きがここに現れたのです。
      MAX_PDBS
      http://docs.oracle.com/database/122/REFRN/MAX_PDBS.htm#REFRN-GUID-55526BAC-DCB2-4C76-9ACF-1E3D2047E267
      つまり、パラメータの説明によると、CDBやApplication ROOTで許容するPDBの最大個数という意味です。
      私は驚き、うれしくなり、そして自分の環境ですぐに試さなくては、と思いました。既に自身の環境には3個のPDB(PDB$SEEDは含めていません)がありました。
      SQL> alter system set max_pdbs=3;
      System altered.
      
      SQL> show pdbs
      
      CON_ID CON_NAME               OPEN MODE  RESTRICTED
      ------ ---------------------- ---------- ----------
      2      PDB$SEED               READ ONLY  NO
      3      PDB1                   READ WRITE NO
      4      PDB2                   READ WRITE NO
      5      CLONE_PDB              MOUNTED
      
      SQL> alter system set max_pdbs=2;
      alter system set max_pdbs=2
      *
      ERROR at line 1:
      ORA-32017: failure in updating SPFILE
      ORA-65331: DDL on a data link table is outside an application action.
      
      そんなわけで、(少なくとも私の環境では)エラーメッセージが少々粗いですが、このパラメータは求めていたことを実現してくれています。シングルテナント環境では、この値を1に設定し、このコンテナデータベースに対し、2個目のPDBの作成やプラグインをさせないようにしましょう。
      まっさらのコンテナデータベースを使い別のテストを実施しました。
      SQL> show pdbs
      
      CON_ID CON_NAME      OPEN MODE  RESTRICTED
      ------ ------------- ---------- ----------
      2      PDB$SEED      READ ONLY  NO
      
      SQL> alter system set max_pdbs=1;
      System altered.
      
      SQL> show parameter max_pdbs
      
      NAME                     TYPE     VALUE
      ------------------------ -------- ----- 
      max_pdbs                 integer      1
      
      SQL>  create pluggable database pdb1 admin user adm identified by adm  file_name_convert=('/u02/oradata/CDB2/pdbseed','/u02/oradata/CDB2/pdb1');
      Pluggable database created.
      
      SQL>  create pluggable database pdb2 admin user adm identified by adm  file_name_convert=('/u02/oradata/CDB2/pdbseed','/u02/oradata/CDB2/pdb2');
      
      create  pluggable database pdb2 admin user adm identified by adm  file_name_convert=('/u02/oradata/CDB2/pdbseed','/u02/oradata/CDB2/pdb2')
      *
      ERROR at line 1:
      ORA-65010: maximum number of pluggable databases created
      
      
      SQL> drop pluggable database pdb1 including datafiles;
      Pluggable database dropped.
      
      SQL>  create pluggable database pdb2 admin user adm identified by adm  file_name_convert=('/u02/oradata/CDB2/pdbseed','/u02/oradata/CDB2/pdb2');
      Pluggable database created.
      確かなソリューションのように見えます。

      しかしながら、Oracle ACE DirectorFranck Pachotのエントリもご覧ください。このパラメータによって発生する問題について記載しています。
      Oracle 12cR2: MAX_PDBS
      http://blog.dbi-services.com/oracle-12cr2-max_pdbs/

      [Cloud] Oracle Container Cloud Service - Managing Containers Easily on Oracle Public Cloud

      原文はこちら。
      https://community.oracle.com/community/cloud_computing/infrastructure-as-a-service-iaas/oracle-container-cloud-service/blog/2016/11/14/oracle-container-cloud-service-managing-containers-easily-on-oracle-public-cloud

      本日Oracle Container Cloud Service (Container CS) の一般提供を発表できることに非常にわくわくしております。Oracleが買収し、Container CSというクラウドサービスに変化させたStacnEngineコンテナ管理ソフトウェアを使った非常にわくわくする旅路でした。

      (筆者は)元々のStackEngineチームに属していましたので、個人的にもコアの設計原則である”easy-to-use”が、競合他社製品と比べてContainer CSの大きな差別化要素として使われていることに興奮しています。
      この使い勝手のよさが、Container CSのいくつかの主要な差別化機能になっています。

      (1) Container CSは、Dockerコンテナアプリケーションを実行するワーカーノードにパワーを供給するために必要なIaaS Computeをどのようなキャパシティでも簡単にプロビジョニングすることができます。プロビジョニング後、すぐにプラットフォームを使うことができます。実施することは、ご自身のコンテナを持ち込み。気軽に実行する、これだけです。さらに、複数のContainer CSインスタンスを必要に応じて自由に使いたいとお客様は思ってらっしゃることでしょう。開発チームやDevOpsチーム用のインスタンスを展開し、個々人のためにその他のインスタンスを展開してください。これにより、お客様がDockerワークロードをラップトップから開放しコンテナ環境に簡単に移すことができます。

      (2) Container CSには1クリックで展開できる、たくさんのサンプル・コンテナ・アプリケーションがあります。このサンプルには、シンプルかつたった1個のイメージと、すぐに実行できるテンプレート中のランタイム情報とで構成されている、Service(サービス)と呼ばれるものと、オーケストレーションが定義された、複数のホストにわたって展開可能な複数イメージのアプリケーションである、Stack(スタック)と呼ばれるものがあります。これらのServiceとStackの長所は、お客様がこうしたサンプルやこれらのサンプルのビルド方法を活用し、自身のアプリケーションをモデリングする上で役立てることができる、という点です。

      (3) Container CSのUIは、TCPチェックを含む多くのネイティブ機能と理解しやすい色分けされたヘルスチェックを使っています。そのため、UIからステータスの前後関係と実行中のコンテナの状態を理解することができます。しかし、最大の前後関係はデプロイメントの機能を通じて与えられるものと考えます。デプロイメントは、コンテナ化されたアプリケーションを実行した際に作成されます。デプロイメントによって、デプロイメント全体の健康状態とともに、コンテナが何を実行しているのかという意味で個々のコンテナを確認することができます。

      標準の"docker ps"コマンドでターミナルに表示される情報と比較してみてください。下の画面ショットで、速く確認できる情報には限りがあります。おおよそ、コンテナのリスト、ネイティブDocker名とアップタイムぐらいです。ターミナル・ウインドウを使うオブザーバーで、コンテナが実際にしていることがわかるのでしょうか。
      下図で、アプリケーションや、実行中のアプリケーションは何かわかるでしょうか。
      では、これを次の2画面と対比してみてください。この画面では記述名を持つ、Container CSで動作している全てのデプロイメントを確認できます。
      デプロイメントビューのからみでコンテナを見ることができます。最初の画面では、実行中の全てのデプロイメントとその健康状態を表示しています。


      下図では、デプロイメントの一つに関する詳細をご覧いただけます。このケースでは、この環境の全てのホストに渡ってデプロイされているELKロギングアプリケーションが良好な状態であることがわかります。
      ContainerCS-Deployment-Detail.jpg

      Oracle Public CloudのContainer CSチーム(と筆者)にとって、今日は我々のコンテナ管理テクノロジーをご利用いただくためにお披露目でき、非常にうれしい日です。

      無料トライアルは、以下のURLの[無料トライアル]のリンクをクリックし、[Oracle Cloud PaaSおよびIaaS]をクリックすると登録できます。詳細情報も以下のURLからどうぞ。
      Oracle Container Cloud Service
      https://cloud.oracle.com/ja_JP/container

      [Java] Visual VM in JDK 9 and Beyond

      原文はこちら。
      https://blogs.oracle.com/java-platform-group/entry/visual_vm_in_jdk_9

      Visual VMはJava Virtual Machine上で動作しているコードに関する情報を提供するツールで、Oracle JDK 6、7、8で提供されています。
      Visual VMの詳細情報はNetBeans Profiler and Visual VM blogをご覧ください。
      NetBeans Profiler
      https://blogs.oracle.com/nbprofiler/
      JDK 9から、Visual VMはOracle JDKに同梱されません。Visual VMをOracle JDK 9以後で使いたい場合には、Visual VMオープンソースプロジェクトサイトからダウンロードすることができます。
      VisualVM - All-in-One Java Troubleshooting Tool
      https://visualvm.github.io/

      [Linux] Oracle Linux 7.3 Available Now

      原文はこちら。
      https://blogs.oracle.com/linux/entry/oracle_linux_7_update_3

      Oracle LinuxチームとVirtualizationチームはx86-64向けOracle Linux 7 Update 3の一般提供を発表できることをうれしく思っています。

      サブスクリプションを持つユーザーの方は、ISOをMy Oracle Supportからダウンロードできます。ISOイメージはOracle Software Delivery Cloudからもダウンロードできます。
      My Oracle Support
      https://support.oracle.com/
      Oracle Software Delivery Cloud
      http://edelivery.oracle.com/linux/
      個々のRPMパッケージはPublic YumサーバおよびUnbreakable Linux Network (ULN)から入手できます。
      Oracle Linux Yum Server
      http://yum.oracle.com/
      Unbreakable Linux Network
      https://linux.oracle.com/
      このリリースでは、UEK Release 4 (UEK R4)がOracle Linux 7 ISOイメージに初めて同梱されています。新しいOracle Linux 7 Update 3をインストールすると、デフォルトでUEK R4で起動しますが、既存のOracle Linux環境をアップデートするには明示的にUEK R4をインストールする必要がありますのでご注意ください(既存のUEK R3カーネルを自動的に置き換えることはしません)。

      Kernel Support with Oracle Linux 7 Update 3

      Oracle Linux 7 Update 3 ISOイメージには、Unbreakable Enterprise Kernel (UEK) とRed Hat Compatible Kernel (RHCK)の2種類のカーネルパッケージが同梱されており、インストールされます。インストールプロセスで、UEKをデフォルトカーネル、RHCKを代替カーネルとしてとして起動するよう構成します。

      Oracle Linux 7 Update 3 ISOイメージには以下のカーネルパッケージが含まれています。
      • kernel-uek-4.1.12-61.1.18.el7uek (UEK R4u2 +errata)
      • kernel-3.10.0-514.el7
      Oracle Linux 7 Update 3は引き続きサポートしますが、最新のUEK R3u7以後を同梱することはありません。

      Application Compatibility

      Oracle LinuxはRed Hat Enterprise Linuxとユーザー空間の互換性を維持していますが、OSの基礎になるカーネルバージョンには依存しません。ユーザー空間の既存のアプリケーションは引き続きOracle Linux Update 3とUEK R4との組み合わせで変更せずに実行できますし、既にRHEL 7やOracle Linux 7で動作保証されているアプリケーションに対し、再度動作検証・保証する必要はありません。

      Notable in Oracle Linux 7 Update 3:

      UEFI Secure Boot Support

      このアップデートで、UEFIセキュアブートが有効化されているシステム上にOracle Linux 7をインストール、利用することができます。Oracle Linux 7 Update 3ではUEFIセキュアブートを完全にサポートしています。

      Oracle Linux 7 Update 3のその他の新機能や変更は、製品ドキュメントのリリースノートをご覧ください。
      Oracle Linux 7 Document Library
      https://docs.oracle.com/cd/E52668_01/index.html
      Oracle Linuxはダウンロード、利用、配布は無償です。アップデートやエラータも無料でご利用いただけます。サポートについては、どのシステムでサポート契約が必要かを決めてください。
      Oracle Linux OS and Support
      http://www.oracle.com/linux
      Free Updates and Errata for Oracle Linux
      https://blogs.oracle.com/linux/free-updates-and-errata-for-oracle-linux
      Oracle Linux Supoprt
      http://www.oracle.com/us/technologies/linux/support/overview/index.html
      これがOracle Linuxを開発、テスト、本番システムのための理想的な選択肢たらしめています。全システムを最新かつセキュアに保ちながら、個々のシステムでどのサポート範囲がベストなのかを決めてください。Oracle Linux Premier Supportを持つお客様は、Oracle Kspliceを使ったゼロダウンタイムカーネルアップデートやOracle OpenStack for Oracle Linuxのサポートも受けることができます。
      Oracle Ksplice
      http://www.oracle.com/us/technologies/linux/ksplice-datasheet-487388.pdf
      Oracle OpenStack for Oracle Linux
      http://www.oracle.com/technetwork/server-storage/openstack/linux/documentation/datasheet-oracle-openstack-2296038.pdf

      [Database] Upgrades to Oracle Database 12.2.0.1 (and Downgrades)

      原文はこちら。
      https://blogs.oracle.com/UPGRADE/entry/upgrades_and_downgrades_to_oracle

      Oracle Database 12c Release 2 (12.2) がNASおよびEMEAゾーンのDatabase Cloud Service、Exadata Cloud Serivice、Exadata Express Cloud Serviceでご利用いただけるようになりました。Oracle Database 12.2のドキュメントも公開されています。
      (訳注)
      Oracle Database Cloud Service - What's New in Oracle Database
      http://docs.oracle.com/cloud/latest/dbcs_dbaas/whatsnewindb.htm
      All Books for Oracle® Database Online Documentation Library 12c Release 2 (12.2)
      http://docs.oracle.com/database/122/nav/portal_booklist.htm

      DBUAやコマンドライン上で catctl.pl を使い直接アップグレードをサポートするバージョンは以下の通りです。
      • Oracle Database 11.2.0.3
      • Oracle Database 11.2.0.4
      • Oracle Database 12.1.0.1
      • Oracle Database 12.1.0.2
      Direct Upgrade to Oracle Database 12.2
      Oracle Database 11.2.0.3より前のバージョンは直接アップグレードのサポート対象外です。11.2.0.3より前のバージョンをお使いの場合、Data PumpのようなツールやTransportable Tablespaces(トランスポータブル表領域)などといったテクニックを使うと、アップグレードにあたって2段階、3段階の移行作業をしなくてすむようになります。もちろん、Oracle Cloudへの移行時にも同様のことが言えます。

      ダウングレードについては、CDB以外について、アップグレードする前のバージョンにダウングレードすることができます。

      [Java] Hung JVM due to the threads stuck in pthread_cond_timedwait()

      原文はこちら。
      https://blogs.oracle.com/poonam/entry/hung_jvm_due_to_the

      このエントリでは、Javaプロセスのハングが実際にはJava/JVMが原因ではなく、OSの問題が原因で起こるという複数のシナリオについて説明していきます。今回説明するどちらのハングもLinux OSで発生します。
      それでは、最初のケースを見ていきましょう。この例では、スレッドがJavaの Thread.sleep() を呼び出すところでスタックしているようです。プロセスのスタックトレースから、2個のスレッドに関心を当ててみましょう。
      Thread 26755: (state = IN_VM)
       - java.lang.Thread.interrupt0() @bci=0 (Interpreted frame)
       - java.lang.Thread.interrupt() @bci=51, line=852 (Interpreted frame)
       - oracle.core.ojdl.BufferedLogWriter.stopFlusher() @bci=17, line=380
      (Interpreted frame)
      
      Thread 21714: (state = BLOCKED)
       - java.lang.Thread.sleep(long) @bci=0 (Interpreted frame)
       - oracle.core.ojdl.BufferedLogWriter$Flusher.run() @bci=30, line=401
      (Interpreted frame)
      
      スレッド #26755 は、Thread.sleep() を実行しているスレッド #21714 に割り込みしようとしています。スレッド#21714はプロセス内の他スレッドが進行できないようにするBLOCKED状態に留まっているため、その結果プロセスがハングしています。
      では、ネイティブ・スタックトレースを見てみましょう。
      Thread 26755:
      #0  0xf77e7430 in __kernel_vsyscall ()
      #1  0x4dcc31b9 in __lll_lock_wait () from /lib/libpthread.so.0
      #2  0x4dcbe550 in _L_lock_677 () from /lib/libpthread.so.0
      #3  0x4dcbe421 in pthread_mutex_lock () from /lib/libpthread.so.0
      #4  0x064ff034 in os::Linux::Event::unpark() ()
      #5  0x064fc60a in os::interrupt(Thread*) ()
      
      Thread 21714:
      #0  0xf77e7430 in __kernel_vsyscall ()
      #1  0x4dc0fc43 in __lll_lock_wait_private () from /lib/libc.so.6
      #2  0x4db94348 in _L_lock_9835 () from /lib/libc.so.6
      #3  0x4db91f27 in calloc () from /lib/libc.so.6
      #4  0x4dcc0e1c in pthread_cond_timedwait@GLIBC_2.0 () from /lib/libpthread.so.0
      #5  0x064fefa1 in os::Linux::Event::timedwait(timespec*) ()
      #6  0x064fc2bf in os::sleep(Thread*, long long, bool) ()
      #7  0x063d5d90 in JVM_Sleep ()
      
      pthread_cond_timedwait() 関数に期間としてどのような値を渡したのか疑問に思われるかもしれません。このときの値は5秒でしたので、5秒後 pthread_cond_timedwait() は待機状態から復帰しているはずです。
      pthread_cond_timedwait()は、他スレッドとの調整に利用するpthread_cond_t* condpthread_mutex_t* mutexという引数を受け入れます。
      pthread_cond_timedwait(3) - Linux man page
      https://linux.die.net/man/3/pthread_cond_timedwait
      ではcondmutexの両引数を見てみましょう。
      (gdb) print *((pthread_cond_t*)0xad533ff0)
      $3 = {__c_lock = {__status = 0, __spinlock = 17}, __c_waiting = 0xad534050}
      
      (gdb) print *((pthread_mutex_t*)0xad533fd8)
      $4 = {__m_reserved = 2, __m_count = 0, __m_owner = 0x54d2, __m_kind = 0, __m_lock = {__status = 1, __spinlock = 0}} 
      __m_owner = 0x54d2 = 21714
      
       (gdb) print *$11->_osthread->_interrupt_event
      $14 = {<CHeapObj> = {<No data fields>}, _count = 0, _nParked = 1,
      cachePad = {-2.3622328335110874e-90, 4.2439915835115547e-313,
          1.4480588116526359e-314, 4.2439915866735748e-313}, _mutex =
      {{__m_reserved = 2, __m_count = 0, __m_owner = 0x54d2, __m_kind = 0,
      __m_lock = {
              __status = 1, __spinlock = 0}}}, _cond = {{__c_lock = {__status
      = 0, __spinlock = 17}, __c_waiting = 0xad534050}}, FreeNext = 0xbad, Immortal = 1}
      
      上のデータから、スリープ状態にあるスレッドが_mutexを所有していること、割り込もうとしているスレッドが_mutexを取得してスリープ状態にあるスレッドにシグナルを送信しようと待機していることがわかります。よく見ると、スリープ状態のスレッドは、_mutexのリリースする前に(callocで)メモリアロケーションを完了するためにネイティブ・ヒープのロックを待っています。

      そのため、スレッドがpthread_cond_timedwait()で無限にスタックするのは、JVMが問題なのではなく、Linuxのカーネルレベルのロック同期に伴う問題であることがわかりました。

      では、別のケースを見ていきましょう。このケースでは、3個のスレッドが__pthread_cond_timedwait()でスタックしており、プロセス中の他のスレッドの進行を抑止しています。
      ----------------- 11374 -----------------
      0x00000032f1c0ba0e      __pthread_cond_timedwait + 0x13e
      0x00007fb1453bbf94      _ZN13ObjectMonitor4waitElbP6Thread + 0x224
      0x00007fb1454a0d83      _ZN18ObjectSynchronizer4waitE6HandlelP6Thread + 0x53
      0x00007fb14520b34b      JVM_MonitorWait + 0x1fb
      0x00007fb13d010eee      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
      0x00007fb13d005a82      * java.lang.Thread.join(long) bci:70 line:1214 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.execution.GetCfgRunDTE.execute() bci:864 line:504 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.execution.RunOneJob.execute() bci:1675 line:1521 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.execution.RunOneJob.main(java.lang.String[]) bci:18 line:58 (Interpreted frame)
      0x00007fb13d000438      <StubRoutines>
      0x00007fb14519e8d0      _ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1e0
      0x00007fb1453ca829       _ZN2os20os_exception_wrapperEPFvP9JavaValueP12methodHandleP17JavaCallArgumentsP6ThreadES1_S3_S5_S7_  + 0x19
      0x00007fb14519e6e5      _ZN9JavaCalls4callEP9JavaValue12methodHandleP17JavaCallArgumentsP6Thread + 0x25
      0x00007fb1451d99f7       _Z17jni_invoke_staticP7JNIEnv_P9JavaValueP8_jobject11JNICallTypeP10_jmethodIDP18JNI_ArgumentPusherP6Thread  + 0x147
      0x00007fb1451c753f      jni_CallStaticVoidMethod + 0x20f
      0x0000000040002284      JavaMain + 0x2a4
      
      ----------------- 31490 -----------------
      0x00000032f1c0ba0e      __pthread_cond_timedwait + 0x13e
      0x00007fb1453bbf94      _ZN13ObjectMonitor4waitElbP6Thread + 0x224
      0x00007fb1454a0d83      _ZN18ObjectSynchronizer4waitE6HandlelP6Thread + 0x53
      0x00007fb14520b34b      JVM_MonitorWait + 0x1fb
      0x00007fb13d010eee      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
      0x00007fb13d005a82      * java.lang.Thread.join(long) bci:70 line:1214 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.engine.LocalTaskProcess.execute() bci:70 line:206 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.engine.TaskProcess.executeLocal(boolean) bci:277 line:751 (Interpreted frame)
      0x00007fb13d005a82      * iasauto.engine.TaskProcess.run() bci:631 line:289 (Interpreted frame)
      0x00007fb13d005f5c      * java.lang.Thread.run() bci:11 line:682 (Interpreted frame)
      0x00007fb13d000438      <StubRoutines>
      0x00007fb14519e8d0      _ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1e0
      0x00007fb1453ca829       _ZN2os20os_exception_wrapperEPFvP9JavaValueP12methodHandleP17JavaCallArgumentsP6ThreadES1_S3_S5_S7_  + 0x19
      0x00007fb14519e246       _ZN9JavaCalls12call_virtualEP9JavaValue11KlassHandle12symbolHandleS3_P17JavaCallArgumentsP6Thread  + 0x116
      0x00007fb14519e2c7      _ZN9JavaCalls12call_virtualEP9JavaValue6Handle11KlassHandle12symbolHandleS4_P6Thread + 0x47
      0x00007fb145230c12      _Z12thread_entryP10JavaThreadP6Thread + 0xa2
      0x00007fb1454d3401      _ZN10JavaThread3runEv + 0x121
      
      ----------------- 11681 -----------------
      0x00000032f1c0ba0e      __pthread_cond_timedwait + 0x13e
      0x00007fb1453bbf94      _ZN13ObjectMonitor4waitElbP6Thread + 0x224
      0x00007fb1454a0d83      _ZN18ObjectSynchronizer4waitE6HandlelP6Thread + 0x53
      0x00007fb14520b34b      JVM_MonitorWait + 0x1fb
      0x00007fb13d010eee      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
      0x00007fb13d005a82      * java.util.TimerThread.mainLoop() bci:201 line:509 (Interpreted frame)
      0x00007fb13d005a82      * java.util.TimerThread.run() bci:1 line:462 (Interpreted frame)
      0x00007fb13d000438      <StubRoutines>
      0x00007fb14519e8d0      _ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread + 0x1e0
      0x00007fb1453ca829       _ZN2os20os_exception_wrapperEPFvP9JavaValueP12methodHandleP17JavaCallArgumentsP6ThreadES1_S3_S5_S7_  + 0x19
      0x00007fb14519e246       _ZN9JavaCalls12call_virtualEP9JavaValue11KlassHandle12symbolHandleS3_P17JavaCallArgumentsP6Thread  + 0x116
      0x00007fb14519e2c7      _ZN9JavaCalls12call_virtualEP9JavaValue6Handle11KlassHandle12symbolHandleS4_P6Thread + 0x47
      0x00007fb145230c12      _Z12thread_entryP10JavaThreadP6Thread + 0xa2
      0x00007fb1454d3401      _ZN10JavaThread3runEv + 0x121
      0x00007fb1453cbcdf      _Z10java_startP6Thread + 0x13f
      
      これまでの調査から、これは以下のコミットで関連する修正が完了したLinuxカーネルの問題であると信じています。
      futex: Ensure get_futex_key_refs() always implies a barrier
      https://github.com/torvalds/linux/commit/76835b0ebf8a7fe85beb03c75121419a7dec52f0
      まとめると、見かけ上JavaプロセスがハングしているのはJava/JVMの問題っぽく見えたとしても、本当の理由はそうではないことがあります。私たちはスレッドのネイティブスタックトレースをよく見て、何が原因でスレッドが停止しているのか、どこでスタックしているのか、を理解する必要があります。

      [Java] Crashes in ZIP_GetEntry

      原文はこちら。
      https://blogs.oracle.com/poonam/entry/crashes_in_zip_getentry

      先日、以下のようなスタックトレース付きで、アプリケーションクラッシュに関する数多くの報告が、様々なお客様や製品グループから寄せられました。
      Stack: [0xb0c00000,0xb0c80000],  sp=0xb0c7c890,  free space=498k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      C  [libc_psr.so.1+0x700]  memcpy+0x2f8
      C  [libzip.so+0xd19c]
      C  [libzip.so+0x2380]  ZIP_GetEntry+0xe4
      C  [libzip.so+0x2800]  Java_java_util_zip_ZipFile_getEntry+0xc4
      j  java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J+0
      j  java.util.zip.ZipFile.getEntry(JLjava/lang/String;Z)J+0
      j  java.util.zip.ZipFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;+31
      j  java.util.jar.JarFile.getEntry(Ljava/lang/String;)Ljava/util/zip/ZipEntry;+2
      j  java.util.jar.JarFile.getJarEntry(Ljava/lang/String;)Ljava/util/jar/JarEntry;+2
      
      ほとんどの場合、JVMインスタンス実行中にアクセスしているjarファイルを変更、上書きした際にZIP_GetEntryにてクラッシュが発生しています。パフォーマンスの理由により、HotSpot JVMのメモリはmmapを使い各Jarファイルのセントラルディレクトリ構造にマップします。こうすることで、Jarファイルからエントリを読み取る必要がある都度セントラルディレクトリ構造データをディスクから読み取ることを避けています。Jarファイルをディスク上で変更、上書きする場合、以前に読み取ったJVMのデータのコピーがディスク上のJarファイルと一致しなくなり、変更されたJarファイルからエントリを読み取り、ロードしようとするとアプリケーションクラッシュが発生することがあります。

      Java 1.6.0_23以後では、プロパティを使ってJarファイルのセントラルディレクトリ構造メモリマッピングのマッピングを抑止することができます。
      -Dsun.zip.disableMemoryMapping=true
      このプロパティを有効にすると、JVMはJarファイルのエントリを読み出す都度ディスク上のJarファイルからセントラルディレクトリ構造を読み取る必要があるため、アプリケーションのパフォーマンスに影響することにご注意ください。そのため、JVMがJarファイルのイメージをロードしている間は、Jarファイルを変更したり上書きしたりしないようにすることがベストです。

      Java 9では、このZIPクラッシュを以下の機能強化で解決しました。
      JDK-8142508: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash risk
      https://bugs.openjdk.java.net/browse/JDK-8142508
      この変更に対するコード・レビューのスレッドは以下からどうぞ。
      RFR: JDK-8142508: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash risk
      http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-November/036495.html
      この機能強化はmmapを使うZIPファイルのネイティブ実装をJava実装に置き換え、上述のアプリケーションクラッシュのリスクを除去しています。