normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

Windows 上で WildFly 8.x 実行時に "java.net.BindException: Address already in use" が発生する

WildFly 8.x, "java.net.BindException: Address already in use" on fresh install in windows Vista/7/8 の記事に記載があるが、WindowsVista, 7, 8 )で WildFly 8.x 実行時に "java.net.BindException: Address already in use" が発生する場合がある。

普通は「Tomcat を起動しっぱなしだった」や「JBoss AS や別バージョンの WildFly を起動しっぱなしだった」が原因だが、どうやら NVIDIA Network Service が問題らしい。WindowsVista, 7, 8 )で NVIDIA を利用しており、WildFly 8.x を利用する場合は以下のプロセスを停止することで暫定対策ができる。
f:id:waritohutsu:20150605143726p:plain

DocumentDB の Java SDK で jackson を使う場合の TIPS

随分前に発表された DocumentDB だが、意外にサンプルが少ないので触ってみたところを軽く記載する。DocumentDB は JSON 形式でデータをやり取りするため、Java オブジェクトを JSON 形式に変換する必要がある。

Build a Java web application using DocumentDB に記載されたサンプルを見ると Project Lombok を利用しているが、今回は jackson を使ってみた。

まず、あらかじめ管理ポータルから DocumentDB アカウントを作成し、"TestDB" というデータベースの作成、"TestCollection" というコレクションの作成、以下の様にドキュメントの作成を実施する。
f:id:waritohutsu:20150524151856p:plain

次に、管理ポータルからエンドポイントとキーを取得し、以下のコードを実行する。

package com.mydomain.documentdb;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.microsoft.azure.documentdb.ConnectionPolicy;
import com.microsoft.azure.documentdb.ConsistencyLevel;
import com.microsoft.azure.documentdb.Database;
import com.microsoft.azure.documentdb.Document;
import com.microsoft.azure.documentdb.DocumentClient;
import com.microsoft.azure.documentdb.DocumentClientException;
import com.microsoft.azure.documentdb.DocumentCollection;
import com.microsoft.azure.documentdb.RequestOptions;
import com.mydomain.model.Person;

public class SampleTest {

	// Define an id for your database and collection
	private static final String DATABASE_ID = "TestDB";
	private static final String COLLECTION_ID = "TestCollection";

	// documentdb.properties から情報を取得
	private static String END_POINT;
	private static String MASTER_KEY;

	private static DocumentClient documentClient;
	private static Database databaseCache;
	private static DocumentCollection collectionCache;

	@Before
	public void testInitialize() throws IOException {
		// TODO: 外部設定ファイルを作成すること
		String path = "documentdb.properties";
		InputStream in = SampleTest.class.getClassLoader().getResourceAsStream(
				path);
		if (in == null) {
			throw new IllegalArgumentException(path + " not found.");
		}
		Properties props = new Properties();
		props.load(in);

		END_POINT = props.getProperty("END_POINT");
		MASTER_KEY = props.getProperty("MASTER_KEY");
		documentClient = new DocumentClient(END_POINT, MASTER_KEY,
				ConnectionPolicy.GetDefault(), ConsistencyLevel.Session);
	}

	@Test
	public void readTest01() throws DocumentClientException,
			JsonParseException, JsonMappingException, IOException {
		Person expected = new Person();
		Person actual;

		expected.setAge(45);
		expected.setName("割と普通");

		List<Document> documentList = documentClient
				.queryDocuments(getTestCollection().getSelfLink(),
						"SELECT * FROM root r WHERE r.id='" + 1 + "'", null)
				.getQueryIterable().toList();
		ObjectMapper mapper = new ObjectMapper();
		actual = mapper.readValue(documentList.get(0).toString(), Person.class);

		Assert.assertEquals(expected, actual);
	}

	private Database getTestDBDatabase() {
		if (databaseCache == null) {
			// Get the database if it exists
			List<Database> databaseList = documentClient
					.queryDatabases(
							"SELECT * FROM root r WHERE r.id='" + DATABASE_ID
									+ "'", null).getQueryIterable().toList();

			if (databaseList.size() > 0) {
				// Cache the database object so we won't have to query for it
				// later to retrieve the selfLink.
				databaseCache = databaseList.get(0);
			} else {
				// Create the database if it doesn't exist.
				try {
					Database databaseDefinition = new Database();
					databaseDefinition.setId(DATABASE_ID);

					databaseCache = documentClient.createDatabase(
							databaseDefinition, null).getResource();
				} catch (DocumentClientException e) {
					// TODO:
					e.printStackTrace();
				}
			}
		}

		return databaseCache;
	}

