[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利用率を節約できたので、運用効率も向上しました。