ラベル プログラム の投稿を表示しています。 すべての投稿を表示
ラベル プログラム の投稿を表示しています。 すべての投稿を表示

2020年12月18日金曜日

Eclipse Java EEのDynamic Web ProjectでJavaScriptライブラリの構成管理をしつつモジュラーハンドラーを利用する方法

Eclipse Java EEのDynamic Web ProjectでJavaScriptのライブラリの構成管理をやりたかったので,ちょっとトライしてみました.

以下の作業をすれば,${PROJECT_HOME}/libにあるJavaScriptのライブラリ,あるいは,${PROJECT_HOME}/src/main/javascriptにある自身のコードが更新した際に,それらを一つにパックしたコードを${PROJECT_HOME}/src/main/webapp/jsに作成することができます.ただ,ライブラリと自分のコードを一つにパックすると,デバッグしずらいし,Builderをプロジェクトごとに登録するのが面倒だし,元々やりたかったのはJavaScriptライブラリの構成管理なので,使わずじまいとなりそうです.ちなみに,${PROJECT_HOME}は,プロジェクトのベースとなるディレクトリのことです.

1.存在しない場合,下記のディレクトリを作成.
  • ${PROJECT_HOME}/lib
  • ${PROJECT_HOME}/src/main/javascript
  • ${PROJECT_HOME}/src/main/webapp/js
2.次のコマンドを実行.
% cd ${PROJECT_HOME}/lib
% npm init -y
% npm install --save-dev webpack webpack-cli
3.次の内容を「${PROJECT_HOME}/lib/package.json」に追加.
{
      :
  "scripts": {
      :
    "build": "webpack --mode=production"
  },
      :
}
4.次の内容のファイルを「${PROJECT_HOME}/lib/webpack.config.js」に作成.
module.exports = {
    entry: '../src/main/javascript/index.js',
    output: {
        path: __dirname + '/../src/main/webapp/js',
        filename: 'main.js',
    },
    resolve: {
        modules: ["node_modules", "../../../lib/node_modules/"],
    }
};
5.次の内容の実行ファイル(実行パーミッションを付与する必要あり)を「${PROJECT_HOME}/bin/npmbuild.sh」に作成.
#!/bin/sh
export PATH="/usr/local/bin:$PATH"
npm run build
6.右ボタンを押下して,表示されるプルダウンメニューから「Properties」を選択.
7.「Properties」ダイアログにおいて次の操作を実行.
1.左にあるメニューから「Builders」を選択.
2. 「New...」ボタンを押下.
8.「Choose configuration type」ダイアログ内の「Program」を選択し,「OK」ボタンを押下.
9.「Edit Configuration」ダイアログにおいて次の操作を実行.
1.「Name」に作成するBuilderの名称を入力.
2. 「Main」タブにおいて,次の操作を実行.
1.「Location」に実行ファイルのパスを入力(「Browse Workspace...」ボタンを押下して表示されるダイアログで当該ファイルを選択可能).
2.「Working Directory」に「package.json」が置かれたディレクトリのパスを入力(「Browse Workspace...」ボタンを押下して表示されるダイアログで当該ファイルを選択可能).
3. 「Refresh」タブにおいて,次の操作を実行.
1.「Refresh resources upon completion」をチェック.
2.「Specific resources」をチェック.
3.「Specify Resources...」ボタンを押下して表示されるダイアログでBuilderを実行する対象となるディレクトリを選択.
4.「Recursively include sub-folders」をチェック.
4. 「Build Options」タブにおいて,次の操作を実行.
1.「Allocate Console」をチェック.
2.「After a "Clean"」,「During manual builds」,「During auto builds」をチェック.
3.「Specify working set of relevant resources」をチェック.
4.「Specify Resources...」ボタンを押下して表示されるダイアログでBuilderを実行する対象となるディレクトリを選択.
5. 「OK」ボタンを押下.
10.「Properties」ダイアログにおいて,次の操作を実行.
1.選択したBuilderがリストの一番上になるまで「Up」ボタンを押下.
2.「Apply and Close」ボタンを押下.

2020年12月9日水曜日

Eclipse EEのDynamic Web Projectにおいてライブラリを管理するためにGradleを使う方法