	private DocumentCollection getTestCollection() {
		if (collectionCache == null) {
			// Get the collection if it exists.
			List<DocumentCollection> collectionList = documentClient
					.queryCollections(
							getTestDBDatabase().getSelfLink(),
							"SELECT * FROM root r WHERE r.id='" + COLLECTION_ID
									+ "'", null).getQueryIterable().toList();

			if (collectionList.size() > 0) {
				// Cache the collection object so we won't have to query for it
				// later to retrieve the selfLink.
				collectionCache = collectionList.get(0);
			} else {
				// Create the collection if it doesn't exist.
				try {
					DocumentCollection collectionDefinition = new DocumentCollection();
					collectionDefinition.setId(COLLECTION_ID);

					// Configure the new collection performance tier to S1.
					RequestOptions requestOptions = new RequestOptions();
					requestOptions.setOfferType("S1");

					collectionCache = documentClient.createCollection(
							getTestDBDatabase().getSelfLink(),
							collectionDefinition, requestOptions).getResource();
				} catch (DocumentClientException e) {
					// TODO:
					e.printStackTrace();
				}
			}
		}

		return collectionCache;
	}
}
package com.mydomain.model;

public class Person {
	int age;
	String name;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Person == false)
			return false;

		Person p = (Person) obj;
		boolean isAgeSame = age == p.getAge();
		boolean isNameSame = name == null ? p.getName() == null : //
				name.equals(p.getName());
		return isAgeSame && isNameSame;
	}
}

