5. 旧バージョンとの互換性

5.1. WebOTX V8とV9の非互換項目

5.1.1. Webアプリケーションのリロード

Webアプリケーションのリロードは手動で行います。 [ Tomcatからの移行 > Tomcatとの対比 > 設定項目 > Tomcat設定項目との対応 > コンテキスト(共通) - reloadable ] を参照ください。

5.1.2. Webアプリケーションの配備ディレクトリ

Webアプリケーションの配備先は以下のディレクトリに変更になりました。
V8: ${INSTANCE_ROOT}/applications/j2ee-modules/{アプリケーション名}
                           
V9: ${INSTANCE_ROOT}/applications/{アプリケーション名}

5.1.3. HTTPリスナに対する設定(maxParameterCountの例)

V8: otxadmin> set server.http-service.http-listener.agent-ajp-listener.property.maxParameterCount=500
         
V9: otxadmin> set server.network-config.network-listeners.network-listener.ajp-listener-1.property.maxParameterCount=500

5.1.4. virtual-serverで使用するリスナを列挙する属性

V8: server.http-service.virtual-server.<virtual-server-name>.http-listeners
         
V9: server.http-service.virtual-server.<virtual-server-name>.network-listeners

5.1.5. 利用するコネクタの指定

V8:JavaVMのシステムプロパティに以下を設定
 -Dcom.nec.webotx.enterprise.web.connector.useCoyoteConnector=(true | false)

設定値 説明
true BIO(既定値)
false Grizzly NIO

V9: otxadmin> set server.network-config.protocols.protocol.<protocol名>.type=(ajp | grizzly | nio | bio)

type 説明
grizzly Grizzly NIOコネクタ(既定値)
ajp Webサーバ連携コネクタ
nio NIOコネクタ
bio BIOコネクタ

5.1.6. 統計情報採取の設定

V8: otxadmin> set server.monitoring-service.module-monitoring-levels.web-container=(ON | OFF)

設定値 説明
ON 採取する
OFF 採取しない

V9: otxadmin> set server.monitoring-service.module-monitoring-levels.web-container=(HIGH | OFF)

設定値 説明
HIGH 採取する
OFF 採取しない

5.1.7. セッションオブジェクトの属性の管理オプションの既定値

システムプロパティ:org.apache.catalina.session.useConcurrentHashMap

V8:  既定値: false(低メモリ消費優先)
         
V9:  既定値: true(排他処理性能優先)

5.1.8. リスナスレッド数

最大リスナスレッド数
V8: server.http-service.http-listener.<リスナID>.max-processors
         
V9: server.thread-pools.thread-pool.<スレッドプール名>.max-thread-pool-size

最小リスナスレッド数
V8: server.http-service.http-listener.<リスナID>.min-processors
         
V9: server.thread-pools.thread-pool.<スレッドプール名>.min-thread-pool-size

スレッド数警告のしきい値
V8: server.http-service.http-listener.<リスナID>.limit-processors
         
V9: server.thread-pools.thread-pool.<スレッドプール名>.limit-thread-pool-size

5.1.9. cross-contextの既定値

Dottedname :server.applications.web-module.<Webアプリケーション名>.cross-context

V8:  既定値: false(クロスコンテキスト不許可)
         
V9:  既定値: true(クロスコンテキスト許可)

5.1.10. welcome-fileの仮想パス対応

V8: servlet-mappingのurl-patternに"*.do"を設定してwelcome-fileにindex.doを設定している場合、ディレクトリにアクセスしたとき、404エラーを表示する。

V9: servlet-mappingのurl-patternに"*.do"を設定してwelcome-fileにindex.doを設定している場合、ディレクトリにアクセスしたとき、*.doにマッピングされたservletを実行する。

※V9では、strutsやjsfで使用されるindex.doやindex.jsf等の物理的に存在しないパス名を welcome-fileに指定して利用する事が出来るようになりました。
※V8と同様の表示をさせるには、 [ Tomcatからの移行 > Tomcatとの対比 > 設定項目 > Tomcat設定項目との対応 > コンテキスト(共通) - resourceOnlyServlets ] オプションで、url-patternに対応付いたservlet-nameを指定します。

5.1.11. HTTPリクエストヘッダの最大サイズの指定オプション

V8:  server.http-service.http-listener.<リスナID>.property.maxHttpHeaderSize
         
V9:  server.network-config.protocols.protocol.<プロトコル名>.http.header-buffer-length-bytes

5.1.12. jsp事前コンパイルの対応taglib定義バージョン

jspプリコンパイルでサポートする web.xmlのtaglib定義仕様はweb-app2.4以降の仕様(<web-app> - <jsp-config> - <taglib>)に変更しました。

