Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

外部言語の操作

$system.internal インタフェースにより、対応する Java、.NET、または Python のターゲット・オブジェクトを制御する ObjectScript プロキシ・オブジェクトを生成できます。プロキシ・オブジェクトにはターゲットと同じメソッドとプロパティのセットがあり、プロキシの呼び出しがそれぞれターゲットによりエコーされます。プロキシとターゲット間の通信は、Java、.NET、または Python の External Server に接続された ObjectScript Gateway オブジェクトにより管理されます。

ゲートウェイ・オブジェクトと InterSystems 外部サーバ間の接続
Connection diagram: proxy object <-> Gateway object <-> TCP/IP <-> External server <-> target object
  • ゲートウェイ・オブジェクトは、InterSystems IRIS ネームスペース内で実行され、1 つ以上の ObjectScript プロキシ・オブジェクトの接続を管理します。

  • InterSystems 外部サーバ・プロセスは、外部言語環境 (Java、.NET、または Python) で実行され、1 つ以上のターゲット・オブジェクトの接続を管理します。各ターゲット・オブジェクトは、外部サーバ・プロセスによって生成された個別のスレッドで実行されます。

  • 双方向のTCP/IP 接続により、ゲートウェイ・オブジェクトと外部サーバは、外部サーバ・インスタンスを一意に識別するポート番号を使用してメッセージを交換できるようになります。

以下のセクションでは、接続を確立し、ターゲットを定義し、プロキシ・オブジェクトを使用する方法を説明します。

.

ゲートウェイの作成とプロキシ・オブジェクトの使用

接続の開始、プロキシ・オブジェクトの作成、およびメソッドの呼び出しのプロセス全体を、1 つの文に圧縮できます。以下の例は Java 外部サーバを開始し、ターゲット・クラス java.util.Date のインスタンスのプロキシを作成し、日付を表示するメソッドを呼び出します。

write $system.external.getJavaGateway().new("java.util.Date").toString()

   Sun May 02 15:18:15 EDT 2021

この 1 行のコードは、プロキシ・オブジェクトの作成と使用のプロセス全体を示します。

Tip:

InterSystems ターミナルでこの呼び出しを実行してみましょう。C# と Python での同等のコマンドを以下に示します。

          write $system.external.getDotNetGateway.new("System.DateTime",0).Now
          write $system.external.getPythonGateway.new("datetime.datetime",1,1,1).now().strftime(%c)

外部サーバは InterSystems IRIS のインストール時に自動的に設定され、それ以上注意を払わなくてもほぼ確実に動作します (そうでない場合、“外部サーバの定義のトラブルシューティング” を参照してください。希望の言語のプラットフォームを識別するパス設定を変更する必要がある場合があります)。

前の例では、すべてを 1 行に圧縮していましたが、その行は以下の 3 つの重要な動作を実行します。

  • まず、ObjectScript と外部サーバ間の接続をカプセル化する ObjectScript Gateway オブジェクトを作成します。通常、以下のようにゲートウェイを変数に割り当てます。

    set javaGate = $system.external.getJavaGateway()
    
  • 次に、これはゲートウェイ・オブジェクトの new() メソッドを使用して、指定したクラスのプロキシ・オブジェクトを作成します。ここでも、オブジェクトは通常以下のように変数に割り当てられます。

    set dateJava = javaGate.new("java.util.Date")
    
  • 最後に、プロキシのオブジェクト・メソッドを呼び出します。

    write dateJava.toString()
    

以下の例は、3 つすべての言語でのこれらの手順を示しています。

ゲートウェイ・オブジェクトの作成

Java、.NET、および Python 外部サーバそれぞれに、getJavaGateway()getDotNetGateway()getPythonGateway() の固有のゲートウェイ作成メソッドがあります。これらの各メソッドは既定の構成で外部サーバを開始し、Gateway オブジェクトを返して接続を管理します。

set javaGate = $system.external.getJavaGateway()
set netGate = $system.external.getDotNetGateway()
set pyGate = $system.external.getPythonGateway()