上記を実行すると、以下のエラーが発生する。

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "_attachments" (Class com.mydomain.model.Person), not marked as ignorable
 at [Source: java.io.StringReader@1bb5a082; line: 1, column: 18] (through reference chain: com.mydomain.model.Person["_attachments"])
	at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
	at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:246)
	at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:604)
	at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:590)
	at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:689)
	at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:514)
	at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2395)
	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1595)
	at com.mydomain.documentdb.SampleTest.readTest01(SampleTest.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	(中略)


不明なフィールドである _attachments が存在する様だ。念のためやり取りされる JSON データを見ると以下の様に複数のフィールドが追加されている。

{_attachments=attachments/, _rid=i-ZOANFBawACAAAAAAAAAA==, name=割と普通, id=1, _self=dbs/i-ZOAA==/colls/i-ZOANFBawA=/docs/i-ZOANFBawACAAAAAAAAAA==/, age=45, _etag="00001000-0000-0000-0000-5560769f0000", _ts=1432385183}

こちらの問題に対応するには以下の様に jackson 特有のアノテーションを追加して不明なプロパティの無視を指定する。

package com.mydomain.model;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
	int age;
	String name;

	//(中略)


読み込みの場合は上記で良いのだが、書き込みの場合(特に更新)では今回無視したフィールドが必要なことが懸念される。こちらに対する調査はまた後日で。

Maven でコンパイルするとラムダ式使えないと怒られる件

JDK 1.8 が出てだいぶ経つので、各位もラムダ式を使っていることだと思う。今回はラムダ式を利用したモジュールで Maven コンパイルを実施する場合の軽い TIPS を紹介する。ご存じな方はご存じだと思うが、毎度 pom.xml に記載用の情報を検索するのも面倒なので以下に記載しておきたい。

ハマるポイントとして、ラムダ式を利用したソースで "mvn compile" 等を実行した場合に以下のエラーが発生する点だ。

D:\opt\workspace\Java8CodingProject>mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Java8CondigProject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
<中略>
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /D:/opt/workspace/Java8CodingProject/src/test/java/com/mydomain/lambda/SampleTest.java:[18,33] ラムダ式は-source 1.5でサポートされていません  (ラムダ式を使用可能にするには、-source 8以上を使用してください)
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.798 s
[INFO] Finished at: 2015-05-23T16:58:51+09:00
[INFO] Final Memory: 10M/491M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.
1:testCompile (default-testCompile) on project Java8CondigProject: Compilation failure
[ERROR] /D:/opt/workspace/Java8CodingProject/src/test/java/com/mydomain/lambda/SampleTest.java:[18,33] ラムダ式は-source 1.5でサポートされていません
[ERROR] (ラムダ式を使用可能にするには、-source 8以上を使用してください)
[ERROR] -> [Help 1]

上記のエラーを見れば一目瞭然だが、Maven さん(使っているのは 3.2.5 )は JDK 1.5 ベースでコンパイルしているらしい(流石に古すぎだろうと思うが)。。。。


解決方法は以下の様に pom.xml に追記すればよい。

<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.mydomain</groupId>
	<artifactId>Java8CondigProject</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
	</properties>
	<dependencies>
		<dependency>
        (中略)

次回以降は 1.8 ベースでのコンパイルが実行される。

Windows Azure Storage Emulator のインストールに失敗する場合の TIPS

Web Platform Installer 等を利用して Azure SDK のセットアップをする際、Windows Azure Storage Emulator のインストールに失敗することがある。今回はこちらを解決するかもしれない TIPS を紹介する。今回の作業による影響範囲は見切っていないので、実施は自己責任でお願いしたい

概要

Web Platform Installer 等を利用してインストールに失敗した場合、エラーダイアログからログを閲覧することができる。インストールの失敗ログを開き、以下のエラーが存在しているかを確認する。

<中略>
Action start 11:02:11: InstallFinalize.
CAQuietExec:  Windows Azure Storage Emulator 3.4.0.0 command line tool
CAQuietExec:  Error: Cannot create database.
CAQuietExec:  Error 0xfffffff3: Command line returned an error.
CAQuietExec:  Error 0xfffffff3: CAQuietExec Failed
CustomAction RunInitialize returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 11:02:12: InstallFinalize. Return value 3.
Action ended 11:02:12: INSTALL. Return value 3.
Property(S): UpgradeCode = {CF5CD495-AEDE-42DA-B7CF-A70D398D4E6A}
<中略>

上記を見ると、どうやらデータベースを作成できないらしい。ご存知の方もいるかもしれないが、Azure のエミュレータはローカルにデータベースを持つので、そちらが再作成がうまくいっていないようだ。
こちらのエラーで検索すると MSDN フォーラムで "CAQuietExec: Error: Cannot create database." の記事を見つけた。いろいろと議論がある様だが、ポイントは以下だ。

Hi,

That may not be sufficient.

As far as I'm concerned, my first install attemp left some files in my c:\users\[user] directory :

WAStorageEmulatorDb30.mdf
WAStorageEmulatorDb30_log.ldf

The sqllocaldb logs would mention these files still existed and it would not erase them.

I just deleted them manually.
Recreated the v11.0 (without the double quotes, please):

sqllocaldb stop v11.0
sqllocaldb delete v11.0
sqllocaldb create v11.0

私の場合は C:\users\[user directory] に以下のファイルが存在したので、すべて削除(別フォルダに移動)した。

  • WAStorageEmulatorDb33.mdf
  • WAStorageEmulatorDb33_log.ldf
  • WAStorageEmulatorDb34.mdf
  • WAStorageEmulatorDb34_log.ldf

次にコマンドラインを開き(管理者権限は不要)、以下のコマンドを実行した。

sqllocaldb stop v11.0
sqllocaldb delete v11.0
sqllocaldb create v11.0

後は再度 Azure SDK のインストールを実行すれば問題なくインストールが完了すると思われる。

Azure Redis Cache を Java で利用する

Azure Redis Cache が日本でも利用可能になってしばらくたつが、確認のために Java から疎通を取ったので簡単にメモ。

使うまでの手順

Azure の新ポータル側 https://portal.azure.com にアクセスし、Data + Storage から Redis Cache を選択する。
f:id:waritohutsu:20150321191729j:plain

次に設定からアクセスポートを選択し「SSL によるアクセスのみ許可する」で「いいえ」を選択する。これは Redis の Java クライアントである Jedis が SSL 接続をサポートしていないためだ。
f:id:waritohutsu:20150321192134j:plain

管理ポータルの設定は以上なので、次は Java プロジェクトを作成し、pom.xml に以下を追記して Jedis の依存関係を解決する。

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.6.2</version>
        </dependency>

以下のコードを利用して Azure Redis Cache を利用できる。

package com.domain.redisclientproject;

import redis.clients.jedis.Jedis;

public class Main {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("<site name>.redis.cache.windows.net", 6379);
        jedis.auth("<管理ポータルから取得できるキー>");
        jedis.set("foo", "bar");
        String value = jedis.get("foo");
        System.out.println(value);
    }
}

