特集:組み込みにも役立つJavaとネイティブコードの橋渡し

JNIより簡単にJavaとC/C++をつなぐ「JNA」とは


富士ソフト株式会社
高見 誠
2009/12/14


C/Sでは、サーバサイドはC/C++がまだまだ主役

今回の主な内容

C/Sでは、サーバサイドはC/C++がまだまだ主役
JNIを使いやすくした「JNA」とは

JNAを利用するための基本的な流れ
JavaとC/C++のマッピング方法、6パターン
JNAアプリケーションのアーキテクチャ
JNIよりも保守性を高めるJNA

 インターネットの普及に加えて、リッチクライアントRIAの発展とともに、アプリケーションの形態は、C/S(クライアント/サーバ)システムから、Webアプリケーションシステムにシフトしています。一般の情報発信システムだけではなく、企業の基幹情報システムまで、盛んにWebアプリケーションで構築するようになりました。

 この変化の主役であるといわれる、Java技術は、Webアプリケーションシステムの発展とともに、ネットワークの親和性や、プラットフォーム適用の多様性で、広く受け入れられて、Webアプリケーションシステム開発の基盤技術になっています。

 これまでのC/Sシステムでは、サーバロジックはC/C++で実装されるケースが一般的でした。C/SシステムからWebアプリケーションシステムにシフトする際に、Java技術を導入することを決めた場合、Java技術で、すべて新規開発するのは1つの選択肢ですが、速く移行するために、既存のソフトウェア資産を再利用するのも、もう1つの選択肢でしょう。

表側はJava、裏側でC/C++というレガシー移行

 つまり、Webプレゼンテーションサービス層はJava技術で実装して、ビジネスロジック層は安定したC/C++で書かれた既存モジュールを再利用します。このとき、JavaのWebプレゼンテーションサービス層とC/C++のビジネスロジック層を連携するために、JavaからC/C++のネイティブライブラリAPIを呼び出す技術が必要です。

 一方、Java技術の発展や、プラットフォームの多様性とともに、Webサーバロジックの実装だけではなく、Java技術でGUIアプリケーションを開発するケースも増えています。しかしながら、プラットフォームのOSや、デバイスドライバなどがほとんどC++で書かれている現状で、ネイティブAPIを利用するには、やはりJavaからC/C++のネイティブライブラリAPIを呼び出す技術が必要です。

「JNI」ってなかったっけ?

 これらのアプリケーションシステム構築における共通点は、JavaからC/C++のネイティブライブラリAPIを呼び出す技術が必要になることであり、Java技術では、これらのニーズを満たすために、JNI(Java Native Interface)仕様と実装を提供しています。

 しかし、実際にコーディングをしてみると、煩雑で、なじまないコーディングを強いられて、メソッドのマッピングやデータのマッピングに追われてしまい、肝心なビジネスロジックに集中できません。利用のハードルは高く、トータルではシステム開発の生産性が期待した通りにはならず、さらにシステム全体の保守性低下が発生します。

 本特集では、システム開発の生産性向上のために直接JNIを利用せず、比較的利用ハードルが低いJNA(Java Native Access)ライブラリを利用する方法を紹介します。なお、C/C++になじみのない読者は下記記事を参照しておいてください。

JNIを使いやすくした「JNA」とは

 JNAとは、直接JNIを利用せず、Javaプログラムが簡単にネイティブライブラリ(.dll、あるいは、.so)を共有する方法を提供するライブラリです。

 機能的には、.NETP/Invoke(Platform Invoke)や、Pythonctypesと類似しています。特別処理が必要となる配列などの複雑なデータ型を使う一部のAPIを除けば、C/C++のコードを書かず、JavaプログラムがネイティブライブラリAPIを呼び出せるので、システム開発の生産性も向上しますし、保守性が低下することもありません。

サポートするプラットフォーム

 特に、JNAを用いて開発したGUIアプリケーションは、自動的にマルチプラットフォームに対応するため、プラットフォームを意識せず開発できます。JNAサイトによると、JNAは以下のプラットフォームをサポートしています。

  • Windows(x86、x86_64)
  • Linux(x86、AMD64)
  • FreeBSD/OpenBSD(x86、AMD64)
  • Solaris(x86、AMD64、SPARC、SPARC V9)
  • Mac OS X(PPC、x86、x86-64)

 最近人気のモバイルプラットフォームAndroidに対するサポートについても話題となっていて、将来には利用できることを期待したいです。最近は組み込み分野でもJavaが進出してきていて、適用分野は広いと思います。 ほかにも、さまざまなところで使われているので、今後要注目のライブラリといえるでしょう。

JNAの生い立ち

 JNAは、元サン・マイクロシステムズの開発者がNetBeans IDEを開発するために、開発されました。初めて公開されたのは1999年ですから、すでに10年以上経過しており、2006年にオープンソースとして発表されました。以後も、機能が増やされ、サポートするプラットフォームも増え、海外では多数なプロジェクトに採用されています。現在も、新しいリリースが続々公開されており、活発に開発が続いています。

JNIをベースに

 JNAは、JNIをベースとしています。従って、性能面ではJNIよりオーバーヘッドが多いと思われます。しかし、JNAの内部実装では、データ型の変換は最適化されていますので、JNIを用いる自前実装より、必ず劣るとはいえません。

 また、ハードウェア性能の進歩もあって、むしろシステム開発の生産性向上や安全性を優先することも考えられるでしょう。

JNAの主な機能

 クロスプラットフォームや言語間の呼び出しには、データ型のマッピングとメソッド(関数)のマッピングが、主な実装処理です。JNAは、開発者の負担を軽減するために、以下の主な機能を提供し、強くサポートしてくれます。

  • ネイティブライブラリのマッピング
  • ネイティブメソッド(API)のマッピング
  • データのマーシャリング(各プログラミング言語のネイティブなデータ表現を共通データ形式に変換する処理)

 データのマーシャリングでは、ほとんどのプリミティブなデータ型は自動的にマッピングしてくれます。しかし、配列型やネスト構造のデータ型などは、CとJavaの配列に対する実装方法の差異があるので、データをマッピングするための補助ユーティリティを利用して自前で実装する必要があります。これについては、後で詳しく紹介します。

JNAの入手

 JNAは、JNAのサイトからダウンロードできます。2009年11月の原稿執筆時現在の最新バージョンは3.2.3で、採用しているライセンスはLGPL 2.1またはそれ以降です。

JNAを利用する開発環境の構築

 ダウンロードした後、インストール作業は必要ありません。入手した「jna.jar」ファイルを開発するアプリケーションの外部ライブラリとして、単純にクラスパスを通すだけです。

 jna.jarパッケージは、データマッピング用のJavaサブパッケージをいくつか含みます。そのほか、WindowsやSolarisやLinuxなどのプラットフォームのネイティブライブラリAPIにディスパッチするためのライブラリ(.dllや.so)も含まれます。

  1-2-3-4

 INDEX 特集「組み込みにも役立つJavaとネイティブコードの橋渡し」
Page1
  C/Sでは、サーバサイドはC/C++がまだまだ主役
JNIを使いやすくした「JNA」とは
  Page2
  JNAを利用するための基本的な流れ
JavaとC/C++のマッピング方法、6パターン
 【1】ライブラリのマッピング
 【2】APIのマッピング
 【3】プリミティブデータ型のマーシャリング
  Page3
   【4】構造体型のマッピング
 【5】配列型のマッピング
  Page4
   【6】入れ子構造体型のマッピング
JNAアプリケーションのアーキテクチャ
JNIよりも保守性を高めるJNA

Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間