また、カスタマイズされた外部サーバ構成で使用するための汎用の getGateway() メソッドもありますが (詳細は “外部サーバの定義のカスタマイズ” を参照)、ほとんどの目的には既定のメソッドで十分なはずです。

プロキシ・オブジェクトの作成

各ゲートウェイ・オブジェクトには、プロキシ・オブジェクトを作成するための new() メソッドがあります。

set dateJava = javaGate.new("java.util.Date")
set dateNet = newGate.new("System.DateTime",0)
set datePy = pyGate.new("datetime.datetime",1,1,1).now()

new() メソッドへの各呼び出しでは、クラス名と必要なすべての引数を指定します。この例には現在 3 つの外部サーバを介して接続された 3 つのプロキシ・オブジェクトが含まれています。各オブジェクトは、その他の ObjectScript オブジェクトと同様に処理されます。3 つすべてを、同じ ObjectScript アプリケーションで使用できます。

プロキシ・オブジェクトのメソッドとプロパティの呼び出し

これで 3 つのオブジェクトすべてのメソッドとプロパティを、同じ write 文で使用できるようになりました。

write !,"  Java: "_dateJava.toString(),!,"  .NET: "_dateNet.Now,!, "Python: "_datePy.strftime("%c")
     Java: Sun May 02 15:18:15 EDT 2021
     .NET: 2021-05-02 16:38:36.9512565
   Python: Sun May 02 15:23:55 2021

Java および Python の例はメソッドの呼び出しで、.NET の例ではプロパティを使用しています。

これまでの例では、システム・クラスのみを使用していました。これらはいつでも利用可能なので、説明しやすいためです。ほとんどの場合、使用する前にクラスの場所を指定する必要があります。以下のセクションでは、任意のクラスのプロキシの取得方法を説明します。

ターゲット・ソフトウェアへのパスの定義

すべての Gateway オブジェクトには、ソフトウェア・ライブラリ (jar ファイル、アセンブリ、およびモジュール) へのパスのリストを格納できます。addToPath() メソッドでは、リストへの新しいパスを追加できます。addToPath() のメソッド・シグニチャは以下のとおりです。

   addToPath(path As %RawString)

path 引数は 1 つのパスを含む単純な文字列にするか、複数のパスを含む動的配列にすることができます。以下に例を示します。

動的配列へのパスの追加

%DynamicArrayOpens in a new tab クラスは、JSON 配列構造を簡単に作成できるようにする ObjectScript ラッパです。動的配列の %Set() メソッドを使用して、配列にパスの文字列を追加します。以下の例は、配列 pathlist に 2 つのパスを追加し、それを Java Gateway オブジェクトの addToPath() メソッドに渡します。

set pathlist = []
do pathlist.%Set("/home/myhome/firstpath.jar")
do pathlist.%Set("/home/myhome/another.jar")
do javaGate.addToPath(pathlist)

動的配列の詳細は、"JSON の使用" の “%Set()、%Get()、および %Remove() の使用” を参照してください。

以下の例は、各言語にクラスを指定する方法を示しています。

Java クラスへのパスの追加

Java の場合、パスにはフォルダまたは jar を指定できます。以下の例は、someclasses.jar へのパスを追加し、次に someclasses.classname のインスタンスのプロキシを作成します。

set javaGate = getJavaGateway()
do javaGate.addToPath("/home/myhome/someclasses.jar")
set someProxy = javaGate.new("someclasses.classname")
.NET クラスへのパスの追加

.NET の場合、パスにはフォルダまたはアセンブリを指定できます。以下の例は、someassembly.dll へのパスを追加し、次に someassembly.classname のインスタンスのプロキシを作成します。

set netGate = getDotNetGateway()
do netGate.addToPath("C:\Dev\myApp\somedll.dll")
set someProxy = netGate.new("someassembly.classname")
Python クラスへのパスの追加