疎通までとなるが、上記の様に簡単に利用することができるのが分かる。

Application Insight の Java モジュールの拡張ポイントを弄ってみる

前回の記事で Java アプリケーション向けに Application Insight を動作させる方法を紹介したが、こちらに対してイベント処理を追加することができる。拡張に利用することのできるクラスは以下の二つだ。

  • applicationinsights-core-0.9.1.jar に含まれる TelemetryModule.java
  • applicationinsights-web-0.9.1.jar に含まれる WebTelemetryModule.java

拡張ポイントについて

TelemetryModule.java と WebTelemetryModule.java はそれぞれインターフェースであり、コードは以下になる。

package com.microsoft.applicationinsights.extensibility;
import com.microsoft.applicationinsights.TelemetryConfiguration;
public abstract interface TelemetryModule
{
  public abstract void initialize(TelemetryConfiguration paramTelemetryConfiguration);
}
package com.microsoft.applicationinsights.web.extensibility.modules;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public abstract interface WebTelemetryModule
{
  public abstract void onBeginRequest(ServletRequest paramServletRequest, ServletResponse paramServletResponse);
  
  public abstract void onEndRequest(ServletRequest paramServletRequest, ServletResponse paramServletResponse);
}

眺めて頂けば察しがつくと思うが、モジュール初期化時、リクエスト前後で処理が追加できることが分かる。

拡張コードと設定

以下のクラスを作成した。

package com.mydomain.applicationinsightmodule;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import com.microsoft.applicationinsights.TelemetryConfiguration;
import com.microsoft.applicationinsights.extensibility.TelemetryModule;
import com.microsoft.applicationinsights.web.extensibility.modules.WebTelemetryModule;

public class MyTelemetryModule implements WebTelemetryModule, TelemetryModule {

	@Override
	public void initialize(TelemetryConfiguration initializer) {
		System.out.println("@@@@InstrumentationKey="
				+ initializer.getInstrumentationKey());
	}

	@Override
	public void onBeginRequest(ServletRequest paramServletRequest,
			ServletResponse paramServletResponse) {
		System.out
				.println("@@@@onBeginRequest at " + this.getClass().getName());
	}

	@Override
	public void onEndRequest(ServletRequest paramServletRequest,
			ServletResponse paramServletResponse) {
		System.out.println("@@@@onEndRequest at " + this.getClass().getName());
	}

}

さらに ApplicationInsights.xml に設定を追記した。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<ApplicationInsights
	xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings"
	schemaVersion="2014-05-30">
	<InstrumentationKey><自分のキー>
	</InstrumentationKey>
	<ContextInitializers>
	</ContextInitializers>
	<TelemetryInitializers>
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationIdTelemetryInitializer" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationNameTelemetryInitializer" />
	</TelemetryInitializers>
	<TelemetryModules>
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebSessionTrackingTelemetryModule" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebUserTrackingTelemetryModule" />
		<Add type="com.mydomain.applicationinsightmodule.MyTelemetryModule" />
	</TelemetryModules>
	<Channel>
		<!-- Setting DeveloperMode to true will enable immediate transmission of 
			the telemetry events, which can be helpful during the development process. 
			Make sure to turn this off on production servers due to performance considerations. -->
		<DeveloperMode>false</DeveloperMode>
	</Channel>
	<DisableTelemetry>false</DisableTelemetry>
</ApplicationInsights>

拡張が完了したので、Java Web アプリケーションを起動すると以下の様にログが出力されていることが確認できる(ホントは slf4j とか使った方がいいのは置いといて)。

情報: Starting Servlet Engine: Apache Tomcat/8.0.9
3 15, 2015 12:47:44 午後 org.apache.jasper.servlet.TldScanner scanJars
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
@@@@InstrumentationKey=<自分のキー>
3 15, 2015 12:47:44 午後 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["http-nio-8080"]
3 15, 2015 12:47:44 午後 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["ajp-nio-8009"]
3 15, 2015 12:47:44 午後 org.apache.catalina.startup.Catalina start
情報: Server startup in 1987 ms
@@@@onBeginRequest at com.mydomain.applicationinsightmodule.MyTelemetryModule
@@@@onEndRequest at com.mydomain.applicationinsightmodule.MyTelemetryModule
@@@@onBeginRequest at com.mydomain.applicationinsightmodule.MyTelemetryModule
@@@@onEndRequest at com.mydomain.applicationinsightmodule.MyTelemetryModule