※web.xmlの<taglib>の定義位置の仕様
・web-app2.3以前

<web-app> - <taglib>

・web-app2.4以降

<web-app> - <jsp-config> - <taglib>

そのため以下のどちらかの対応が必要です。
(a) 配備時のjspプリコンパイルオプションを外す。

(b) web.xmlのtaglib要素をweb-app2.4以降に準拠して定義する。

(1) web.xmlのバージョンをweb-app2.4に変更します

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2eeweb-app_2_4.xsd" version="2.4">

(2) taglib要素をjsp-config要素内に入れます

<jsp-config>←追加
    …
    <taglib>
        <taglib-uri>/tags/xxx</taglib-uri>
        <taglib-location>/WEB-INF/xxx.tld</taglib-location>
    </taglib>
    …
</jsp-config>←追加

5.1.13. コンテナの FORM URL パラメタ構文解析で扱う POST の最大バイト数

V8:  server.http-service.http-listener.<リスナ名>.property.maxPostSize
         
V9:  server.network-config.protocols.protocol.<プロトコル名>.http.max-post-size-bytes

5.1.14. *.tldファイルが不正な場所に存在する場合のチェックを強化

/WEB-INF/tags 配下にimplicit.tld 以外の*.tldファイルを配置した場合は、アプリケーションのロード時にエラーとなるようWebOTX V9から実装仕様を変更しました。
これはJSP2.1仕様で変更された「JSP.7.3.1 Identifying Tag Library Descriptors Tag」の仕様によるものです。
回避するにはアプリケーション側で、/WEB-INF/tags 配下にある implicit.tld 以外の*.tldファイルを、 /WEB-INF/tags以外の /WEB-INF 配下(/WEB-INF/classes, /WEB-INF/libは推奨しません)に移動するか 以下の設定を行ってください。

JVMシステムプロパティ
-Dcom.nec.webotx.webcontainer.jsp.TldInTags=true

5.1.15. クライアントへの書込みタイムアウト設定

内蔵Webサーバ(V8はbioコネクタ、V9はgrizzlyコネクタ)を使用している場合、クライアントへの書込みタイムアウト(*1)値の設定箇所が異なります。

(*1) タイムアウトの例)
Windowsでファイルをダウンロードする際、ファイルの保存場所を指定するダイアログを開いたまま放置し、いざダウンロードを開始した時、ダイアログを開いてから一定時間が経過していると、書込みタイムアウトが発生し、ダウンロードは失敗、頭のデータしか無いファイルが出来上がる。

書込みタイムアウトの時間を変更するには次の値を更新します。単位はそれぞれミリ秒です。
V8:bioコネクタを使用してる場合
  server.http-service.http-listener.http-listener-1.connection-timeout
V9:内蔵Webサーバ(grizzlyコネクタ)を使用している場合
  -Dcom.nec.webotx.grizzly.writeTimeout
   ※JVMオプションを設定します。既定値は30000(ミリ秒)で、設定値の3倍の値(90秒)でタイムアウトします。
V9:内蔵Webサーバ(grizzlyコネクタ以外)を使用している場合
  server.network-config.protocols.protocol.http-listener.http.connection-timeout

5.2. WebOTX V9とV10の非互換項目

5.2.1. Webコンテナの動作モード廃止

ドメイン作成時に選択が必要であったWebコンテナの動作モード「スタンダードモード」と「アドバンスドモード」は無くなりました。

V10では、配備する際にアプリケーショングループ名とプロセスグループ名を指定する事でアプリケーションはプロセスグループ上で動作します(V9における「アドバンスドモード」相当)。指定しなければエージェントプロセス上で動作します(V9における「スタンダードモード」)。

5.2.2. コネクタ種別の変更

V9では、外部Webサーバ連携用と内蔵Webサーバ用含めて「grizzly」「ajp」「nio」「bio」がありましたが、V10では「grizzly」と「bio」が廃止となり「apr」と「tpm」が追加になりました。

V9: otxadmin> set server.network-config.protocols.protocol.<protocol名>.type=(ajp | grizzly | nio | bio)

type 説明
grizzly Grizzly NIOコネクタ(既定値)
ajp Webサーバ連携コネクタ
nio NIOコネクタ
bio BIOコネクタ

V10: otxadmin> set server.network-config.protocols.protocol.<protocol名>.type=(ajp | tpm | nio | apr)

type 説明
ajp Webサーバ連携コネクタ(エージェントプロセス)
tpm Webサーバ連携コネクタ(プロセスグループ)
nio NIOコネクタ(既定値)
apr APRコネクタ

5.2.3. HTTPリスナに対する設定(maxParameterCountの例)

V9: otxadmin> set server.network-config.network-listeners.network-listener.ajp-listener-1.property.maxParameterCount=500
         