Python の場合、パスにはモジュールまたはパッケージを指定できます。モジュールがパッケージの一部である場合、モジュールのパスはパッケージの最上位のディレクトリから開始するドット表記で指定する必要があります。例えば、モジュール Foo.py へのパスは、以下の 2 つの方法のどちらかで指定できます。

  • モジュールとして処理される場合の標準のパス表記 : C:\Dev\demo\Foo.py

  • パッケージ demo の一部として処理される場合のドット表記 : C:\Dev\demo.Foo.py

以下の例は、動的配列を使用して、フォルダ C:\Dev\demo\ に含まれる 2 つの異なるファイルへのパスを追加します。ファイル Foo.py には、パッケージ化されていないクラス personOne が含まれ、ファイル Bar.py には、パッケージ demo の一部であるクラス personTwo が含まれます。new() を呼び出すと、以下のように両方のクラスのプロキシが作成されます。

set pyPaths = []
do pyPaths.%Set("C:\Dev\demo\Foo.py")
do pyPaths.%Set("C:\Dev\demo.Bar.py")

set pyGate = getPythonGateway()
do netGate.addToPath(pyPaths)
set fooProxy = pyGate.new("Foo.personOne")
set barProxy = pyGate.new("demo.Bar.personTwo")

クラスのないモジュールまたはパッケージのターゲットを割り当てることも可能です。詳細は、このセクションの最後の “Python のターゲットの指定” を参照してください。

Note:

path 引数は、複数のパス文字列を含む %Library.ListOfDataTypesOpens in a new tab のインスタンスとしても指定できますが、使いやすさを考慮すると動的配列をお勧めします。

Python のターゲットの指定

Python のターゲットを指定する構文は、ターゲットがパッケージまたはクラスのいずれに含まれるか、その両方か、またはどちらでもないかによって異なります。以下の例は、パスが addToPath() で指定され、クラス名が new() で指定される場合を示しています。

クラスの例では、person がメイン・クラスで、company はそれがインポートするクラスです。インポートされるクラスは、それが別個のファイル内にあるとしても、指定する必要はありません。

クラスのないモジュールまたはパッケージのターゲットも割り当てられますが、それらは実質的に静的なメソッドおよびプロパティに制限されます (クラスなしでクラス・インスタンス・メソッドを持つことはできないため)。

パッケージなし、クラスなし

パッケージもクラスもないモジュールは、ファイル名を使用します。new() の引数は、ファイル名の後にピリオドが続き、クラスがないことを示していることに注意してください。

do gw.addToPath(/rootpath/noclass.py")
set proxy = gw.new("noclass."))

パッケージなし、1 つのファイル内に 2 つのクラス

メイン・クラス person およびインポートされるクラス company は両方ともファイル /rootpath/onefile.py 内にあります。

do gw.addToPath(/rootpath/onefile.py")
set proxy = gw.new("onefile.person")
パッケージなし、別個のファイル内に 2 つのクラス

メイン・クラス person およびインポートされるクラス company は、/rootpath 内の別個のファイルに含まれます。

do gw.addToPath(/rootpath/person.py")
set proxy = gw.new("person.person")
パッケージ demo、クラスなし

クラスなしのパッケージでは、パッケージ名とファイル名を使用します。この例でのファイルの実際のパスは /rootpath/demo/noclass.py になります。new() の引数はピリオドで終了し、クラスがないことを示しています。

do gw.addToPath(/rootpath/demo.noclass.py")
set proxy = gw.new("demo.noclass.")
パッケージ demo、1 つのファイル内に 2 つのクラス

メイン・クラス person およびインポートされるクラス company は両方ともファイル /rootpath/demo/onefile.py 内にあります:

do gw.addToPath(/rootpath/demo.onefile.py")
set proxy = gw.new("demo.onefile.person")
パッケージ demo、別個のファイル内に 2 つのクラス

メイン・クラス person およびインポートされるクラス company は、/rootpath/demo 内の別個のファイルに含まれます。

do gw.addToPath(/rootpath/demo.person.py")
set proxy = gw.new("demo.person.person")
FeedbackOpens in a new tab