Eclipse EEのDynamic Web Projectにおいてライブラリを管理するためにGradleを使う方法は以下のとおりです.

  • Dynamic Web Projectを作成する.
  • プロジェクトのルートに以下に記すbuild.gradleファイルを作成する.
  • プロジェクトを右クリックして表示されるポップアップメニューで「Configure->Add Gradle Nature」を選択する.
  • srcディレクトリの配下にmain/javaディレクトリを作成する.
  • WebContentディレクトリをsrc/mainに移動し,「webapp」ディレクトリに改名する.
  • プロジェクトを右クリックして表示されるポップアップメニューで「Properties->Deployment Assembly」を選択する.
  • 「Web Deployment Assembly」ダイアログでAddボタンを押下する.
  • 「New Assembly Directive」ダイアログで「Folder」を選択し,Nextボタンを押下する.
  • 「New Assembly Directive」ダイアログで「src->main->webapp」を選択し,Finishボタンを押下する.
  • プロジェクトを右クリックして表示されるポップアップメニューで「Gradle->Refreash Gradle Project」を選択する.
  • buildディレクトリを削除する.

以前同じタイトルの内容[1]を投稿したのですが,こちらのほうが前のよりよい気がしたので,今後はこの方法でやっていこうと思います.

[1] Eclipse EEのDynamic Web Projectにおいてライブラリを管理するためにGradleを使う方法, https://emaizetto.blogspot.com/2020/04/eclipse-eedynamic-web-projectgradle.html

2020年4月11日土曜日

Eclipse EEのDynamic Web Projectにおいてライブラリを管理するためにGradleを使う方法

Eclipse EEのDynamic Web Projectにおいてライブラリを管理するためにGradleを使う方法は以下のとおりです.

  • Dynamic Web Projectを作成する.
  • プロジェクトのルートに以下に記すbuild.gradleファイルを作成する.
  • プロジェクトを右クリックして表示されるポップアップメニューで「Configure->Add Gradle Nature」を選択する.
  • ライブラリを更新した場合は,プロジェクトを右クリックして表示されるポップアップメニューで「Gradle->Refreash Gradle Project」を選択する.

ちょっと失われる設定もあるみたいですが,私的には問題ないので,問題がおきないうちはこの環境でWebアプリを作っていこうと思います.以前から構成管理に憧れていて,ずっとやりたかったんだけど,やっと踏み出すことができて良かったです.

「org.json.JSONException: Unterminated string at XXXX」に対処する方法

org.jsonライブラリを使ったコードでJSON文字列を処理した際に

org.json.JSONException: Unterminated string at XXXX
という例外に出くわしました.この例外は,文字列に直接記述することが許されていない文字を文字列に記述した際に生じるみたいです.そういうわけで,この例外に対する対処方法は,文字列に直接記述することが許されていない文字については,エスケープシーケンスで記述するということになります.

JSONの仕様[1]によると,値としての文字列に直接記述できる文字は,以下のとおりです.

  1. 0x20-0x21
  2. 0x23-5B
  3. 0x5D-10FFFF