Application Insight を Java アプリケーションから利用する

アプリケーションのモニタリングやアラートを設定することが可能な Application InsightsJava からも利用可能になったのでさっそく試してみた。

利用するまでの流れ

まずは以下の様に Eclipse Plugin の Application Insight 機能をインストールする。
f:id:waritohutsu:20150315121832p:plain

次に、以下の様に Azure の新管理ポータルで Application Insight を新規に作成した後、setting - プロパティ から Instrumentation Key を取得する。
f:id:waritohutsu:20150315122236p:plain

次は Eclipse 上から Dynamic Java Web アプリケーションを作成し、右クリックメニューから Configure Application Insight を選択して Application Insight有効化する。この際、Instrumentation Key を求められるので管理ポータルから取得しておくのを忘れないこと。
f:id:waritohutsu:20150315122513p:plain

Application Insight 有効化すると、web.xml に以下の記載が追加されている。以下を見ると単なるサーブレットフィルタなので、Websites 等に配置せずとも動くことが推察できる。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>

	<filter>
		<filter-name>ApplicationInsightsWebFilter</filter-name>
		<filter-class>com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ApplicationInsightsWebFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

更にソースフォルダに ApplicationInsights.xml が配置されており、以下の記載がされている。こちらで Application Insight を構成する情報が設定されていることが分かる(TelemetryInitializers タグにクラスを追加すると何かしてくれそうな気もする)。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<ApplicationInsights
	xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings"
	schemaVersion="2014-05-30">
	<InstrumentationKey><自分のキーが書いてある>
	</InstrumentationKey>
	<ContextInitializers>
	</ContextInitializers>
	<TelemetryInitializers>
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationIdTelemetryInitializer" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.initializers.WebOperationNameTelemetryInitializer" />
	</TelemetryInitializers>
	<TelemetryModules>
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebSessionTrackingTelemetryModule" />
		<Add
			type="com.microsoft.applicationinsights.web.extensibility.modules.WebUserTrackingTelemetryModule" />
	</TelemetryModules>
	<Channel>
		<!-- Setting DeveloperMode to true will enable immediate transmission of 
			the telemetry events, which can be helpful during the development process. 
			Make sure to turn this off on production servers due to performance considerations. -->
		<DeveloperMode>false</DeveloperMode>
	</Channel>
	<DisableTelemetry>false</DisableTelemetry>
</ApplicationInsights>

この時点でも動作はするが Application Insight のクイックスタートの画面から以下の JavaScript が取得できるので、こちらを JSP 画面 or JSF 画面等の監視をしたいページに張り付ける。

<!--
ご使用のアプリケーションに関するエンド ユーザー利用状況分析を収集するには、
追跡するページごとに以下のスクリプトを挿入してください。
このコードを、</head> 終了タグの直前に、
他のスクリプトより前の位置に配置します。最初のデータは、数秒後に
自動的に表示されます。
-->
<script type="text/javascript">
    var appInsights=window.appInsights||function(config){
        function s(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},r=document,f=window,e="script",o=r.createElement(e),i,u;for(o.src=config.url||"//az416426.vo.msecnd.net/scripts/a/ai.0.js",r.getElementsByTagName(e)[0].parentNode.appendChild(o),t.cookie=r.cookie,t.queue=[],i=["Event","Exception","Metric","PageView","Trace"];i.length;)s("track"+i.pop());return config.disableExceptionTracking||(i="onerror",s("_"+i),u=f[i],f[i]=function(config,r,f,e,o){var s=u&&u(config,r,f,e,o);return s!==!0&&t["_"+i](config,r,f,e,o),s}),t
    }({
        instrumentationKey:"<自分のキーを利用する>"
    });
    
    window.appInsights=appInsights;
    appInsights.trackPageView();
</script>

上記を利用してローカル等で Tomcat を起動して動作を確認すると、無事情報が取得できていることが分かる。
f:id:waritohutsu:20150315123649p:plain