V10: otxadmin> set server.network-config.network-listeners.network-listener.agent-ajp-listener.property.maxParameterCount=500

5.2.4. 外部Webサーバ連携用ツールの名称と動作の変更

V9では、外部Webサーバと連携する場合に「環境設定ツール」を利用し設定を行っていました。V10では、このツールの名称が「初期設定ツール」に変更となっています。

また、V9ではIISと連携する場合に環境設定ツールで設定後、「IIS6 メタベース互換のインストール」など手動でIISの設定を行う必要がありましたが、V10では初期設定ツールが自動で行うようになりました。

5.2.5. 動的反映機能の動作の変更

V9における「動的反映機能」は、リクエスト処理の延長でドメインへの問い合わせを実施していましたが、V10では、リクエストとは別スレッドでドメインへの問い合わせを実施するようになりました。

また、動的反映機能を手動でOFF(無効)にする場合、V9では「ajp13_original」というキーワードを ${INSTANCE_ROOT}/config/WebCont/workers.properties に記述していましたが、V10ではこれが変更となりました。

5.2.6. IIOP接続の廃止

V9のアドバンスドモードにあった「IIOP」による接続は V10では無くなりました。V10でアプリケーションをプロセスグループに配備した場合、外部Webサーバとの接続は「AJP」に固定となります。

これに伴い、V9に存在した AJP と IIOP の切り替え機能も廃止となります。

5.2.7. クラスローダのオーバーライドプロパティ名称変更

アプリケーションレベルのクラスローダは、既定の設定では"javax"などで始まるパッケージをロードできません。 指定するパッケージをロードできるようにするプロパティ(あるいはJVMオプション)がありますが、 そのプロパティ名称が"overrideablejavaxpackage"と直感的に判別しにくいため、 V10では判別しやすい名称の別プロパティを追加しました。

ただし、V9に存在したプロパティ"overrideablejavaxpackage"も使用可能です。

5.2.8. Cometの移行

TomcatやGrizzlyのCometを使用している場合は、今後のAPIの互換性が保障されるServlet 3.0を使用したCometに移行してください。
移行の方法を以下に説明します。

5.2.8.1. Tomcat CometからServlet API3.0 Cometへの移行
1クライアントが送信したメッセージを接続済みの全クライアントにレスポンスするチャットの様なアプリケーションを、 Tomcat CometからServlet 3.0 Cometに移行する場合を想定して移行方法を説明します。
移行ポイント Tomcat Comet Servlet3.0 の非同期APIへの移行
サーブレットクラス定義 Tomcat Cometはorg.apache.catalina.comet.CometProcessorをimplementsしています。 普通のServletと同じくHttpServletを継承し、CometProcessorのimplementsは削除します。

public class XXXServlet extends HttpServlet

次のいずれかを設定する必要があります
□@WebServlet に asyncSupported=true を指定。
例えば「@WebServlet(urlPatterns = {"/chat"}, asyncSupported = true)」

□web.xmlの<servlet> 要素の下に「<async-supported>true</async-supported>」を追加。
メッセージキュー メッセージキュー(1クライアントがリクエストしたデータをその他の非同期コンテキストに通知するためのキュー) を使用している場合はServlet3.0 Cometではそのまま流用可能です。
 
Tomcat Cometでメッセージキューを使用している場合はそのまま流用してください。
メッセージキューの実装例です。
BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    Runnable notifierRunnable = new Runnable() {
        public void run() {
            try{
                while(true){ 
                    String cMessage = messageQueue.take();
                    for (AsyncContext ac : queue) {
                        try {
                            PrintWriter acWriter = ac.getResponse().getWriter();
                            acWriter.println(cMessage);
                            acWriter.flush();
                        } catch(IOException ex) {
                            queue.remove(ac);
                        }
                    }
                }
            }catch(InterruptedException e){
                log("messageQueue take error", e);
            }
        }
    };
    notifierThread = new Thread(notifierRunnable);
    notifierThread.start();
}