上記の範囲に収まらない文字については,エスケープシーケンスで記述する必要があります.例えば,値として「0\t1\n」という文字列を記したい場合,「0x30,0x09,0x31,0x0a」と記すとNGなので,「0x30,0x5c,0x74,0x31,0x5c,0x6e」と記す必要があります.(0x30='0',0x31='1',0x09='\t',0x0a='\n',0x5c='\',0x6e='n',0x74='t').

今回の例外は,そのことを知らず,エスケープシーケンスで記す必要のある文字を直接記してしまったために発生したということになります.

[1]RFC8259, https://tools.ietf.org/html/rfc8259

2020年4月1日水曜日

Oculus GoでVideoPlayer越しにビデオを再生できない問題を解消する方法

VideoPlayerを使ってビデオを再生するOculus Go用のプログラムを作成した際に,次のメッセージが表示されて再生できないという問題に出くわしました.

Unity : AndroidVideoMedia: Error opening extractor: -10000

数日間試行錯誤を続けたところ,ビデオのURLに原因があることをつきとめました.

今回デバッグのために作成したコードは以下のとおりです. このコードの14行目でビデオのURLを指定しているのですが,それが「https://192.168.1.5:8443/test.mp4」のときに上記のエラーが発生します.このエラーを解消する方法は,ビデオを「https://hogehoge/test.mp4」というURLでアクセスできる場所に置き,そのURLをvideoPlayer.urlの値に指定するというものです.そうすると,ビデオが再生されるようになります.

原因はURLにあるところまではわかったのですが,URLのどこが原因かは定かではありません.なんとなくですが,ポート番号が怪しい(ポート番号の指定は無視されデフォルトのポート番号が使われているような)気がしています.

2020年3月30日月曜日

SPRESENSEで自作MQTTパブリッシャを動作させる方法

SPRESENSEで自作MQTTパブリッシャを動作させてみようと下記の「MqttPublisherTest.ino」というプログラムを実行したところ, 次のようなエラーに出くわしました.

mosquitto
New connection from 192.168.1.21 on port 1883.
Client  has exceeded timeout, disconnecting.
シリアルモニタ
failed, rc=-4

どうも使っているライブラリが怪しかったので,「SparkfunESP8286WiFi.cpp」というコードの(1)の部分を修正したところ, 上記のエラーは解消することができました, ただ,今度は次のような別のエラーが表示されるようになりました.

mosquitto
New connection from 192.168.1.21 on port 1883.
New client connected from 192.168.1.21 as ESP8266Client-0 (p2, c1, k15).
Socket error on client ESP8266Client-0, disconnecting.
シリアルモニタ
failed, rc=-1

処理内容を細かくチェックすると,MQTTブローカからの返信を処理していない箇所があったので, 「SparkfunESP8286WiFi.cpp」というコードの(2)の部分を追加したところ, シリアルモニタのエラーは解消することができました.

mosquitto
New connection from 192.168.1.21 on port 1883.
New client connected from 192.168.1.21 as ESP8266Client-5165 (p2, c1, k15).
Socket error on client ESP8266Client-5165, disconnecting.
シリアルモニタ
なし

引き続き処理内容を細かくチェックすると,コネクションの状態を返すべきところがWiFiの接続状態を返している箇所があったので, 「SparkfunESP8286Client.cpp」というコードの(3)の部分を修正したところ, ようやく期待通りの動作をさせることができました.

2017年10月17日火曜日

Eclipse WTP + TomcatでHTTPS通信を行う方法

Eclipse WTP + TomcatでHTTPS通信を行う方法をメモしておきます.

1. 次のコマンドを実行した後,パスワードとオレオレ証明証の発行に必要な情報を入力する.
$ keytool -genkey -alias tomcat -keyalg RSA -keystore workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/conf/localhost-rsa.jks
2. Project Explorerの「Servers->Tomcat vX.X Server at localhost-config->server.xml」を選択
3. server.xmlに次の内容を追加(コメントとして雛形があるので,それを解除).
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true">
  <SSLHostConfig>
    <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" certificateKeystorePassword="XXXXXXX" type="RSA" />
  </SSLHostConfig>
</Connector>

2015年6月13日土曜日

GEAのDataNucleus Enhancerが異常終了する問題

GEAのDataNucleus Enhancerが「java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal」という例外で異常終了する問題に出くわしました.この問題の解決方法をメモしておきます.

  • 「/WEB-INF/lib」(別のフォルダでもいいかもしれない)に「xml-apis-X.X.X.jar」と「xercesImpl-X.X.X.jar」を配置する(Xは適当な数字).
  • それら二つのJARファイルを「Java Build Path」の「Libraries」に追加する.

今回は,[1]の質問に対する回答を参考にしました.

[1] AppEngine Error [ java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal ], http://stackoverflow.com/questions/10234201/appengine-error-java-lang-noclassdeffounderror-org-w3c-dom-elementtraversal

2015年4月22日水曜日

CSSではみ出した部分を「…」にする方法

CSSではみ出した部分を「…」にする方法をメモしておきます.

.hogehoge {
    width: 4em;
    white-space: nowrap; 
    overflow: hidden;
    text-overflow: ellipsis;
}
<div class="hogehoge">どうしてプログラムのサンプルに使うテキストは「ほげほげ」なんだろう?</div>

「text-overflow: ellipsis;」と記せば,「…」にならなかったので,何でだろうとずっと悩んでいたのですが, このプロパティは,先の例のように他の3つのプロパティといっしょに使わないと効果が発揮されないんですね. ようやく謎が解けた.\(^O^)/

2015年4月19日日曜日

ロジスティック回帰をJavaで実装

文献[1]で紹介されているロジスティック回帰をJavaで実装してみました.

ロジスティック回帰は,分類問題に適用できる機械学習手法の1つです(確率化したパーセプトロンという理解でいいのかな). 文献で紹介されているとおりあらかじめ用意したデータを分類する関数を求めてみました. グラフにした結果は次の図のとおりです. 青の点が正解,赤の点が不正解,黄色の直線がそれらを分類するために推定された関数,オレンジが正解になる確率が0の領域で,緑が1の領域です. 直線付近は,正解と不正解の境界になっているので,正解になる確率がどんと落ちてます.

ちなみに,これまでグラフはExcelで描いてきたのですが,今回は難しかったので,d3.jsを使ってみました(かなりゴリ押しですけど). 使ってみて思いましたが,大本の文献で使っているPythonがやっぱり一番簡単そうですね.

[1] 中谷 秀洋: ロジスティック回帰を実装してみよう, 機械学習はじめよう 第20回, http://gihyo.jp/dev/serial/01/machine-learning/0020

2015年4月16日木曜日

パーセプトロンをJavaで実装

文献[1]で紹介されているパーセプトロンをJavaで実装してみました.

パーセプトロンは,分類問題に適用できる機械学習手法の1つです. 文献で紹介されているとおりあらかじめ用意したデータを正解(1)と不正解(-1)に分類する関数を求めてみました. グラフにした結果は次の図のとおりです. そうなるようにデータを作ってあるので,当たり前なのですが, 正解と不正解をうまく仕分ける関数を求めることができました.

[1] 中谷 秀洋: パーセプトロンを実装してみよう, 機械学習はじめよう 第17回, http://gihyo.jp/dev/serial/01/machine-learning/0017

2015年4月11日土曜日

ベイズ線形回帰をJavaで実装

文献[1]で紹介されているベイズ線形回帰を記事[2]で作成したプログラムを元にしてJavaで実装してみました.

ベイズ線形回帰は,線形回帰を確率化してベイジアンで関数を求める手法です. 文献で紹介されているとおり基底関数をベイズ基底にして関数を求めてみました. 結果は次の図のとおりです. ベイズ線形回帰なので,関数だけでなく,確率密度も求めることができます.

[1] 中谷 秀洋: ベイズ線形回帰を実装してみよう, 機械学習はじめよう 第14回, http://gihyo.jp/dev/serial/01/machine-learning/0014
[2] mizo0409: 線形回帰をJavaで実装, http://mizo0409.blogspot.jp/2014/01/java.html

2015年1月10日土曜日

サーブレットでネイティブライブラリを使う方法

サーブレットでネイティブライブラリをロードする方法についてメモしておきます.

java.lang.Systemクラスのloadメソッドを使うと,Webアプリケーションの範囲外に特別な設定をせずにネイティブライブラリをロードすることができます.例えば,OpenCVのネイティブライブラリが,次のように配置されている場合,

/opt/local/share/OpenCV/java/libopencv_java2410.dylib
java.lang.Systemクラスのloadメソッドを次のように記述すれば,そのライブラリをロードできます.
System.load("/opt/local/share/OpenCV/java/libopencv_java2410.dylib");

Javaアプリケーションの場合,ソース内では,java.lang.SystemクラスのloadLibraryメソッドを使い,

System.loadLibrary("opencv_java2410");
javaコマンドのオプションでネイティブライブラリのディレクトリを指定すればよいのですが,
java -Djava.library.path=/opt/local/share/OpenCV/java/ ...
これをjava.lang.SystemクラスのsetPropertyメソッドを使って肩代わりさせようとすると,ライブラリのロードに失敗します. どうも「java.library.path」の値は,起動時のものが使われるようで,その後に内容を変更しても使われないみたいです.

そういうわけで,Webアプリケーションで閉じた方法を探していたところ,上記の方法にたどり着きました. 絶対パスが入っているので,環境依存にはなるのですが(必要なら動的に変更できるようにすればいいし), アプリケーションサーバの設定を触らなくていいので,こちらのほうが自分の好みに合います.

2015年1月7日水曜日

java.lang.ClassクラスのgetResourceメソッド

java.lang.ClassクラスのgetResourceメソッドについてメモしておきます(裏はとってないので,あくまで自分の推測です).

java.lang.Class#getResourceがリソースを探索する際の起点は,CLASSPATHに指定されたパスになる.

例えば,「HogeHoge.class」というプログラムと「hogehoge.txt」というファイルが,次のように配置されている場合,

/tmp/bin/HogeHoge.class
/tmp/etc/hogehoge.txt
「HogeHoge.class.getResource("hogehoge.txt")」が「hogehoge.txt」のURLを返すためには,
java -cp "/tmp/bin:/tmp/etc" HogeHoge
というように「hogehoge.txt」が置かれたディレクトリのパスをCLASSPATHに指定してプログラムを実行する必要あります. ちなみに,HogeHogeクラスのソースは以下のとおりです.

import java.net.URL;
public class HogeHoge {
    public static void main(String[] args) {
        URL url = HogeHoge.class.getResource("hogehoge.txt");
        System.out.println(url);
    }
}

また,HogeHogeクラスがhogehogeパッケージのクラスの場合,つまり,ソースが次の場合,

package hogehoge;
import java.net.URL;
public class HogeHoge {
    public static void main(String[] args) {
        URL url = HogeHoge.class.getResource("hogehoge.txt");
        System.out.println(url);
    }
}
ファイル構成は次のようになり,
/tmp/bin/hogehoge/HogeHoge.class
/tmp/etc/hogehoge/hogehoge.txt
コマンドは次のようになります.
java -cp "/tmp/bin:/tmp/etc" hogehoge.HogeHoge

2014年5月6日火曜日

Google Maps JavaScript API v3でマップのサイズを変更する方法

Google Maps JavaScript API v3でマップのサイズを変更する方法をメモしておきます.

マップのサイズを動的に変更すると,次のように一部が欠けているような感じになることがあります.

これを起こさないようにするには,サイズの変更後にマップに対して「resize」イベントを送ればいいみたいです. そうすると,次のように一部が欠けることなく,マップのサイズを変更することができます.

試しに作ってみたコードは以下のとおりです.

2014年1月29日水曜日

線形回帰をJavaで実装

文献[1]で紹介されている線形回帰をJavaで実装してみました.

線形回帰は,与えられたデータに適した関数を基底関数の線形結合から求める手法です. 多項式基底とベイズ基底について正規化項ありとなしで関数を求めてみました. 結果は次の図のとおりです.

[1] 中谷 秀洋: 線形回帰を実装してみよう, 機械学習はじめよう 第11回, http://gihyo.jp/dev/serial/01/machine-learning/0011

2013年11月28日木曜日

AC法をJavaで実装

文献[1]で紹介されているAC法をJavaで実装してみました.

AC法はテキスト内に出現する複数のキーワードを1回走査しただけで検出することができるアルゴリズムです. トライの部分はダブル配列法を使いたいところですが,コード量が多くなるので,今回はTreeMapで済ませました. テストケースの件数が少ないので,もしかするとバグっているかもしれません.

[1] 伊藤 直也, 田中 慎司: Web開発者のための大規模サービス技術入門, 技術評論社, 2010-08

2013年11月17日日曜日

VB CodeをJavaで実装

文献[1]で紹介されているVB CodeをJavaで実装してみました.

また,圧縮の効果も調べてみました. 以下がその結果(一例)です. 140万エントリのID列を想定してランダムに生成した整数列をギャップ列に直して,VC Codeでエンコードしています. 元の整数列が密になる(整数列の長さが増す)ほど,圧縮率が良くなっています. 密になればなるほど,整数間のギャップが小さくなるので,期待通りの結果になりました.

整数列長圧縮前(B)圧縮後(B)圧縮率
1441.00
1040320.80
1004002600.65
1000400019550.49
1000040000140790.35

[1] 伊藤 直也, 田中 慎司: Web開発者のための大規模サービス技術入門, 技術評論社, 2010-08

2012年10月11日木曜日

JSONとオブジェクトを相互に変換する方法

JSONとオブジェクトを相互に変換する方法についてメモしておきます.

JSONオブジェクトのparseメソッドを使えば,JSONをオブジェクトに変換できます.

var json = '{"server_side": "Java", "client_side":"JavaScript"}';
var object = JSON.parse(json);
console.log(object);

JSONオブジェクトのstringifyメソッドを使えば,オブジェクトをJSONに変換できます.

var object = {"server_side": "Java", "client_side":"JavaScript"};
var json = JSON.stringify(object);
console.log(json);
参考資料
[1] JSONについて
[2] ネイティブJSONを使う

2012年9月24日月曜日

インスタンスイニシャライザを利用したMapの初期化方法

インスタンスイニシャライザを利用したMapの初期化方法をメモしておきます.

インスタンスイニシャライザという仕組みを使えば,初期化されたマップを宣言できるようです.例えば,"a","b","c"というキーに対してそれぞれ1,2,3を値とするマップを宣言する場合は,以下のようなコードとなります.

Map map = new HashMap() {{
    put("a", 1);
    put("b", 2);
    put("c", 3);
 }};

一見文法違反のように見えますが,無事コンパイルできます. HashMapを継承した匿名クラスのインスタンスイニシャライザ内で,HashMapから継承したputメソッドを呼び出しているからOKということなんでしょうか(適当に書いているので間違っているかもしれません). Javaでこんな書き方ができるなんて,知らなかった〜.

参考資料
[1] イニシャライザ
[2] [Java] インスタンスイ二シャライザで初期化したMapのシリアライズで