[Security, Support] July 2016 Critical Patch Update Released

原文はこちら。
https://blogs.oracle.com/security/entry/july_2016_critical_patch_update

2016年7月19日(PDT)に、Oracleは2016年7月度のCritical Patch Updateをリリースしました。
Oracle Critical Patch Update Advisory - July 2016
http://www.oracle.com/technetwork/security-advisory/cpujul2016-2881720.html
このCritical Patch Updateでは、(Oracle Database Server、Oracle E-Business Suite、Oracle Industry Applications、Oracle Fusion Middleware、Oracle Sun Products、Oracle Java SE、Oracle MySQLなどの)幅広い製品群に対する修正を提供します。
OracleはこのCritical Patch Updateをできる限り早期に適用されることを推奨いたします。このCritical Patch Updateのサマリーや分析情報はMy Oracle Supportの以下のサポート文書として公開しています(ご覧いただくためにはサポート契約が必要です)。
July 2016 Critical Patch Update: Executive Summary and Analysis (Doc ID 2161607.1)
https://support.oracle.com/rs?type=doc&id=2161607.1

[Java] JDK 8u101, 8u102, 7u111, and 6u121 Released!

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

JDK 8u101、8u102、7u111、6u121がご利用できるようになりました(7u111、6u121はサポート契約されているお客様のみ)。最新のJDKはJava SE Downloadページからダウンロードできます。
Java SE Downloads
http://www.oracle.com/technetwork/java/javase/downloads/index.html
このリリースでの機能強化、変更、修正点は、それぞれのリリースに対応するリリースノートをご覧下さい。
JDK 8u101 Release Notes
http://www.oracle.com/technetwork/java/javase/8u101-relnotes-3021761.html
JDK 8u102 Release Notes
http://www.oracle.com/technetwork/java/javase/8u102-relnotes-3021767.html
JDK 7u111 Release Notes
http://www.oracle.com/technetwork/java/javaseproducts/documentation/javase7supportreleasenotes-1601161.html#R170_111
JDK 6u121 Release Notes
http://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121
JDK 8u101には、ARM用JDK 8u101も含んでいます。この製品に関する情報は、Java™ Development Kit for ARM Release Notes 8 Update 101のページに記載があります。
Java™ Development Kit for ARM Release Notes 8 Update 101
http://www.oracle.com/technetwork/java/javase/8u101-arm-relnotes-3021773.html 
(訳注)
Critical Patch Updateの一環としてリリースされているため、JREのセキュリティベースラインが変更されています。ご利用のお客様はアップデートされることを推奨します。
  • [8] 1.8.0_101-b13
  • [7] 1.7.0_111-b13
  • [6] 1.6.0_121-b09
このリリースに含まれるセキュリティ修正は以下のページから確認できます。
Oracle Critical Patch Update Advisory - July 2016
Oracle Java SE Executive Summary
http://www.oracle.com/technetwork/security-advisory/cpujul2016-2881720.html#AppendixJAVA

[WLS] WebLogic Server 12.2.1.1.0 - Domain to Partition Conversion Tool (DPCT) Updates

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