コネクションキュー コネクション(HttpServletResponseやPrintWriter等)のキューを管理している場合は、Servlet3.0では代わりにAsyncContextをキューで管理します。 HttpServletRequestのstartAsync()を実行した戻り値の AsyncContextをキューに登録します。
AsyncContext ac = request.startAsync();
this.queue.add(ac);
Timeout時間 TomcatではCometEventのsetTimeout()でタイムアウト時間を設定しています。
public void event(CometEvent event) throws IOException, ServletException {
    …
    if (event.getEventType() == CometEvent.EventType.BEGIN) {
    	event.setTimeout(30 * 60 * 1000); // 30分
Servlet3.0ではAsyncContextのsetTimeout()でタイムアウト時間を設定します
AsyncContext ac = request.startAsync();
ac.setTimeout(30 * 60 * 1000); // 30分
エラーコネクションの削除 Tomcat Cometで eventメソッドでのイベントがCometEvent.EventType.ERRORの場合やCometEvent.EventType.ENDの場合にコネクションを キューから削除している例です。
public void event(CometEvent event) throws IOException, ServletException {
  …
    } else if (event.getEventType() == CometEvent.EventType.ERROR) {
        synchronized (queue) {
            queue.remove(response);
        }
        event.close();
    } else if (event.getEventType() == CometEvent.EventType.END) {
        synchronized (queue) {
            queue.remove(response);
        }
        event.close();
    }
AsyncContext取得後にAsyncContextにAsyncListenerの実装をaddListener()します。
AsyncContext ac = request.startAsync();
ac.addListener(new AsyncListenerImpl());

Servlet3.0ではAsyncContextに登録するAsyncListenerの実装内のonError()とonTimeout()でコネクションをキューから削除します
class AsyncListenerImpl extends Thread implements AsyncListener{
  …
    @Override
    public void onError(AsyncEvent ae) throws IOException {
        synchronized (queue) {
            queue.remove(ae.getAsyncContext());
        }
    }

    @Override
    public void onTimeout(AsyncEvent ae) throws IOException {
        synchronized (queue) {
            queue.remove(ae.getAsyncContext());
        }
    }
}
init メソッド 色々な初期化処理が記述されていると思います。
以下は、メッセージキューを使うために、通知者用スレッドを開始している例です。
Runnable notifierRunnable = new Runnable() {
public void run() { 
  ... 
  while(true){ 
    cMessage = messageQueue.take(); 
    for (HttpServletResponse res : queue) { 
        try { 
            PrintWriter acWriter = res.getWriter(); 
            acWriter.println(cMessage); 
            acWriter.flush(); 
        } catch(IOException ex) { 
            queue.remove(ac); 
      ... 
    }
  }
}; 
notifierThread = new Thread(notifierRunnable); 
notifierThread.start();
initで行っている処理はそのまま移植します。
コネクションキューから取得されるコネクション情報はAsyncContextに変更します。

Runnable notifierRunnable = new Runnable() { 
public void run() { 
  ... 
  while(true){ 
    cMessage = messageQueue.take(); 
    for (AsyncContext ac : queue) { 
        try { 
            PrintWriter acWriter = ac.getResponse().getWriter(); 
            acWriter.println(cMessage); 
            acWriter.flush(); 
        } catch(IOException ex) { 
            queue.remove(ac); 
    ...
    }
  }
}; 
notifierThread = new Thread(notifierRunnable); 
notifierThread.start();
eventメソッド Tomcat Cometのイベントが発生した場合の処理が記述されています。
Servlet3.0では下記の対応を行います。
CometEvent<wbr>.EventType<wbr>.BEGIN eventメソッドでイベントタイプがCometEvent.EventType.BEGIN の場合の処理です。
if (event.getEventType() == CometEvent.EventType.BEGIN) {
    …
}
doGetメソッドやdoPostメソッドで処理を行います。
CometEvent<wbr>.EventType<wbr>.READ eventメソッドでイベントタイプがCometEvent.EventType.READ の場合の処理です。
if (event.getEventType() == CometEvent.EventType.READ) {
    …
}
doGetメソッドやdoPostメソッドでServletRequestの getInputStream()を使って ServletInputStreamを取得します。
CometEvent<wbr>.EventType<wbr>.ERROR eventメソッドでイベントタイプがCometEvent.EventType.ERROR の場合の処理です。
if (event.getEventType() == CometEvent.EventType.ERROR) {
    …
}
javax.servlet.AsyncListener を実装したクラスの onErrorメソッドに処理を記述します。
class AsyncListenerImpl extends Thread implements AsyncListener{
    …
    public void onError(AsyncEvent event) throws IOException {
        …
    }
}
CometEvent<wbr>.EventSubType<wbr>.TIMEOUT eventメソッドでイベントタイプがCometEvent.EventSubType.TIMEOUT の場合の処理です。
if (event.getEventSubType() == CometEvent.EventSubType.TIMEOUT) {
    …
}
javax.servlet.AsyncListener を実装したクラスの onTimeoutメソッドに処理を記述します。
class AsyncListenerImpl extends Thread implements AsyncListener{
    …
    public void onTimeout(AsyncEvent event) throws IOException {
        …
    }
}
doGet/doPost メソッド Tomcat Cometでは使用しません。 Tomcat Cometでイベントが CometEvent.EventType.BEGIN の場合に行っている処理をここで実装します。
実装される処理には以下の様なものがあります。 ・AsyncContextを生成します。
・タイムアウト時間を設定します。
・AsyncListenerを生成してAsyncContextに追加します。
・AsyncContextをキューに追加します。

final AsyncContext ac = req.startAsync();
ac.setTimeout(10 * 60 * 1000); 
ac.addListener(new AsyncListener() { 
    ... 
}; 
queue.add(ac);
destroy メソッド 以下の様な色々な後処理が実装されていると思います。
・キューのクリア。
・通知者スレッドの中止。

queue.clear();
notifierThread.interrupt();
Tomcat Cometからそのまま移植します。
5.2.8.2. Grizzly CometからServlet API3.0 Cometへの移行
1クライアントが送信したメッセージを接続済みの全クライアントにレスポンスするチャットの様なアプリケーションを、 Grizzly CometからServlet 3.0 Cometに移行する場合を想定して移行方法を説明します。
移行ポイント Grizzly Comet Servlet3.0 の非同期APIへの移行
サーブレットクラス定義 普通のServletと同じくHttpServletを継承しています。

public class XXXServlet extends HttpServlet
サーブレットクラスの継承はそのまま変えません。
public class XXXServlet extends HttpServlet

次のいずれかを設定する必要があります
□@WebServlet に asyncSupportedを指定。
例えば「@WebServlet(urlPatterns = {"/chat"}, asyncSupported = true)」

□web.xmlの<servlet> の下に「<async-supported>true</async-supported>」を追加。
メッセージキュー CometContextのnotify()の引数にメッセージを渡す事でGrizzlyが管理しているメッセージキューにメッセージを登録している例です。

CometContext cometContext = CometEngine.getEngine().getCometContext(this.contextPath);
cometContext.notify("[" + user + "]: " + message);
メッセージキューは独自に実装します。
メッセージキューの実装例です。
BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    Runnable notifierRunnable = new Runnable() {
        public void run() {
            try{
                while(true){ 
                    String cMessage = messageQueue.take();
                    for (AsyncContext ac : queue) {
                        try {
                            PrintWriter acWriter = ac.getResponse().getWriter();
                            acWriter.println(cMessage);
                            acWriter.flush();
                        } catch(IOException ex) {
                            queue.remove(ac);
                        }
                    }
                }
            }catch(InterruptedException e){
                log("messageQueue take error", e);
            }
        }
    };
    notifierThread = new Thread(notifierRunnable);
    notifierThread.start();
}

コネクションキュー HttpServletResponse等にアタッチするためのCometHandlerを実装したクラスをCometContextに登録する事で、コネクションキューが管理されています。

CometHandlerImpl handler = new CometHandlerImpl();
handler.attach(response);
CometContext cometContext = CometEngine.getEngine().getCometContext(this.contextPath);
cometContext.addCometHandler(handler);
下記の例ではHttpServletResponseをアタッチしています。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
  private  HttpServletResponse response;

  …

  public void attach(HttpServletResponse response){
    this.response = response;
  }
  …
}
コネクションキューは独自に実装します。
HttpServletRequestのstartAsync()を実行した戻り値AsyncContextをコネクションキューに登録します。

Queue<AsyncContext> queue = new ConcurrentLinkedQueue<AsyncContext>();

…

AsyncContext ac = request.startAsync();
this.queue.add(ac);
Timeout時間 CometContextのsetExpirationDelay()を行います。
CometContext cometContext = CometEngine.getEngine().register(contextPath);
cometContext.setExpirationDelay(30 * 60 * 1000);
コネクションキューに登録する前にAsyncContextのsetTimeout()を行います。
AsyncContext ac = request.startAsync();
ac.setTimeout(30 * 60 * 1000);
エラーコネクションの削除 Grizzly内部で管理しています。 AsyncContext取得後にAsyncContextにAsyncListenerの実装をaddListener()します。
AsyncContext ac = request.startAsync();
ac.addListener(new AsyncListenerImpl());

AsyncListenerの実装のonError()とonTimeout()で、コネクションキューからAsyncContextを削除します。

class AsyncListenerImpl extends Thread implements AsyncListener{
  …
  @Override
  public void onError(AsyncEvent event) 
  throws IOException {
    queue.remove(event.getAsyncContext());
  }

  @Override
  public void onTimeout(AsyncEvent event) 
  throws IOException {
    queue.remove(event.getAsyncContext());
  }
}
init メソッド CometEngineにcontextPathを登録しています。
タイムアウト時間を設定しています。

contextPath = config.getServletContext().getContextPath() + "/chat"; 
CometContext context = CometEngine.getEngine().register(contextPath);
context.setExpirationDelay(5 * 60 * 1000);
メッセージキューからメッセージを使うために、メッセージ通知用スレッドをつくって、開始します。

Runnable notifierRunnable = new Runnable() {
  public void run() {
    try{
      while(true){
        String cMessage = messageQueue.take();
        for (AsyncContext ac : queue) {
          try {
            PrintWriter acWriter = ac.getResponse().getWriter();
            acWriter.println(cMessage);
            acWriter.flush();
          } catch(IOException ex) {
            queue.remove(ac);
          }
        }
      }
    }catch(InterruptedException e){
      log("messageQueue take error", e);
    }
  }
};
notifierThread = new Thread(notifierRunnable);
notifierThread.start();
イベントハンドラ CometHandlerを実装したクラスがイベントハンドラです。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
    ・・・

    public void onEvent(CometEvent event) 
    throws IOException{
        ・・・
    }
}
Sservlet3.0ではjavax.servlet.AsyncListener を実装したクラスがイベントハンドラです。
下記の対応を行います。
イベントハンドラ(onEvent) CometContextのnotify()を実行するとCometHandlerを実装したクラスのonEvent()がCometEvent.NOTIFYイベントで呼び出されます。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
    ・・・

    public void onEvent(CometEvent event) 
    throws IOException{
        if ( event.getType() == CometEvent.NOTIFY ){
            String text = (String)event.attachment();
            PrintWriter writer = this.response.getWriter();
            writer.println(text);
            writer.flush();
        }

    }
}
Sservlet3.0ではメッセージキューから値を取り出しコネクションキューにあるコネクションに対してレスポンスを送信する処理を独自に作成して実装します。
initメソッドの例を参考にしてください。
イベントハンドラ(onInitialize) onInitialize()はリクエスト受信時に呼び出されます。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
    ・・・
    
    public void onInitialize(CometEvent event) 
    throws IOException{
        this.response.setContentType("text/plain;charset=UTF-8");
        this.response.setCharacterEncoding("utf-8");

        PrintWriter writer = this.response.getWriter();
        writer.println("Welcome");
        writer.flush();
    }
}
Sservlet3.0ではdoGetメソッドやdoPostメソッドにて実装します。
イベントハンドラ(onTerminate) onTerminate()はCometEngineからコンテキストがunregister()される際に呼び出されます。
例ではコネクションのクローズを行っています。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
    ・・・

    public void onTerminate(CometEvent event) 
    throws IOException{
        this.response.getWriter().close();
        CometContext context = 
            CometEngine.getEngine().getCometContext(contextPath);
        context.removeCometHandler(this);
    }
}
特に実装はありません。
イベントハンドラ(onInterrupt) onInterrupt()はタイムアウト時やクライアントから接続が閉じられた場合に呼び出されます。
例ではコネクションのクローズを行っています。
public class CometHandlerImpl implements CometHandler<HttpServletResponse>{
    ・・・

    public void onInterrupt(CometEvent event) 
    throws IOException{
        this.response.getWriter().close();
        CometContext context = 
            CometEngine.getEngine().getCometContext(contextPath);
        context.removeCometHandler(this);
    }
}
AsyncListenerの実装クラスのonError()やonTimeout()でコネクションキューからAsyncContextを削除する処理を実装します。
class AsyncListenerImpl extends Thread implements AsyncListener{
    ・・・

    public void onError(AsyncEvent event) throws IOException {
        queue.remove(event.getAsyncContext());
    }

    public void onTimeout(AsyncEvent event) throws IOException {
        queue.remove(event.getAsyncContext());
    }
}
doGet/doPost メソッド ■メッセージレスポンス用リクエストの場合
HttpServletResponseをアタッチした CometHandler実装クラスをCometContextに追加しています。
ChatListnerHandler handler = new ChatListnerHandler(); 
handler.attach(response); 
CometContext cometContext = CometEngine.getEngine().getCometContext(contextPath);
cometContext.addCometHandler(handler)
■メッセージリクエスト用リクエストの場合
CometContextのnotify(message)を実行しています。
CometContext cometContext = CometEngine.getEngine().getCometContext(this.contextPath);
cometContext.notify(message);
■メッセージレスポンス用リクエストの場合
AsyncContext にAsyncListenerの実装クラスを追加してコネクションキューにAsyncContextを追加します。
final AsyncContext ac = req.startAsync();
AsyncListenerImpl listener = new AsyncListenerImpl();
ac.addListener(listener);
queue.add(ac);
■メッセージリクエスト用リクエストの場合
メッセージキューにメッセージを登録します。
this.messageQueue.add(message);
destroy メソッド - ・Grizzly Cometで実装があればそのまま移植します。
・コネクションキューをクリアしてメッセージ通知用スレッドを中止します。

queue.clear();
notifierThread.interrupt();

5.2.9. 暗号化方式 SSLv2 の廃止

SSL通信で使用する暗号化方式のうちSSLv2はV10からサポートしていません。SSLv2の設定は無視され他の暗号化方式でSSL通信が行われます。

5.2.10. Webアプリケーションのセキュリティ設定チェック強化

V10よりWebアプリケーションのセキュリティ設定のチェックが強化されています。詳細は注意事項を参照してください。

5.2.11. URLRewritingにおけるHTTPセッションのセッションID用クエリの名前変更

URLRewritingにおいて、クライアント(Webブラウザ)とWebOTX間でHTTPセッションのセッションIDを送受信する時に使用するURLに付与されるクエリの名前がV9とV10では次のように異なります。

 このため、V9で動作していたアプリケーションにクエリ名を大文字として扱う処理があった場合はセッションIDが取得できません。この場合、アプリケーションの処理を小文字で扱えるように修正するか、次の設定を行ってください。

[nec-web.xml]
<?xml version="1.0" encoding="UTF-8"?>
<nec-web-app>

  <session-config>
    <cookie-properties>
      <property name="cookieName" value="JSESSIONID"/>
    </cookie-properties>
  </session-config>

</nec-web-app>

次の点に注意してください。

5.2.12. JSFのFlashスコープで使用するCookieの値の変更

JSFでFlashスコープを利用している場合、"csfcfc"という名前の専用のCookieが生成されます。このCookieに設定される値がV10.2で{ヘッダ}を付与するよう拡張されたため、V10.1以前とは異なる値が設定されるようになりました。

 このため、V9でJSFかつFlashスコープを利用するアプリケーションが動作しており、そのアプリケーションを利用した事があるクライアント(Webブラウザ等)が、過去のCookieを削除しないかクライアントのプロセスを起動したままの状態でV10環境のアプリケーションにアクセスした場合、例外(ArrayIndexOutOfBoundsException)が発生します。
 対処として、クライアント(Webブラウザ)のプロセスを一度終了させてください。これによりFlashスコープ用のCookieが削除され、次回以降正常にアクセスできるようになります。

5.3. WebOTX V10とV11の非互換項目

5.3.1. JSF EnumConverter#getAsString()の仕様を変更

以下のメソッド引数の"value"の値がnullの場合の戻り値が変更になりました。

String javax.faces.convert.EnumConverter#getAsString(FacesContext context, UIComponent component, java.lang.Object value)

V10: null
V11: ""(長さが0の文字列)

V10と同じ動作をするには以下の設定を行ってください。
JVMシステムプロパティ
-Dcom.nec.webotx.javax.faces.convert.EnumConverter.nullValueReturnNull=true

5.4. 使用するポート番号

WebOTX V5、V6、V7、V8、V9、V10で使用するポート番号の一覧を下記に示します。

表2.7.3-1
WebOTX V5.x WebOTX V6.x WebOTX V7.x WebOTX V8.x WebOTX V9.x WebOTX V10.x
HTTP/1.1 8080 80 80 80 80 80
AJP/1.3 8009 8009 8009 8099 8099 8099
運用管理コンソール 8080 4848 4848 5858 5858 5858
HTTPS 8443 443 443 443 443 443
終了待ち受けポート 8005 - - - - -
運用管理ポート - 6202,6212 6202,6212 6202,6212 6202,6212 6202,6212

5.5. 同梱するライブラリ

WebOTXに同梱しているライブラリとバージョンは次の表のとおりです。

表2.2.4-1
名称 V5.3 V6.1 V6.22 V6.31 V6.4 V6.50.02 V7.11.08 V8.12 V8.2 V8.31 V8.4 V8.42 V9.1 V9.2 V9.3 V9.4 V10.1
Java Beans Activation Framework (JAF) - 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.0.2 1.1 1.1 1.1 1.1 1.1
JavaMail - 1.3.1 1.3.1 1.3.1 1.3.1 1.3.1 1.3.1 1.3.1 1.3.1 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.5
JAXP - 1.2.5 1.2.5 1.2.5 1.2.5 1.2.5 1.3.04 1.3.04 1.3.04 1.3.04 1.3.04 1.3.04 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Ant - 1.5.4 1.5.4 1.5.4 1.5.4 1.5.4 1.6.5 1.7.0 1.7.0 1.7.1 1.8.2 1.8.4 1.8.4 1.8.4 1.8.4 1.8.4 1.9.9
Jakarta Commons BeanUtiles (*1) - 1.6.1 1.6.1 1.7.0 1.7.0 1.7.0 1.7.0 1.7.0 1.7.0 1.8.0 1.8.0 1.8.0 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Codec (*1) - 1.2 1.3 1.3 1.3 1.3 1.3 1.3 1.3 1.3 1.4 1.4 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Collections (*1) - 2.11 2.11 2.11 2.11 2.11 2.11 2.11 2.11 2.11 2.11 2.11 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Digester (*1) - 1.5 1.6 1.7 1.7 1.8 1.8 1.8 1.8 1.8 1.8 1.8 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Discovery (*1) - 0.2 0.2 0.2 0.2 0.4 0.4 0.4 0.4 0.4 0.4 0.4 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons EL (*1) - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons FileUpload (*1) 1.0 1.0 1.0 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Launcher (*1) - 1.0-dev 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Logging (*1) 1.0.4 1.0.4 1.0.4 1.0.4 1.0.4 1.1 1.1 1.1.1 1.1 1.1 1.1.1 1.1.1 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Commons Modeler (*1) - 1.1 1.1 1.1 1.1 2.0 2.0 2.0 2.0 2.0 2.0 2.0 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Jakarta Regexp - 1.3 1.3 1.4 1.4 1.4 1.5 1.5 1.5 1.5 1.5 1.5 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし
Log4j - 1.2.8 1.2.8 1.2.13 1.2.13 1.2.14 1.2.14 1.2.15(*1) 1.2.15(*1) 1.2.15(*1) 1.2.15(*1) 1.2.17(*1) 1.2.17(*1) 1.2.17(*1) 1.2.17(*1) 1.2.17(*1) 2.8.2(*1)
XML Xerces 2 Java Parser - 2.5.0 2.5.0 2.5.0 2.5.0 2.5.0 2.9.0 2.9.1 2.9.1 2.9.1 2.9.1 2.9.1 同梱なし(*2) 同梱なし(*2) 同梱なし(*2) 同梱なし(*2) 同梱なし(*2)
XML Xalan Java 2 - 2.5.2 2.5.2 2.5.2 2.5.2 2.5.2 2.7.0 2.7.1 2.7.1 2.7.1 2.7.1 2.7.1 同梱なし(*2) 同梱なし(*2) 同梱なし(*2) 同梱なし(*2) 同梱なし(*2)
The Web Services Description Language
for Java Toolkit (WSDL4J)
- 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4(*3) 1.4(*3) 同梱なし 同梱なし 同梱なし 同梱なし 同梱なし

*1:パッケージ名をWebOTX独自のものに変更しているため、ユーザアプリケーションから利用できません。Webアプリケーションで利用する場合は、WEB-INF/libの下にライブラリを配置してください

*2:V9以降は、XercesおよびXalanを同梱しなくなりました。

JAXPを使用するアプリケーションでJAXP実装のライブラリを含まない場合、デフォルトではJDKに含まれるJAXP実装(com.sun.org.apache.〜 で始まるクラス)が使用されます。
(V8までは、WebOTXに同梱のXerces、Xalanが使用されていました。)

一方、JDKに含まれるJAXP実装クラスのパッケージは、アクセスが制限されています。(Memo参照)
そのため、 ${INSTANCE_ROOT}/config/server.policy を編集して、JAXPを使用するアプリケーションのコードに対して、JDKに含まれるJAXP実装のパッケージへのアクセス権を付与する必要があります。
※ アプリケーション内(例: WARファイル内のWEB-INF/lib)にXerces、Xalanを含む場合は、そちらのJAXP実装が使われるため、アクセス権の付与は必要ありません。

server.policyに追加する権限の例は以下の通りです。

grant codeBase "file:${com.nec.webotx.instanceRoot}/applications/<アプリケーション名>/-" {
    permission java.lang.RuntimePermission "accessClassInPackage.*";
};

grant codeBase "file:${com.nec.webotx.instanceRoot}/generated/-" {
    permission java.lang.RuntimePermission "accessClassInPackage.*";
};

上記の例では、アクセス制限のある全てのパッケージへのアクセス権を付与していますが、 "accessClassInPackage.com.sun.org.apache.xerces.internal.*" や "accessClassInPackage.com.sun.org.apache.xalan.internal.*" のように指定することで、使用するパッケージへのアクセス権のみを付与することも可能です。
その場合は、使用する機能に合わせてパッケージ名を指定した権限を追加してください。

Memo
${JRE_HOME}/lib/security/java.security の package.access に指定されたパッケージおよびそのサブパッケージにアクセスするコードには、 java.lang.RuntimePermission "accessClassInPackage.{パッケージ名}" を与える必要があります。
権限がない場合、該当するパッケージのクラスのロードに失敗します。

*3:標準ではクラスパスに含まれておりません。ライブラリの格納先は${AS_INSTALL}/lib/wssに移動しました。利用する場合は、クラスパスに含めるようにしてください。