作成日: 2007年11月18日
作成者: (株)ズィット 田上 真也
最終更新日: 2007年11月18日
ColdFusion8では、Adobe Intergrated Runtime(AIR)やAdobeLiveCycleなどとの統合を始め、多くの機能の追加とパフォーマンスの向上が図られましたが、今回は追加機能の一つであるMicrosoft.NETとの統合についてご紹介したいと思います。
ColdFusionでは以前バージョンでもWebServiceやCOMなど間接的な形でのみ.NETアセンブリと連携を行うことができましたが、今回のリリースによりCFMLでも.NETアセンブリを扱うことができるようになりました。
既存の.NETコンポーネントを使用することはもちろん、Javaでは標準でコントロールの困難なMicrosoft Office製品であるWordやExcel、PowerPointなどを.NETアセンブリを通じてコントロールすることができます。
ではCFMLからは.NETアセンブリをどのように呼び出すことができるのか、というとJavaやCOMなどと同様にcfobject及びCreateObjectを使用することで.NETアセンブリのインスタンスを簡単に生成することができます。
・cfobjectタグの例
<cfobject type=”.NET”
class="SampleClassLibrary1.Class1″
assembly="C:/cfdotnet/dll/SampleClassLibrary1.dll”
name="sample” />
・CreateObject タグの例
sample =
createObject(”.NET”, “SampleClassLibrary1.Class1″, “C:/cfdotnet/dll/SampleClassLibrary1.dll");
詳しい構文については
cfobjectタグ
(http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_m-o_09.html#2926282)
CreateObjectファンクション
(http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=functions_c-d_13.html#5178272)
をご参照ください。
ColdFusionでは.NETアセンブリにアクセスする為に拡張機能を通じて参照を行っています。※1
この拡張機能はColdFusion側と.NET側とで2つに分かれて機能します。※2
ColdFusion側ではcfobject又はCreateObjectで呼び出された際にCFMLで扱えるように.NETアセンブリのJavaのProxyクラスを通じて.NET側へ通信(tcp/Binaryまたはhttp/SOAP)を行います。
.NET側ではColdFusion側からの要求を受けて.NETアセンブリを呼び出します。
ですので、ColdFusion側では.NETアセンブリを呼び出す為のJavaのProxyクラスが必要です。
JavaのProxyクラスはColdFusion側と.NET側が同一環境である場合、ColdFusionが自動で生成を行ってくれます。
.NETアセンブリが別リモートホスト環境にある場合は、ColdFusionは自動生成できない為別途作成する必要があります。詳しくは後述いたします。
※1 詳細に関しては
ColdFusion Developer’s GuideのUsing Microsoft .NET Assemblies -> About ColdFusion and .NET
(http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=dotNet_02.html)
の「How .NET access works」の項をご参照ください。
※2 その中核にJNBridgeProというJava-.NET間のBrigdeソフトウェアを使用しています。
JNBridgeProではJavaから.NETアセンブリを呼び出すことに加え.NETアセンブリからJavaを呼び出す機能も持っています。
JNBridgeProについてはホームページ(http://www.jnbridge.com/)をご参照ください。
まずは.NETアセンブリを利用する為の環境を整えます。
ColdFusion8で.NETアセンブリクラスへアクセスする為には、ColdFusion8の他に以下の2つがインストールされている必要があります。
1)Microsoft .NET Framework SDK
2)ColdFusion 8 .NET Integration Services
どちらも.NETが稼働する環境でインストールが必要となります。
(リモートの.NET アセンブリにアクセスする場合には呼び出すリモートホスト上に「Microsoft .NET Framework SDK」及び「.NET Integration Services」をインストールします。
この場合リモートのホストにColdFusion8をインストールする必要はありません。)
1)Microsoft .NET Framework SDKのインストール
利用する.NETアセンブリのバージョンをインストールしておく必要があります。
なお本稿のサンプルでは.NET Framework 2.0を利用しています。インストールされていないようでしたらダウンロードページ
(http://www.microsoft.com/downloads/details.aspx?familyid=FE6F2099-B7B4-4F47-A244-C96D69C35DEC&displaylang=ja)よりダウンロードを行ってインストールを行ってください。
2)ColdFusion 8 .NET Integration Servicesのインストール
− ColdFusion8をインストールしていない場合
ColdFusion8のDeveloperバージョンはダウンロードページ
(http://www.adobe.com/support/coldfusion/downloads.html)からダウンロードできます。
「.NET Integration Services」はWindows用のColdFusionインストーラに
含まれています。インストールのサブコンポーネントを選択する際には
「.NET Integration Services」にチェックを付けてインストールをして下さい。
− ColdFusion8をインストールしている場合
「.NET Integration Service」がインストールされている必要があります。
インストールされていない場合は「ColdFusion 8 .NET Integration Service」のみのインストーラが用意されています。
ColdFusion8のDeveloperバージョンと同じページにリンクがありますのでダウンロードしてインストールを行ってください。
ここで注意していただきたいことは、「.NET Integration Services」をインストールする前に.NET Framework SDKをインストールしておく必要があるということです。
ColdFusion8の.NET Integration Servicesを先にインストールし、後にMicrosoft .NET Framework SDKをインストールしても、JavaのProxyクラスが正しく生成時に後でインストールした.NET Frameworkを認識できず、利用時に例外が発生してしまいます。
もし既にインストールされている場合には、再度インストールを行ってください。
本稿のサンプルを以下(dotnet_integration_sample.zip)よりダウンロードしてください。
Zipファイルを展開すると以下の3つのディレクトリが出てきます。
├─C#projectファイル
├─CF
└─cfdotnet
・C#projectディレクトリ
今回使用するサンプルのC#でのソースファイルです。
なお今回のサンプルはMicrosoft Visual C# Express Edition で作成しています。
・CFディレクトリ
今回使用するサンプルのColdFusionのソースです。
ColdFusionが参照できるパスに配置してください。
本稿ではColdFusionインストールディレクトリ/wwwrootに配置しているとして説明していきます。
・cfdotnet
ColdFusionがインストールされているローカルの呼び出しの場合
→そのままC:の直下に配置をしてください。
ColdFusionがインストールされていないリモートへの呼び出しの場合
ColdFusion側(呼び出し元)
.NET側(呼び出される側)
ColdFusionから呼び出される.NETアセンブリクラスのソースです。本稿でのサンプルはC#で作成していますがC#でなければ駄目、という訳ではありません。
SampleClassクラスはColdFusionから呼び出す為のクラスです。
4つのメソッドを用意しています。
1)public IList ArrayListSample()
ArrayListを返すサンプルです。
2)public IList ArrayArgumentSample(Object[] args)
配列をもらって.NET側で値を追加して返すサンプルです。
3)public Hashtable HashtableSample()
System.Collections.Hashtableを返すサンプルです。
4)public SampleDto CustomClassSample(SampleDto dto)
カスタムクラスを引数で受けて返すサンプルです。
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
namespace SampleClassLibrary
{
public class SampleClass
{
// ArrayListを返すサンプルです。
public IList ArrayListSample()
{
IList list = new ArrayList();
list.Add(”.NETで追加した値です。(ArrayListSample)");
return list;
}
// ColdFusionの配列を引数としたサンプルです。
public IList ArrayArgumentSample(Object[] args)
{
IList retArray = new ArrayList();
foreach (Object obj in args)
{
retArray.Add(obj);
}
retArray.Add(”.NETで追加した値です。(ArrayArgumentSample)");
return retArray;
}
// Hashtableを返すサンプルです。
public Hashtable HashtableSample()
{
Hashtable hashTable = new Hashtable();
hashTable.Add("DOTNET”, ”.NETで追加した値です。(HashtableSample)");
return hashTable;
}
// カスタムのクラスを引数及び戻り値としたサンプルです。
public SampleDto CustomClassSample(SampleDto dto)
{
dto.UserName = “サンプル太郎 : ” + dto.UserId;
return dto;
}
}
}
SampleClass.cs
SampleDtoクラスはSamplesClassとColdFusionの間を行き来する転送用のオブジェクトです。
プロパティでアクセスするようになっています。
using System;
using System.Collections.Generic;
using System.Text;
namespace SampleClassLibrary
{
public class SampleDto
{
private string userId = “”;
private string password = “”;
private string userName = “”;
public SampleDto(){}
public string UserId
{
get
{
return this.userId;
}
set
{
this.userId = value;
}
}
public string Password
{
get
{
return this.password;
}
set
{
this.password = value;
}
}
public string UserName
{
get
{
return this.userName;
}
set
{
this.userName = value;
}
}
}
}
SampleDto.cs
上記のクラスをビルドしたものが「SampleClassLibrary.dll」となっています。
(C:/cfdotnet/dllにあります。)
今度は.NETアセンブリを呼び出す為のColdFusion側のソースです。
ColdFusion側では呼び出す先の.NETアセンブリがローカルにあるのかリモートにあるのかで若干インスタンスの呼び出し方法が違ってきます。
−ローカルの.NETアセンブリを呼び出す場合
<cfobject type=”.NET”
class="SampleClassLibrary.SampleClass”
assembly="C:/cfdotnet/dll/SampleClassLibrary.dll”
name="samples” />
−リモートの.NETアセンブリを呼び出す場合
<cfobject type=”.NET”
class="SampleClassLibrary.SampleClass”
assembly="/cfdotnet/jar/SampleClassLibrary.jar”
name="samples”
protocol="tcp”
server="192.168.1.102″
port="6086″/>
呼び出し方法の違いは以下のとおりです
・リモートの場合はリモートのホストの情報を属性に設定する必要がある。
・リモートの場合は通信方法も指定する。
・assembly属性はローカルでは.NETのDLLを指定するが、リモートでは.NETアセンブリを呼び出す為のJavaのProxyクラス(jarファイル)を指定する。
なお、CreateObjectに関しても同様にローカルとリモートで呼び出し方法が異なります。
しかしそれ以外の部分に関しては差異がありません。ローカルであろうとリモートであろうと同様に.NETアセンブリを扱うことができます。
サンプルではSampleClassのメソッドを呼び出し戻ってきた値をColdFusion側で追加してそれぞれdumpして表示をしています。
ここで気をつけなければならないのがプロパティ及びフィールドへのアクセスです。
CFMLからはプロパティやフィールドへは、値を設定する場合には“Set_”(1)、値を取得する場合には“Get_”(2)、の接頭辞をつけたメソッドを通じてのみアクセスすることができます。
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns="http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv="Content-Type” content="text/html; charset=Shift_JIS” />
<title>ColdFusion .NET Integration サンプル (Local)</title>
</head>
<body>
<cfset assemblyList = “C:/cfdotnet/dll/SampleClassLibrary.dll” / >
<cfobject action="create” type=”.net” class="SampleClassLibrary.SampleClass” assembly="#assemblyList#” name="samples” />
<!— ArrayListのサンプル —>
<cfset dotNetArrayList = samples.ArrayListSample() />
<cfset ArrayAppend(dotNetArrayList, “CFから追加した値です。1(Array)") />
<cfdump var="#dotNetArrayList#” />
<!— CFの配列を渡すサンプル —>
<cfset cfArray = ListToArray(ArrayToList(dotNetArrayList, ”,"), ”,")/>
<cfset ArrayAppend(cfArray, “CFから追加した値です。2(Array)") />
<cfset dotNetArrayList2 = samples.ArrayArgumentSample(#cfArray#) />
<cfdump var="#dotNetArrayList2#” />
<!— Hashtable —>
<cfset dotNetTable = samples.HashtableSample() />
<cfset dotNetTable.CFKEY = “CFから追加した値です。” />
<cfset StructInsert(dotNetTable, “CFKEY2″, “CFから追加した値です。その2")
/>
<cfdump var="#dotNetTable#” />
<!— カスタムクラス —>
<cfset cfDto = CreateObject(”.NET”, “SampleClassLibrary.SampleDto”, “#assemblyList#")/>
<!—
プロパティやフィールドへの値の設定は
Set_プロパティ名( 値 )
—>
<cfset cfDto.Set_UserId("user001″) />
<cfset cfDto.Set_Password("password") />・・・・・・・(1)
<cfset dotNetDto = samples.CustomClassSample(cfDto) />
<cfdump var="#dotNetDto#” />
<br />
ユーザー名<p>
<!—
プロパティやフィールドからの値の取得は
Get_プロパティ名()
—>
<cfdump var="#dotNetDto.Get_UserName()#” />・・・・・・・(2)
</p>
</body>
</html>
「sample_local.cfm」
・ColdFusionの自動型変換機能
ColdFusionでは.NETのクラスもCFMLから容易に利用できる様、自動で型の変換を行います。
自動での型変換にはいくつかのタイプがあります。
(1)ColdFusionと.NETの双方向で互換性が保って変換されるもの
(2)ColdFusion側で厳密に型指定(JavaCast)や特定の操作を行うことで型変換ができるもの
(3).NET側からColdFusion側への変換のみ行うもの
(4)型の変換が行えないもの
(1)はboolやintなどのプリミティブ型やstring、また配列型などが該当します。
(2)はBigDecimal型やSystem.Byte型などが該当します。
(3)はSystem.Collection.ArrayList、System.Collection.Hashtable、System.Data.DataTableが該当します。
残念ながらenum型は(4)に該当しColdFusionでは扱えません。
詳しくは
(http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=dotNet_04.html#1153686)をご参照ください。
今回は特にColdFusionでアプリケーションを組む際によく利用されるだろう以下の型を抜粋してサンプルを作成しています。
それでは実際にサンプルを動かしてみます。
(1)ColdFusionのローカルの.NETアセンブリクラスにアクセスする場合
sample_local.cfmにアクセスしてみてください。
例: http://localhost:8500/sample_local.cfm
ColdFusionは初回アクセス時に.NETアセンブリを呼び出すのに必要なJavaのProxyクラスを自動生成してくれる為、初回はやや時間がかかりますがそのままページが表示されます。
2回目以降はすばやく表示されるようになります。
(2)ColdFusionのリモートホストの.NETアセンブリクラスにアクセスする場合
リモートでの呼び出しの場合はもう少し設定を行う必要があります。
ColdFusionからリモートのクラスを呼ぶ際には、リモートの.NETアセンブリを呼び出す為のJavaのProxyクラスを生成する必要があります。
手順は後述していますので参考にしてみてください。
ここでは、用意したサンプルのJavaのProxyクラスを使用します。
また、呼び出される.NET側においては呼び出す対象の.NETアセンブリのパスを指定する必要があります。
ColdFusionインストールディレクトリ/jnbridge又は.NET Integration Servicesインストールディレクトリにある「JNBDotNetSide.exe.config」の<assemblyList>タグ内にパスを記述します。
<assemblyList>
<assembly file="C:/cfdotnet/dll/SampleClassLibrary.dll"/>
</assemblyList>
「JNBDotNetSide.exe.config」
サンプルを動かす前にもう一点。リモートの呼び出しではsample_remote.cfmにアクセスして確認していただけますが、サンプルではリモートのサイトを「192.168.1.102」としています。
各環境にあわせserver属性やport属性を修正してください。
それでは、sample_remote.cfmにアクセスしてみてください。
本サンプルではMacOSX上からリモートの呼び出しを行い動作することを確認しました。
・リモートクラスの作成方法
1.jnbproxyGui.exeを起動します。
jnbproxyGui.exeはColdFusion8がインストールされている場合は“ColdFusionインストールディレクトリ/jnbridge”
インストールされていない場合は“.NET Integration Servicesインストールディレクトリ”直下にあります。
2.「Create new Java -> .NET project」を選択します。
3.メインウインドウが開きます。メニューの「Project」->「Edit Assembly List」を選択します。
4.ダイアログが開きます。「Add」ボタンを押下してください。
5.ファイル選択のダイアログが開くのでJavaのProxyクラスを作成したい
.NETアセンブリを選択して「OK」ボタンを押下します。
6.一覧に追加されていることを確認し「OK」を押下します。
7.次にメニューから「Project」->「Add from Assembly List」を選択します。
8.作成する.NETアセンブリクラス名を下のテキストボックスに入力して「Add」ボタンを押下します。
9.一覧に追加されていることを確認し「OK」を押下します。
10.メッセージボックスが表示されるのでそのまま「OK」ボタンを押下します。
11.Environmentのリストにクラスが表示されるので
メニューから「Edit」->「Check All in Environment」を選択してチェックをつけます。
12.Environmentのリスト右の「Add」ボタンを押下します。
13.Expose proxiesのリストにクラスが表示されるのでメニューから「Edit」->「Check All in Expose proxies」を選択してチェックをつけます。
14.メニューから「Project」->「Build」を選択すると、
jarファイルの保存場所を指定するダイアログが開くので指定するとBuildが始まります。
BUILDCOMPLATEDと表示されれば完了です。
駆け足でしたが.NETアセンブリを呼び出すまでをご紹介いたしました。いかがだったでしょうか。
既存の.NETの資源をWebServiceなど利用せずに使用できることや.NETでなければ難しいということで見送っていたことも、一部だけ.NET利用するといった事もでき選択肢が増えたことは喜ばしい事だと思います。
またColdFusionはJavaを始めWebServiceなども容易に扱うことができ、対応プラットフォームも増えました。
今後ColdFusion8が様々な言語間を統合する役割としてもますます活躍が期待できそうです。