Domain to Partition Conversion Tool (DPCT) はWebLogic Server(10.3.6、12.1.2、12.1.3、もしくは12.2.1)の既存ドメインをWebLogic Server 12.2.1ドメインのパーティションに移行するためのアシスタントツールです。
このDPCTは、独立した、しかしながら関連する2個の操作から構成されています。
  1. 既存のドメインを検査し、関連する構成やバイナリファイルを取り込んでアーカイブにエクスポートする。
  2. WebLogic Server 12.2.1で利用可能なパーティションへのインポートオプションを使って、エクスポートしたドメインのアーカイブをインポートし、新規パーティションを作成する。このパーティションには移行元からの構成リソースやアプリケーション・デプロイメントが含まれる。
    WebLogic Server 12.2.1.1.0リリースに伴い、DPCTの機能改善に伴うアップデートや変更がありました。アップデートされたドキュメントには、新機能、修正された不具合、既知の制限事項がまとめられています。
    Oracle® Fusion Middleware
    Using Oracle WebLogic Server Multitenant 12c (12.2.1.1.0)
    Migrating a WebLogic Server Domain to a Domain Partition
    https://docs.oracle.com/middleware/12211/wls/WLSMT/config_dpct.htm#WLSMT1695

    Key Updates

    a) WebLogic Server 12.2.1.1.0をインストールするとDPCTも配布されるようになりました
    当初DPCTは、OTNからのみダウンロードできる別のZipファイルとして配布されていましたが、12.2.1.1.0から、DPCTは製品インストールとともに配布されるようになっています。
    $ORACLE_HOME/wlserver/common/dpct/D-PCT-12.2.1.1.0.zip
    
    12.2.1.1.0のインストール環境からこのファイルを移行元ドメインのあるサーバへコピーし、展開して利用することができます。なお、DPCTはOTNからも依然としてダウンロードできます。
    Free Oracle WebLogic Server Installers for Development
    Domain To Partition Conversion Tool
    http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html

    b) 利用にあたってパッチ適用は不要です
    以前はDPCTを利用するにあたって、DPCTが生成したアーカイブをインポートするために移行先の12.2.1インストール環境にパッチを適用する必要がありましたが、この制限はなくなりました。

    c) プラットフォームサポートの改善
    Windows環境ではDPCT利用にあたって発生していた不具合は解決済みです。

    d) レポートの改善
    新しくなったレポートファイルは、エクスポートされた各ドメインに対して生成されます。移行元ドメインの詳細だけでなく、エクスポートされたアーカイブに取り込まれた構成リソースやデプロイメントの各々の詳細も列挙しますし、エクスポートできなかったリソースも記載されます。

    e) オーバーライド時に使うJSONファイルのフォーマット変更
    生成されたJSONファイルを使うと、インポート時に指定して移行先環境のカスタマイズを可能とするためのオーバーライド機構を提供します。このファイルの形式が正しく整形され、変更がより簡単、わかりやすくなりました。

    f) JSONオーバーライドファイルへのリソースの追加
    移行先ドメインに対するカスタマイズを支援するため、JDBCシステムリソース、SAFエージェント、メールセッション、JDBCストアといった追加のリソースを、生成されたJSONファイル内に構成可能なオブジェクトとして記述できるようになりました。

    g) 新しいexport-domainスクリプトの包含
    DPCT実行時に使うスクリプトを書き換え、新しいスクリプトとして追加しました。この新しいスクリプトはexport-domain.[cmd|sh]という名前で、ヘルプテキストがよりわかりやすく、スクリプトへの入力値に名前付きパラメータを利用できるようになりました。以前のスクリプトも後方互換のために提供しているので引き続き利用できますが、可能であれば新しいスクリプトを利用されることを推奨します。
    export-domain スクリプトの利用方法
    Usage: export-domain.sh -oh {ORACLE_HOME} -domainDir {WL_DOMAIN_HOME}
           [-keyFile {KEYFILE}] [-toolJarFile {TOOL_JAR}] [-appNames {APP_NAMES}]
            [-includeAppBits {INCLUDE_APP_BITS}] [-wlh {WL_HOME}]
           where:
                 {ORACLE_HOME} : the MW_HOME of where the WebLogic is installed
                 {WL_DOMAIN_HOME} : the source WebLogic domain path
                 {KEYFILE} : an optional user-provided file containing a clear-text passphrase used to encrypt exported attributes written to the archive, default: None;
                 {TOOL_JAR} : file path to the com.oracle.weblogic.management.tools.migration.jar file.
                 Optional if jar is in the same directory location as the export-domain.sh
                 {APP_NAMES} : applicationNames is an optional list of application names to export.
                 {WL_HOME} : an optional parameter giving the path of the weblogic server for version 10.3.6.Used only when the WebLogic Server from 10.3.6 release is installed under a directory other than {ORACLE_HOME}/wlserver_10.3

    Enhanced Cluster Topology and JMS Support

    上記に加え、エクスポート/インポート操作を再構築し、DPCTが数多くのWebLogic Serverの主要な機能をサポートするようになりました。
    移行元ドメインを検査してエクスポート・アーカイブを生成する際に、DPCTはリソースやデプロイメントのターゲットとして、移行先ドメインの適切なサーバやクラスタを指定できるようになりました。移行元ドメインの各サーバやクラスタに対し、対応するリソースグループオブジェクトが生成されたJSONファイルに作成されます。各リソースグループは専用の仮想ターゲットにターゲット指定されており、順に移行先ドメインのサーバやクラスタへターゲット指定できるようになっています。
    移行元のドメインにおける特定のWebLogic Serverインスタンスやクラスタをターゲット指定しているすべてのアプリケーション・デプロイメントとリソースは、移行先ドメインのリソースグループに対応します。
    この変更の結果、適切に新しい環境にマップできるようJSONファイルでターゲットを指定することによって、移行先ドメインが移行元のクラスタやサーバのリソースと異なる名前である状況であってもサポートできるようになりました。
    以前あった、シングルサーバおよびクラスタトポロジーでのJMS構成のエクスポートに関わる数多くの制限が解決済みですので、一般的なJMSのユースケースでDPCTを使った移行がサポートされるようになりました。ドキュメントには既存の既知の制限が列挙されています。

    [Linux] Oracle Linux Kernel Developers at LinuxCon Japan

    原文はこちら。
    https://blogs.oracle.com/linuxkernel/entry/oracle_linux_kernel_developers_at

    Oracle Linuxのカーネル開発者が7月13日から15日にかけて開催されるLinuxCon Japanで講演します。
    LinuxCon Japan
    (英語)http://events.linuxfoundation.org/events/linuxcon-japan
    (日本語)http://events.linuxfoundation.jp/events/linuxcon-japan
    講演タイトルとスピーカーは以下の通りです。
    James Morrisは、他のカーネル開発者とならんで、Kernel Developer Panelにも参加予定です。

    [Java] Putting Hypermedia Back in REST with JAX-RS

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

    あなたのJavaエンタープライズ・アプリケーションで本格的なハイパーメディアドリブンのREST APIを実装すると、変更に対してより柔軟性と弾力性が増します。よい副作用として、一つ一つのRESTリソースを文書化する必要性もなくなります。

    誰もがRESTにしています。少なくとも誰もがやっていると主張しています。しかし、ハイパーメディアを使わずにビルドされている場合を除き、発見できるほとんどのWeb APIは、「RPCスタイル」と「HTTPセマンティクスを持つ基本的なリソース」の間にあります。

    Real-World "REST" Examples

    多くの実プロジェクトでは、任意のHTTP APIのことを間違ってRESTfulと呼んでいます。Listing 1の例を見てみましょう。
    POST /doSomeAction
    <someActionRequest>
        <param>12345</param>
    </someActionRequest>
    
    200 OK
    <someActionResponse>
        <value>2345</value>
    </someActionResponse>
    
    Listing 1. RPC HTTP example (request and response)
    これらのHTTP呼び出しは、実際にはHTTPを使ってメソッドを呼び出しています。doSomeActionというURLはメソッド名で、POSTが全ての呼び出しで使われています(データの読み取りにおいてもです)。そしてリクエストおよびレスポンスのボディ部分は入出力パラメータです。
    これはSOAPエンベロープがないSOAP以外の何者でもないと結論付けることができます。

    Resources and HTTP Semantics


    REST APIのURLはアプリケーションのビジネス・エンティティを表しています。つまり、APIデザイン時には動詞ではなくオブジェクトの観点で検討する必要がある、ということです。
    以下はユーザー管理モジュールのために、ユーザーオブジェクトをHTTPで公開します(Listing 2)。
    GET /users
    200 OK

    <users>
        <user>
            <id>12345</id>
            <name>Duke</name>
            <motto>Java rocks!</motto>
        </user>
        <!-- some more users ... -->
    </users>
    
    Listing 2. Resources example (request and response)
    ここでの違いは、URLがビジネスオブジェクト(全ユーザーのリスト)を反映しており、正しいHTTPメソッドを使ってリソースを読み取る、というところです。
    クライアントが全ユーザーを読み取り、各ユーザーのリソースをフォローしたいという場合、URLの構築方法を知る必要があるでしょう。特定ユーザーのURLが/users/12345である場合、クライアントは暗黙のうちに一致するオブジェクトのIDを使って全ユーザーのURLを結合する必要があります。これはクライアントがサーバにのみ存在しているべきロジックと密に結合しています。
    一般的な誤解は、RESTがいささか予測可能なURLであるということです。実際には、読み込み可能なURLがあると便利ですが、より重要なのは、サーバーはURLの制御に留まり、積極的に必要なリソースにクライアントを導く、という事実です。これはどうやって実現できるのでしょうか。
    Listing 3は、リソースとHTTPセマンティクスを使ってユーザーを作成する例です。
    POST /users

    <user>
        <name>Duke</name>
        <motto>JAX-RS rocks!</motto>
    </user>
    
    201 Created
    Location: /users/12345
    Listing 3. Creating resources (request and response)
    サーバはリクエストに対してHTTPステータス201 Createdを返し、Locationヘッダー・フィールドには新規作成されたリソースのURLが含まれています。クライアントはこのURLを利用して特定のユーザーのリソースにアクセスします。これは、もはやURLがクライアント側で作成されないことを意味します。つまりサーバが再びURLを管理下に置いています。

    Enter Hypermedia


    関連するリソースにアクセスする方法はハイパーメディアを使って指示できます。
    リスト4に示すように、再びユーザ・リストの例を考えてみましょう。ただ今回はリソースのリンクを持っています。
    GET /users
    200 OK

    <users>
        <user>
            <name>Duke</name>
            <motto>Java rocks!</motto>
            <link rel="self" href="/users/12345"/>
        </user>
        <!-- some more users ... -->
    </users>
    
    Listing 4. Resources with links example (request and response)
    レスポンスにはもはやビジネスオブジェクトのIDは含まれておらず、対応するリソースへのリンクが含まれています。クライアントはアプリケーションの構造を事前に知らなくても、これらのリンクに従うことができますが、同一性だけを認知しておく必要があります。これはクライアントに対し、リンクそれ自身が、包含するオブジェクト(つまりユーザー)のリソースであることを伝えているのです。
    その結果、関係性だけを知った上で、リンクを使ってクライアントに全ての必要なロケーションへ指示します。あとはサーバー次第です。
    Listing 5は、別の局面でのリソースリンク・アプローチの例です。今回はブックストアの例をJSON形式で表現しています。
    GET /books/12345
    200 OK

    {
        "name": "Java",
        "author": "Duke",
        // + availability, price
        "_links": {
            "self": "/books/12345",
            "add-to-cart": "/shopping_cart"
        }
    }
    
    Listing 5. Resource with several links (request and response)
    リソースには同一性を示すリンクだけでなく、「ショッピングカートに入れる」機能にアクセスできるURLも含まれています。これがハイパーメディアを使用するメリットです。そのリンクは、ユーザーがカートに本を追加することができる場合にのみ含まれます。本を購入できる場所の例として書店を考えてみましょう。いくつかの前提条件に一致する場合にのみ、本をユーザーのショッピングカートに追加することができます。このビジネスロジック(例えば、在庫がある書籍のみを追加する)は、理想的には、冗長なロジックを防止するため、サーバー上にのみ存在します。
    (本の在庫がある場合のみ、ショッピングカートボタンを見せるという)ロジックをクライアントに複製せずに、ロジックが適用される場合にのみレスポンスのボディにサーバはadd-to-cartのリンクを含めます。クライアントはadd-to-cartの関係を知っているので、ファンシーなボタンを表示し、そのボタンがクリックされれば、そのURLにアクセスします。
    しかし、APIユーザーは、どのデータをadd-to-cartのURLに送信する必要がある、ということをどうやって知るのでしょうか。このアクションは、HTTPのGET呼び出しではなく、必要なデータ(例えば書籍ID、追加する書籍の個数、など)を伴ってPOST呼び出しをします。この情報を、文書化(つまり、そのURLにアクセスする方法の説明)、もしくは、より洗練されたハイパーメディア・アプローチを介して、APIに含める必要があります。
    様々なレベルの管理・制御を可能にするいくつかのハイパーメディアを意識したコンテンツ・タイプがあります。  M. AmundsenによるH Factorに関するエントリを参照ください。
    Hypermedia Types > H factor
    http://amundsen.com/hypermedia/hfactor/
    あるハイパーメディアを意識したコンテンツ・タイプにSirenがあります。これを使うと、リンクを定義できるだけでなく、いわゆるアクションも定義できます。シンプルなGET呼び出しを使う以外の方法でリソースへアクセスする方法を示します。
    Siren: a hypermedia specification for representing entities
    https://github.com/kevinswiber/siren
    Listing 6はリンクとアクションを持つ書籍の例です。
    GET /books/12345
    200 OK

    {
        "class": [ "book" ],
        "properties": {
            "isbn": "1-1234-5678",
            "name": "Java",
            "author": "Duke",
            "availability": "IN_STOCK",
            "price": 29.99
        },
        "actions": [
            {
                "name": "add-to-cart",
                "title": "Add Book to cart",
                "method": "POST",
                "href": "http://api.jamazon.example.com/shopping_cart",
                "type": "application/json",
                "fields": [
                    { "name": "isbn", "type": "text" },
                    { "name": "quantity", "type": "number" }
                ]
            }
        ],
        "links": [
            { "rel": [ "self" ], "href": "http://api.jamazon.example.com/books/1234" }
        ]
    }
    
    Listing 6. Siren book resource example (request and response)
    クライアントはadd-to-cart機能を呼び出すためのあらゆる必要な情報、これにはURL、HTTPメソッド、Content-type、あらゆる必要なコンテントデータが含まれますが、これらをJSONプロパティの形式で受け取ります。ISBNと個数のフィールドの情報の出所だけは、知っておく必要があります。これはクライアント上に存在する必要があるビジネス・ロジックであることは明らかです。
    その結果、クライアントは、アプリケーションのドメイン・モデル以外の前提知識を持たなくても、自己探索方式でAPIを使用してナビゲートすることができます。「利用方法」の情報はAPI自身に焼き付けてあるので、多くのドキュメントをここに保存することができます。
    それに加えて、ハイパーメディアを使用した場合には、API変更に対してより高い柔軟性を持たせることができ、クライアントは対応することができます。
    一般的には、APIが大きくなり、利用するクライアントの種類が増えれば増えるほど、REST APIをハイパーメディア駆動にすることはますます理に適います。

    Enter Java EE

    JAX-RSはJava EEでRESTful Webサービスを開発するための標準です。
    Listings 7と8では、(Listing 5で示した)HTTP呼び出しを処理するJAX-RSリソースクラスとアノテーションが付いたPOJOを示しています。
    @Path("books")
    @Produces(MediaType.APPLICATION_JSON)
    public class BooksResource {
    
        @Inject
        BookStore bookStore;
    
        @Context
        UriInfo uriInfo;
    
        @GET
        public List<Book> getBooks() {
            final List<Book> books = bookStore.getBooks();
    
            books.stream().forEach(u -> {
                final URI selfUri = uriInfo.getBaseUriBuilder().path(BooksResource.class).path(BooksResource.class, "getBook").build(u.getId());
                u.getLinks().put("self", selfUri);
            });
    
            return books;
        }
    
        @GET
        @Path("{id}")
        public Book getBook(@PathParam("id") final long id) {
            final Book book = bookStore.getBook(id);
    
            final URI selfUri = uriInfo.getBaseUriBuilder().path(BooksResource.class).path(BooksResource.class, "getBook").build(book.getId());
            book.getLinks().put("self", selfUri);
    
            // check if business logic applies
            if (bookStore.isAddToCartAllowed(book)) {
                final URI addToCartUri = uriInfo.getBaseUriBuilder().path(CartResource.class).build();
                book.getLinks().put("add-to-cart", addToCartUri);
            }
            return book;
        }
    }
    
    Listing 7. JAX-RS resource class
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Book {
    
        @XmlTransient
        private long id;
        private String name;
        private String author;
    
        @XmlElement(name = "_links")
        private Map<String, URI> links = new HashMap<>();
    
        // getters & setters
    }
    
    Listing 8. Book example POJO
    getBooksリソース・ハンドラは、BookStore ManagedBeanを呼び出して、対応するURIを付加し、クライアントに返す本を取得します。注意いただきたいのは、Content-typeがapplication/jsonであっても、JAXB(Java Architecture for XML Binding)アノテーションを使って、JSON出力にJavaオブジェクトをマッピングできる、ということです。アプリケーションサーバに同梱されている主要なJSONマッピングフレームワークもまた、JAXBアノテーションを考慮します。
    JAX-RSのUriInfo機能を使って、JAX-RSクラスから直接得た情報を使ってURIをプログラムで作成します。pathメソッドは@Pathアノテーションのpathの部分を連結します。getBookメソッドには、書籍の実際のIDで置換する必要があるパス・パラメーターが含まれています。これは、対応する引数を使ってbuildmethodを呼び出すことによって行われます。
    UrlInfoコンポーネントのもう一つの有用な機能は、getBaseUriBuilderというビルダーです。これは与えられたHTTPリクエストに従って、プロトコル、ホスト、ポートを作成します。アプリケーションサーバが例えばApacheやnginxの背後にある場合、元のHTTPリクエストのリクエストプロトコル、ホストやポート、つまりはプロキシサーバのベースURLを使ってURIを作成します。これはJAX-RSの標準機能であり、設定作業とJava EEアプリケーションをITランドスケープとの密結合を最小限にとどめることができます。
    getBookリソースハンドラは、基本的には1個の書籍のためにのみ同じことをします。そしてビジネスロジックが一致した場合、このリソースハンドラはadd-to-cartリンクも含みます。これが、ハイパーメディアを使ってクライアントの挙動を制御する方法の一例です。

    Listing 9および10は、与えられた例における可能性のあるレスポンスです。
    GET /hypermedia-test/resources/books
    200 OK

    [
      {
        "name": "Java",
        "author": "Duke",
        "_links": {
          "self": "http://localhost:8080/hypermedia-test/resources/books/1"
        }
      },
      {
        "name": "Hello",
        "author": "World",
        "_links": {
          "self": "http://localhost:8080/hypermedia-test/resources/books/2"
        }
      }
    ]
    
    Listing 9. Books resource example
    GET /hypermedia-test/resources/books/1
    200 OK

    {
      "name": "Java",
      "author": "Duke",
      "_links": {
        "self": "http://localhost:8080/hypermedia-test/resources/books/1",
        "add-to-cart": "http://localhost:8080/hypermedia-test/resources/shopping_cart"
      }
    }
    
    Listing 10. Book resource example
    Sirenなどのコンテント・タイプを使ったより洗練された例は、レスポンスにより多くの情報を必要とします。Siren4Jのようなライブラリには、所望のハイパーメディア・コンテント・タイプでレスポンスを作成する機能があります。
    Java library for the Siren Hypermedia Type Specification
    https://github.com/eserating/siren4j/
    しかしながら、外部ライブラリを使って依存性を増やさず、できる限り生成されるデプロイメントアーティファクトのサイズを小さくするため、ふつうのJava EE 7の機能を使う方法をご紹介しましょう。これはつまり、コンテント・タイプに応じてフィールドを含む独自のJavaクラスを作成する、もしくはプログラム的なアプローチを使う、ということを意味します。JSON-Pは、最大限JSONの構造をプログラムで作成できる機能を提供します。
    JSR 353: JavaTM API for JSON Processing
    https://jcp.org/en/jsr/detail?id=353
    Listing 11は、bookリソースのレスポンスをJSON-Pを使い、プログラムで作成する例です。
    @GET
    public JsonArray getBooks() {
        return bookStore.getBooks().stream().map(b -> {
            final URI selfUri = uriInfo.getBaseUriBuilder().path(BooksResource.class).path(BooksResource.class, "getBook").build(b.getId());
            final JsonObject linksJson = Json.createObjectBuilder().add("self", selfUri.toString()).build();
            return Json.createObjectBuilder()
                    .add("name", b.getName())
                    .add("author", b.getAuthor())
                    .add("_links", linksJson).build();
        }).collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add).build();
    }
    
    @GET
    @Path("{id}")
    public JsonObject getBook(@PathParam("id") final long id) {
        final Book book = bookStore.getBook(id);
    
        final URI selfUri = uriInfo.getBaseUriBuilder().path(BooksResource.class).path(BooksResource.class, "getBook").build(book.getId());
        final JsonObjectBuilder linksJson = Json.createObjectBuilder().add("self", selfUri.toString());
    
        if (bookStore.isAddToCartAllowed(book)) {
            final URI addToCartUri = uriInfo.getBaseUriBuilder().path(CartResource.class).build();
            linksJson.add("add-to-cart", addToCartUri.toString());
        }
    
        return Json.createObjectBuilder()
                .add("name", book.getName())
                .add("author", book.getAuthor())
                .add("_links", linksJson).build();
    }
    
    Listing 11. Book resource example using JSONP
    StreamsやLambda式、メソッドハンドルといったJava 8の言語機能を使って、取得されたPOJOのJsonObjectsとJsonArraysをプログラムで作成しています。このアプローチを使うと、開発者はレスポンスの構造や利用するコンテント・タイプを完全に管理することができます。
    実プロジェクトでは、ビジネス・オブジェクトをリンクやアクションを含むハイパーメディア・レスポンスにマッピングするためのこの機能は、Contexts and Dependency Injection (CDI) Managed Beanのような単独のコンポーネントに分割され、プロジェクト内の全てのRESTリソースクラスで再利用されることでしょう。
    完全なサンプルは、以下のリンクからどうぞ。
    Hypermedia with JAX-RS
    https://github.com/sdaschner/jaxrs-hypermedia
    サンプルには、リソースのリンクだけを含むハイパーメディアAPIを作成する方法や、様々なアプローチを使い、アクションを含める方法(Sirenを使って実現しています)が含まれています。

    Conclusion


    Java EE 7アプリケーションでハイパーメディア・ドリブンのREST APIを作成するために必要なものを全てご紹介しました。
    どのレベルのハイパーメディアを適用することが理に適っているのか、どのHTTPコンテント・タイプを使うべきか、レスポンスを作成するにあたって、ふつうのJava EE 7のアプローチに比べて、3rdパーティの依存性(ライブラリ)を利用することは妥当なのかどうか、ということを設計するにあたり選択することが最も重要です。

    See Also

    About the Author


    Sebastian DaschnerはフリーランスのJavaコンサルタント、ソフトウェア開発者、アーキテクトです。プログラミングやJava EEのエンスージアストであり、JCPへ参加し、JSR 370 Expert Group (JSR 370: JavaTM API for RESTful Web Services (JAX-RS 2.1) Specification)のメンバーです。また、GitHubで様々なオープンソースプロジェクトのハッキングをしています。6年以上Javaに関わってきました。Javaのほかに、LinuxやDockerのようなコンテナ技術のヘビーユーザーでもあります。自身のブログTwitterでコンピュータ・サイエンスのプラクティスを啓蒙しています。

    [Java, JavaScript] Java source name pattern checker with a nashorn script

    原文はこちら。
    https://blogs.oracle.com/sundararajan/entry/java_source_name_pattern_checker

    Ken Fogel(@omniprof)が先日以下のようなTweetをしていました。

    IDEによるソリューションはないのですが、以下のNashornスクリプトをカスタマイズして、Javaソースコード中のクラスやメソッド、変数名のパターンをチェックすることができます。このスクリプトはJava Tree APIを使ってJavaソースコードを解析しています。
    Compiler Tree API
    https://docs.oracle.com/javase/8/docs/jdk/api/javac/tree/
    その後、TreeScannerサブクラスをスクリプト内で利用してcheckXYZメソッドを呼び出し、クラスやメソッド、変数名をチェックします。checkXYZNameがfalseを返すと、このスクリプトは標準出力にソースのファイル名、行番号、列番号を表示します。
    おそらくこのスクリプトをカスタマイズして学生のソースを評価するのに使うことができるかもしれません。
    /*
     * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *   - Redistributions of source code must retain the above copyright
     *     notice, this list of conditions and the following disclaimer.
     *
     *   - Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *
     *   - Neither the name of Oracle nor the names of its
     *     contributors may be used to endorse or promote products derived
     *     from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    // Usage: jjs checknames.js -- <file-or-directory>
    
    if (arguments.length == 0) {
        print("Usage: jjs checknames.js -- <file-or-directory>");
        exit(1);
    }
    
    // Java types used
    var File = Java.type("java.io.File");
    var Files = Java.type("java.nio.file.Files");
    var StringArray = Java.type("java.lang.String[]");
    var ToolProvider = Java.type("javax.tools.ToolProvider");
    var Tree = Java.type("com.sun.source.tree.Tree");
    var Trees = Java.type("com.sun.source.util.Trees");
    var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
    
    // customize these functions with checks that you'd want!
    function checkClassName(name) {
        return name.length < 3;
    }
    
    function checkMethodName(name) {
        return name.length < 3;
    }
    
    function checkVarName(name) {
        return name.length < 3;
    }
    
    function checkNames() {
        // get the system compiler tool
        var compiler = ToolProvider.systemJavaCompiler;
        // get standard file manager
        var fileMgr = compiler.getStandardFileManager(null, null, null);
        // Using Java.to convert script array (arguments) to a Java String[]
        var compUnits = fileMgr.getJavaFileObjects(Java.to(arguments, StringArray));
        // create a new compilation task
        var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
        var sourcePositions = Trees.instance(task).sourcePositions;
        // subclass SimpleTreeVisitor
        var NameChecker = Java.extend(TreeScanner);
    
        var visitor = new NameChecker() {
            report: function(node) {
                var pos = sourcePositions.getStartPosition(this.compUnit, node);
                var line = this.lineMap.getLineNumber(pos);
                var col = this.lineMap.getColumnNumber(pos);
                print("Too short name: " + node.name + " @ " + this.fileName + ":" + line + ":" + col);
            },
    
            // override to capture information on current compilation unit
            visitCompilationUnit: function(compUnit, p) {
                this.compUnit = compUnit;
                this.lineMap = compUnit.lineMap;
                this.fileName = compUnit.sourceFile.name;
    
                return Java.super(visitor).visitCompilationUnit(compUnit, p);
            },
    
            // override to check class name
            visitClass: function(node, p) {
                if (checkClassName(node.simpleName.toString())) {
                    this.report(node);
                }
    
                return Java.super(visitor).visitClass(node, p);
            },
    
            // override to check method name
            visitMethod: function(node, p) {
                if (checkMethodName(node.name.toString())) {
                    this.report(node);
                }
    
                return Java.super(visitor).visitMethod(node, p);
            },
    
            // override to check variable name
            visitVariable: function(node, p) {
                if (checkVarName(node.name.toString())) {
                    this.report(node);
                }
    
                return Java.super(visitor).visitVariable(node, p);
            }
        }
    
        for each (var cu in task.parse()) {
            cu.accept(visitor, null);
        }
    }
    
    // for each ".java" file in directory (recursively).
    function main(dir) {
        var totalCount = 0;
        Files.walk(dir.toPath()).
          forEach(function(p) {
              var name = p.toFile().absolutePath;
              if (name.endsWith(".java")) {
                  checkNames(p);
              }
          });
    }
    
    main(new File(arguments[0]));
    

    [WLS] Connection Initialization Callback on WLS Datasource

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

    WebLogic Server 12.2.1.1がダウンロードできるようになりました。一般提供の発表に関するエントリは以下をどうぞ。
    Oracle WebLogic Server 12.2.1.1 is Now Available
    https://blogs.oracle.com/WebLogicServer/entry/oracle_weblogic_server_12_22https://orablogs-jp.blogspot.jp/2016/06/oracle-weblogic-server-12211-is-now.html
    One of the WebLogic Serverデータソースの機能の一つで、接続初期化中に呼び出されるコールバックを定義することができます。ただ、登場して長いにもかかわらずあまり取り上げられませんでした。コールバックの当初の目的は、Application Continuity (AC) 機能と共に使われるメカニズムを提供することでした。これを使うと、接続が予約されていたり、後ほど接続を再生する場合、アプリケーションにとって同じ接続初期化を保証することができる、というものです。後者の場合、元の接続に「リカバリ可能」なエラーがあって閉じられ、その陰で新規接続が予約され、元の接続に対してなされた操作の全てが新規接続で再生されます。コールバックを使うと、アプリケーションが必要とする任意の状態を使って再度接続を初期化することができます。

    アプリケーションソフトウェア内でgetConnection()を呼び出した任意の箇所にこの処理を散乱させずに、コールバックを使って全ての接続を初期化することができるというこのコンセプトは、再生を使わなかったとしても非常に便利です。実際には、コールバックをデータソース記述子で構成することができるので(この方法をお薦めします)、コールバックを記述する以外にアプリケーションへの変更はありません。

    以下でこの機能のサポートの歴史をまとめました。接続の初期化コールバックを設定している前提で、以下をサポートしていました。
    WLS Version Description
    10.3.6 リプレイドライバを使って実行する場合にActiv GridLinkデータソースでのみ呼び出される(リプレイはActive GridLink for RACでのみサポート)
    12.1.1/12.1.2/12.1.3 リプレイドライバと任意のデータソースタイプを使っている場合に呼び出される(リプレイのサポートが汎用データソースにも追加されたため)
    12.2.1 Oracleドライバと任意のデータソースタイプを使って呼び出される
    12.2.1.1 任意のドライバ、任意のデータソースタイプを使って呼び出される。Oracleドライバだけに制限する理由はないですね。
    Javaコード中でデータソースにコールバックを登録することで、アプリケーションにコールバックを構成することができますが、データソース毎にこれを1回だけ実施する必要があります。データソース構成で登録するほうがずっと簡単だと思います。

    以下はコールバックのサンプルです。
    package demo;
    import oracle.ucp.jdbc.ConnectionInitializationCallback;
    
    public class MyConnectionInitializationCallback implements
      ConnectionInitializationCallback { 
      public MyConnectionInitializationCallback()  { 
      }
      public void initialize(java.sql.Connection connection)
        throws java.sql.SQLException {
         // Re-set the state for the connection, if necessary
      }
    }
    
    以下は、できるだけデフォルトのものを使って登録しているコールバックを表示する、シンプルなJythonスクリプトです。
    import sys, socket
    hostname = socket.gethostname()
    connect("weblogic","welcome1","t3://"+hostname+":7001")
    edit()
    dsname='myds'
    jndiName='myds'
    server='myserver'
    cd('Servers/'+server)
    target=cmo
    cd('../..')
    startEdit()
    jdbcSR = create(dsname, 'JDBCSystemResource')
    jdbcResource = jdbcSR.getJDBCResource()
    jdbcResource.setName(dsname)
    dsParams = jdbcResource.getJDBCDataSourceParams()
    dsParams.addJNDIName(jndiName)
    driverParams = jdbcResource.getJDBCDriverParams()
    driverParams.setUrl('jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=otrade)))')
    driverParams.setDriverName('oracle.jdbc.OracleDriver')
    driverParams.setPassword('tiger')
    driverProperties = driverParams.getProperties()
    userprop = driverProperties.createProperty('user')
    userprop.setValue('scott')
    oracleParams = jdbcResource.getJDBCOracleParams()
    oracleParams.setConnectionInitializationCallback('demo.MyConnectionInitializationCallback')  # register the callback
    jdbcSR.addTarget(target)
    save()
    activate(block='true')
    
    ここではいくつか注目すべき点があります。まず、構成を使用してコールバックを登録するには、クラスがクラスパスになければなりません。とにかく、実行するには、サーバーのクラスパスにある必要がありますが、設定のために早く取得する必要があります。第二に、この機能の経緯から、接続パラメータではなくOracleのパラメータに設定が含まれています。そのため、我々は構成できることはそれほど多くありません。(Oracleタブに加えて)以下の図に示すように、WebLogic Server 12.2.1.1管理コンソールでは、[接続プール]の詳細パラメータでエントリを確認し、設定することができます。最後に、インタフェースはユニバーサル接続プール(UCP)インターフェイスであることにご注意ください。このコールバックをUCPアプリケーションで共有することができます(全てのドライバタイプをDatabase 12.1.0.2以降でサポートしています)。

    この機能は管理ガイドのApplication Continuityの章に記載があります。
    Oracle® Fusion Middleware Administering JDBC Data Sources for Oracle WebLogic Server 12c (12.2.1.1)
    Advanced Configurations for Oracle Drivers and Databases
    Application Continuity > Configuring Application Continuity > Using a Connection Callback
    http://docs.oracle.com/middleware/12211/wls/JDBCA/ds_oracledriver.htm#CCHFJDHF
    このエントリでは、コールバックを使って実際に何もしなかったことに失望されているかもしれませんが、次回のエントリで、別の新しいWLS12.2.1.1の機能でどのように使われているかを示すために再びこのコールバックを使用する予定です。