『こどもパソコン IchigoJam』を使ったプログラムワークショップで使用した簡単なゲームプログラムです。

BASICで記述されていますが、IchigoJam BASIC以外の環境で実行する場合、なんらかの変換・移植処理が必要になると思います。
IchigoJam BASICのリファレンス(説明書)は、 http://ichigojam.net/IchigoJam.html から参照できます。

プログラム入力後、RUNコマンドで実行します。

■ ゲームルール ■

  • 画面の上からおちてくるアルファベットとおなじキーをおすと、あたり!
  • 上の方であたるほど、こうとくてん!
  • アルファベットが画面の下までいくとミス!
  • 3かいミスをするとゲームオーバー。
ライセンス
NYSL ( http://www.kmonos.net/nysl/ )
10 CLS:LOCATE 10,10:PRINT "PUSH KURO-BUTTON"
20 IF BTN()=0 THEN GOTO 10
30 S=0:M=0
40 C=65+RND(26)
50 X=RND(32):Y=0
60 CLS
70 LOCATE 0,23:PRINT "SCORE=",S,"MISS=",M
80 LOCATE X,Y
90 PRINT CHR$(C);
100 IF INKEY()=C THEN BEEP 1:S=S+25-Y:GOTO 40
110 WAIT 10
120 Y=Y+1
130 IF Y<23 THEN GOTO 60
140 M=M+1
150 IF M<3 THEN PLAY "A16G16A2R8G16F16E16D16D-8D4":WAIT 150:GOTO 40
160 PLAY "C4C8.C16C4E-8.D16D8.C16C8.<B16>C4"
170 I=0
180 SCROLL 0:WAIT 5
190 I=I+1:IF I<24 THEN GOTO 180
200 LOCATE 10,10:PRINT "GAME OVER"
210 LOCATE 10,12:PRINT "SCORE=", S
220 END

ステップアップ・改造のヒントとして、以下の項目を提示しています。

かんたんな改造(かいぞう)

  • プレイヤーがボタンをおすとブザーがなるようにしてみよう
  • てきキャラにヒットしたら、LEDをつけて、ブザーをならすようにしてみよう
  • 音楽(おんがく)のしゅるいをふやしてみよう

ちょっとむずかしい改造(かいぞう)

  • 「レベル」をついかして、てきを10こやっつけるごとにレベルがあがるようにしてみよう
  • レベルが10あがるごとに、めちゃくちゃはやくおちてくるようにしてみよう
  • 自分(じぶん)がそうさするキャラクターをついかしてみよう
  • 自分がそうさするキャラクターからげいげきミサイルをはっしゃできるようにしてみよう

むずかしい改造(かいぞう)

  • てきキャラクターを2ついじょうにふやしてみよう
  • てきキャラクターのおちるそくどに、じゅうりょくがあるようにしてみよう
    (じゅうりょくは、理科(りか)や物理(ぶつり)の教科書(きょうかしょ)でしらべてみよう。理科(りか)・物理(ぶつり)と算数(さんすう)・数学(すうがく)のルールをゲームにくみこむとリアルさがぐんとあがるぞ!!)

IBMのRDBMS『DB2』のデータを、オープンソースRDBMS『PostgreSQL』に移行したときの作業メモです。

作業環境

移行元の環境
  • Windows 10 Pro(64ビット版)
  • DB2 Express-C v10.5
移行先の環境
  • CentOS 6.9(64ビット版)
  • PostgreSQL 9.6.3
  • DB2クライアント v10.5
PostgreSQLはpostgresql.orgよりyumコマンドでインストールしています。

wget http://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-6-x86_64/pgdg-centos96-9.6-3.noarch.rpm
rpm -ivh pgdg-centos96-9.6-3.noarch.rpm
yum install postgresql96-server

事前準備

移行先環境では、下記の項目が完了している必要があります。

  • Perlが使える状態になっている。
  • Perl ::CSV::XSが使える状態になっている。
  • DB2クライアントが使える状態になっている。
  • PostgreSQLのユーザ(データベースの作成権限、ロールの作成権限付き)が登録されている。
  • PostgreSQLの移行先データベースが作成されている。

DB2クライアントからDB2サーバに接続できるようにする

移行先の環境で、既にDB2サーバへの接続設定済み、または設定が不要の場合は、この部分は読み飛ばしてください。

Qiitでhitさんが公開されている『db2クライアントからdb2サーバに接続する方法』を参考に、DB2クライアントからDB2サーバに接続できるように設定します。

/opt/ibm/db2/V10.5_01/bin/db2 CATALOG TCPIP NODE RMTNODE REMOTE 192.168.1.160リモートサーバのアドレス SERVER リモートサーバのポート番号 OSTYPE リモートサーバのOS種別
/opt/ibm/db2/V10.5_01/bin/db2 CATALOG DATABASE リモートサーバのデータベース名 AS クライアントで参照する際の別名 AT NODE カタログしたリモートノード名 AUTHENTICATION 認証種別

私の環境では下記のように実行しました。

/opt/ibm/db2/V10.5_01/bin/db2 CATALOG TCPIP NODE ノード名 REMOTE 192.168.1.160 SERVER 50000 OSTYPE WIN
/opt/ibm/db2/V10.5_01/bin/db2 CATALOG DATABASE DB2NODB AS RMTDB AT NODE RMTNODE AUTHENTICATION SERVER

DB2移行ツールの導入

Dalibo社がGitHub上で公開している『db2topg』をダウンロードし、移行先環境の適当な場所に展開します。

公開されているソースを実行するとdb2topg.plに2点ほど問題が見つかったので、あらかじめ修正します。

  1. 「iso-8859-15 or utf8 at ./db2topg.pl line 383.」と出力される。

文字コードの推測に失敗すると発生するようです。
使用しない文字コードを対象としないよう、db2topg.plの383行目付近の条件を修正します。

  • 修正前
    my $decoder = guess_encoding($data_guess, qw/iso8859-15 utf8 utf16-le utf16-be/);
    
  • 修正後
    my $decoder = guess_encoding($data_guess, qw/utf8 utf16-le utf16-be/);
    
  1. I don’t understand </****** ※ 「DB2ADMIN」は適切なスキーマ名を設定してください。>

「DB2ADMIN」などは環境によって変化すると思います。
DB2のコメント形式が出現すると発生するようです。
コメント出現時に無視するよう、db2topg.plの1081行目付近に条件を追加します。

  • 修正後
    elsif ($line =~ /^\/\*\*\*\*\*\*/)
    {
        next;
    }

    db2topgに含まれる.plファイルに対して実行権限を付与しています。
    実行権限を付与しない場合、以下の手順では適宜お使いの環境に合わせて読み替えてください。

DB2からDDLなどを出力

DB2から移行対象となるデータベースのDDLなどを出力します。
私の場合、-zオプションを付けて対象スキーマを絞ってしまいましたが、省略するとデータベースをまるごと移行できるようです。

/opt/ibm/db2/V10.5_01/bin/db2look -d DB2のデータベース名 -z DB2の対象スキーマ名 -i DB2のユーザ名 -w DB2のログインパスワード -e -l -xd -o DB2からの出力スクリプトファイル名.sql

/opt/ibm/db2/V10.5_01/bin/db2look -d rmtdb -z db2admin -i db2admin -w db2admin -e -l -xd -o my_db2_sql_script.sql

PostgreSQL変換用のスクリプトを出力

./db2topg.pl -f my_db2_sql_script.sql -o DB2データの出力ディレクトリ -d DB2のデータベース名 -u DB2のユーザ名 -p DB2のログインパスワード

./db2topg.pl -f my_db2_sql_script.sql -o db2pg_migration -d rmtdb -u db2admin -p db2admin

作業ディレクトリの変更

cd DB2データの出力ディレクトリ

cd db2pg_migration

DB2固有の表現の変更または削除

使用している環境によって変化してくると予想しています。
私の環境では「 OCTETS」と 「DEFAULT “SYSIBM”.”DATE(‘9999-12-31’)」がさしあたって不要だったので、sedコマンドで除去しました。

sed -e 's/ OCTETS//g' -e 's/ DEFAULT "SYSIBM"."DATE"('\''9999-12-31'\'')//g' before.sql > _before.sql

変換用スクリプト実行(before – テーブルなどの作成)

psql -e –set=ON_ERROR_STOP=1 –single-transaction -f _before.sql PostgreSQLのデータベース名

psql -e --set=ON_ERROR_STOP=1 --single-transaction -f _before.sql pgdb_migration

before.sqlを実行するとロールが作成されます。
このため、2回目以降の実行エラーが発生し以後の処理が行われません。
回避するため、before.sqlの実行前に作成されたロールの削除が必要になるケースがあります。

psql -e –set=ON_ERROR_STOP=1 –single-transaction -c ‘drop role PostgreSQLのロール名’ -U PostgreSQLのログインユーザ名 -d postgres

psql -e --set=ON_ERROR_STOP=1 --single-transaction  -c 'drop role db2admin' -U postgres -d postgres

DB2からデータをエクスポート

/opt/ibm/db2/V10.5_01/bin/db2 -f export.db2

DB2のデータをPostgreSQLにインサート

../deltocopy.pl -d . | psql -e –set=ON_ERROR_STOP=1 PostgreSQLのデータベース名

../deltocopy.pl -d . | psql -e --set=ON_ERROR_STOP=1 pgdb_migration

変換用スクリプト実行(after)

psql -e –set=ON_ERROR_STOP=1 –single-transaction -f after.sql PostgreSQLのデータベース名

psql -e --set=ON_ERROR_STOP=1 --single-transaction -f after.sql pgdb_migration

変換用スクリプト実行(unsure)

psql -e -f unsure.sql PostgreSQLのデータベース名

psql -e -f unsure.sql pgdb_migration

このステップでは、ビューに対するコメントづけが失敗するケースがあるようです。
ビューそのものの移行は行われるので、特に必要が無ければ無視しても大丈夫だと思います。


ユーザ名やパスワードの設定などが相当ゆるゆるの環境で手順の検証を行いましたが、上記の手順でDB2のデータがPostgreSQLに移行できました。
文字化け等も発生していないように見受けられますが、現在確認を進めている最中です。

PostgreSQLに移行したデータは、publicスキーマではなくDB2で使用していたスキーマ名を引き継いで移行されることに注意が必要です。

検証はしていませんが、DB2サーバにアクセスできPerlが動く環境があれば、Linux環境以外でも実行できそうな感じがします。

#
# DB2サーバが別のサーバで実行されていて、DB2クライアントからDB2サーバに接続する場合に実行
#   RMTNODE 		ノード名
#   192.168.1.xxx	リモートサーバのアドレス
#	50000			リモートサーバのポート番号
#	WIN				リモートサーバのOS種別
# /opt/ibm/db2/V10.5_01/bin/db2 CATALOG TCPIP NODE RMTNODE REMOTE 192.168.1.xxx SERVER 50000 OSTYPE WIN
#
# ----
#	DB2NODB		リモートサーバのデータベース名
#	RMTDB			クライアントで参照する際の別名
#	RMTNODE			カタログしたリモートノード名
#	SERVER			認証種別
# /opt/ibm/db2/V10.5_01/bin/db2 CATALOG DATABASE DB2NODB AS RMTDB AT NODE RMTNODE AUTHENTICATION SERVER

#############################################################################################



# ----
# DB2からDDLなどを出力
# ----
# /opt/ibm/db2/V10.5_01/bin/db2look -d DB2のデータベース名 -z DB2の対象スキーマ名 -i DB2のユーザ名 -w DB2のログインパスワード -e -l -xd -o DB2からの出力スクリプトファイル名.sql
/opt/ibm/db2/V10.5_01/bin/db2look -d RMTDB -z db2admin -i db2admin -w db2admin -e -l -xd -o my_db2_sql_script

# ----
# 念のためUTF8変換
# ----
# nkf --utf8 DB2からの出力スクリプトファイル名.sql > db2.utf8.sql
nkf --utf8 my_db2_sql_script.sql > db2.utf8.sql

# ----
# PostgreSQL変換用のスクリプトを出力
# ----
# ./db2topg.pl -f db2.utf8.sql -o DB2データの出力ディレクトリ -d DB2のデータベース名 -u DB2のユーザ名 -p DB2のログインパスワード
./db2topg.pl -f db2.utf8.sql -o db2pg_migration -d RMTDB -u db2admin -p db2admin

# ----
# PostgreSQL変換用のスクリプトを出力
# ----
# cd DB2データの出力ディレクトリ
cd db2pg_migration

# ----
# 2回目以降の実行の場合、すでに既存ロールdb2adminが存在しているので、これを削除
# ----
# psql -e --set=ON_ERROR_STOP=1 --single-transaction  -c 'drop role PostgreSQLのロール名' -U PostgreSQLのログインユーザ名 -d postgres
psql -e --set=ON_ERROR_STOP=1 --single-transaction  -c 'drop role db2admin' -U postgres -d postgres

# ----
# before.sqlにはDB2固有の表記が含まれているので実行前に" OCTETS"や"SYSIBM"で始まるデフォルト値設定を取り除く
# ----
sed -e 's/ OCTETS//g' -e 's/ DEFAULT "SYSIBM"."DATE"('\''9999-12-31'\'')//g' before.sql > _before.sql

# ----
# 変換用スクリプト実行(before - テーブルなどの作成)
# ----
# psql -e --set=ON_ERROR_STOP=1 --single-transaction -f _before.sql PostgreSQLのデータベース名
psql -e --set=ON_ERROR_STOP=1 --single-transaction -f _before.sql pgdb_migration

# ----
# DB2からデータをエクスポート
# ----
/opt/ibm/db2/V10.5_01/bin/db2 -f export.db2

# ----
# DB2のデータをPostgreSQLにインサート
# ----
# ../deltocopy.pl -d . | psql -e --set=ON_ERROR_STOP=1 PostgreSQLのデータベース名
../deltocopy.pl -d . | psql -e --set=ON_ERROR_STOP=1 pgdb_migration

# ----
# 変換用スクリプト実行(after)
# ----
# psql -e --set=ON_ERROR_STOP=1 --single-transaction -f after.sql PostgreSQLのデータベース名
psql -e --set=ON_ERROR_STOP=1 --single-transaction -f after.sql pgdb_migration

# ----
# 変換用スクリプト実行(unsure)
# Viewのコメント付けが失敗する
# ----
# psql -e -f unsure.sql PostgreSQLのデータベース名
psql -e -f unsure.sql pgdb_migration

OpenCVやFFmpegなど画像処理関連のライブラリをJavaで使えるようにしたJavaCV( https://github.com/bytedeco/javacv )を使い、動画ファイルを静止画ファイル群に変換するサンプルプログラムです。

サンプル中では動画ファイルとしてMP4形式を指定していますが、AVI形式やWMV形式なども使用できます。
また、出力する形式についてもJPEG形式以外にもPNG形式やMBP形式なども指定できます。

JavaCVのorg.bytedeco.javacv.FFmpegFrameGrabberクラスには、動画ファイルのフレームレートやサイズ、総フレーム数などを取得するプロパティが用意されているのですが、org.bytedeco.javacv.FFmpegFrameGrabber#startを呼び出すまでは、期待する値が返ってきません。

ループ内でorg.bytedeco.javacv.Java2DFrameConverter#convertを用いて動画からフレームごとの画像を切り出す部分も、かなりの頻度でnullが返ってきます。
これが動画ファイルに起因するものなのか、JavaCVまたはOpenCV/FFmpegなどに起因するものなのか、使用方法の誤りか現在のところ特定できていません。

また、org.bytedeco.javacv.FrameGrabber#getFrameNumberを用いてフレーム番号を取得する処理でも重複したフレーム番号が返ってきたり、番号が飛ぶなどの現象が起きましたが、こちらも原因の特定ができていません。

処理を実行すると、かなりの枚数の画像ファイルが生成されディスク容量を消費します。
実行の際にはディスクの空き容量にご注意ください。

動作確認を行った環境:

Java

Java SE Development Kit 8

JavaCV

1.3.2

ライセンス

NYSL

// This software is distributed under the license of NYSL.
// ( http://www.kmonos.net/nysl/ )

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;

public class 動画ファイルから静止画を切り出すプログラム {

	public static void main(String[] args) {
		new 動画ファイルから静止画を切り出すプログラム().slice(new File("./mp4/sample.mp4"), new File("./jpeg"));
	}


	/**
	 * 	動画ファイルをフレームごとに切り出し静止画に変換する
	 *	
	 *	@param srcMoviePath	動画ファイルのパス
	 *	@param destJpegPath	静止画ファイルの出力ディレクトリのパス
	 */
	public void slice(final File srcMoviePath, final File destJpegPath) {
		
		try {
			
			FFmpegFrameGrabber frameGrabber= new FFmpegFrameGrabber(srcMoviePath);
			Java2DFrameConverter frameConverter = new Java2DFrameConverter();
			
			frameGrabber.start();
			
			// FFmpegFrameGrabber#startを実行した後から、getFrameRateやgetLengthInFramesなどのプロパティで値が取得できるようになる 
			System.out.println("format:" + frameGrabber.getFormat() + ", size:" + frameGrabber.getImageWidth() + "x"
					+ frameGrabber.getImageHeight() + ", frame-rate:" + frameGrabber.getFrameRate()
					+ ", length-in-frame:" + frameGrabber.getLengthInFrames());

			int count = 0;
			
			// 現在のフレーム番号が動画ファイルの総フレーム数に到達するまでループ
			while (frameGrabber.getFrameNumber() < frameGrabber.getLengthInFrames()) {
				
				// フレームを取りだして
				BufferedImage img = frameConverter.convert(frameGrabber.grab());
				if (img == null) {
					// BufferedImageが取得できないことがあるので、そのときはスキップ
					continue;
				}
				
				// 静止画で出力
				// フレーム番号が重複することがある
			    ImageIO.write(img, "jpg", new File(destJpegPath, "frame-" + frameGrabber.getFrameNumber() + "-" + count + ".jpg"));
			    
			    count++;
			}
			
			frameGrabber.stop();
			frameGrabber.close();
				
		} catch (FrameGrabber.Exception e) {
			e.printStackTrace();;
		} catch (IOException e) {
			e.printStackTrace();;
		}
	}
}

macOS上で動くVisual Studio、『Visual Studio for Mac』が正式にリリースされました。

前身の統合開発環境『Xamarin Studio』を使っており、Microsoftによるブランド統合によりWindows版Visual Studioと操作感や機能が統一されていくのではないかと期待していたのでこのリリースは楽しみでした。
さっそくインストールしてみます。

まず、Visual Studio for Macのwebサイト( https://www.visualstudio.com/ja/vs/visual-studio-mac/ )からインストーラをダウンロードします。

0

VisualStudioInstaller.dmgがダウンロードされます。
2017/05/10にリリースされたバージョンのインストーラの大きさは27MB弱なので、全部入りの環境ではなく、環境やユーザの選択に応じて必要なソフトウェアをダウンロードしていく方式のようです。

0-1

ダブルクリックするとフォルダが開きます。
フォルダの中に配置されたアイコンをダブルクリックして作業を続けます。

1

インストーラが起動します。
『続行』ボタンをクリックして作業を続行します。

2

インストールを行うソフトウェアを選択します。
このときVisual Studio for Macをインストールしようとしているマシンに、既にインストールされているソフトウェア(Android SDKなど)の確認を行い、重複してインストールされないようになっています。
自分の場合、Xamarin Studioが導入済みなので、iOSとAndoroid向けのXamarin.Formsは更新インストールとなりました。

インストールしたいソフトウェアを選択し、『インストールと更新』ボタンをクリックします。

3

ダウンロードがはじまります。

4-1

ウィザードの下部に表示されているように、インストール中に何度かmacOSのアカウント確認のダイアログが表示されます。
ほったらかしにしておくという訳にはいかないようです。

5

しばらくするとインストールが完了します。

『Visual Studioの開始』ボタンをクリックして、Visual Studioを起動します。

6

Visual Studio for Macが起動されました。

当たり前のことですが、メニューなどのメッセージが日本語で表示されています。
UIで使用する言語は、ユーザー設定のダイアログから変更できます。

7

『新しいソリューションの作成』からVisual Studio for Macで作成できるアプリケーションの種類をチェックします。
「.NET Core」の項目がまぶしいですね。Microsoft純正という安心感は大きいです。

8

しかし、ここで気づきました。

ダウンロードしてインストールすると、Communityエディションとしてインストールされます。
自分はVisual Studio Professionalサブスクリプションを契約しているので、Professionalエディションにあげられないものか気になります。

9

バージョン情報を確認すると、やはりCommunityエディションと表示されます。

10

インストーラの選択を間違えたのではないかと思い、Visual Studioサブスクリプションのポータル画面( http://my.visualstudio.com )を開きます。

使用できるツールの一覧に、Visual Studio for Macが増えています。

20

アイコンをクリックしてみると、ダウンロードやキーの入手の画面が!
さっそくダウンロードします。

21

ダウンロードしたインストーラを開くと… あれ!? さっきと同じ!?
よく見るとダウンロードしたインストーラのファイルサイズも1バイトたりと違わず同じです。

22

当然、インストール対象のソフトの選択画面も同じ。
しかも「インストールや更新の対象はありません。」の注釈付きです。
インストーラではなくアクティベーションで変わりそうな予感。

 23

Visual Studio for Macを再度起動し、『Account』メニューをクリックします。

24

登録されているアカウントが表示されます。
よく見ると「!」が付いていて、『Re-enter credentials…』ボタンがあります。

ボタンをクリックし、Microsoftアカウントの認証を済ませると

25

無事、Professionalエディションになりました!!

26-1

バージョン情報を見てもProfessionalエディションです。
無事解決。

27

そういえば、MicrosoftがXamarinを買収し、Xamarin Studioのアカウント設定でMicrosoftアカウントが使えるようになった頃、同じようなことがあったような…(^-^;

webシステムの開発をしていて、ブラウザから比較的大きなファイルをサーバに送信しようとしたときに正常に終了しないケースを発見しました。
具体的には、2MB程度までは複数個のファイルを指定しても問題なく正常終了するのですが、5MB、10MB、15MB…と増やしていくと処理が失敗するようになります。

ブラウザや環境によって表示されるメッセージは異なるようなのですが、開発者向けのコンソールを見ると、Chromeでは「net::ERR_CONNECTION_RESET」、Safariでは「Failed to load resource: ネットワーク接続が切れました。」と表示されます。
その他のブラウザではなにも表示されないケースもあるようです。名称未設定

この原因についてネットで検索してみると、「IPv6を切れ」や「ブラウザのキャッシュを削除しろ」などいろいろな意見がありますが、これだ!という決定打はないようです。

ネットで見つかった情報をもとに対応をしてみたのですが解決できず、いろいろと試してみたところ、私の環境では───

アンチウィルスソフトが原因

になっていることがわかりました。

ウィルス対策として導入している『ESET Cyber Security Pro』(mac用)、『ESET SMART SECURITY』(Windows用)のWebアクセス保護機能が悪さをしていました。
設定画面からこの機能をオフにすると正常に動作するようになりました。

お悩みの方は、一度アンチウィルスソフトやファイアウォールなどの設定を確認してみると良いかもしれません。


今回、フロント側のJavaScript/jQueryからサーバ側のJava/JEEにファイルを送信するという機能を実装していたのですが、問題を発見してから挙動を確かめていると「100%失敗するのではなく、ときどき正常に終了することもある」という開発者泣かせの厄介なケースであることが判明しました。

FirefoxのFirebugアドオンの『ネットワーク』タブでリクエストの状況を見ると、失敗しつつときどき成功という状態が確認できます。
というか、失敗しているときはHTTPステータスコードも返ってきていないっぽい。

スクリーンショット 2017-05-10 19.07.15

とりあえず、手間がかからなく問題を捕まえやすそうなJavaScriptのデバッガを使って処理を呼び出しているところにブレイクポイントをしかけてみます。
空値が返ってきてヒントになりそうな情報がつかめません。ブラウザによってはあらぬところに処理が飛んでいきます。

次に、JEEサーバにデプロイしているwebアプリケーションの適当な場所にブレイクポイントをしかけたところ、「Error uploading: Processing of multipart/form-data request failed.」というメッセージが生じていることを補足できました。
そのメッセージが生成されている場所を追いかけていくと、内部で使用しているApache Commons FileUploadでなにかが起きているところまで辿り着くことができました。

org.apache.commons.fileupload.FileUploadBaseクラスのparseRequestメソッド内で、Streams#copyを使ってHTTPリクエストからの入力ストリームをテンポラリファイル書き出すところで、java.io.IOExceptionが発生し処理が止まります。
例外処理の中ではキャッチしたIOExceptionからgetMessageメソッドで具体的な内容を取得してメッセージ化し、それをorg.apache.commons.fileupload.FileUploadBase.IOFileUploadExceptionに込めてスローさせるので、意図からすると呼び出し側ではスローされた例外を見れば原因がわかりそうです。
しかし、IOFileUploadExceptionのメッセージを見るとnullが設定されており原因は把握できません。(他のケースでは実装者の意図通り原因が表示されるようです。)
そこで、ここにブレイクポイントをしかけると、IOExceptionの具体的な中身はEOFExceptionであることがわかります。
入力ストリームの内容を出力ストリームに送る機能でEOFExceptionが出るということは、ブラウザ側がきちんとデータを送っていないか、間に挟まっているフレームワークが悪さをしているかがまず思い浮かびます。
処理の都合上jQuery.ajax()を使って実装していることも原因として充分に怪しいのですが、直前に対処した問題がまさに後者のパターンであったため、これなのではないかと推測、そして深みへとはまります。

補足したメッセージをネットで検索をしてみるとApache Commons FileUploadのトラッキングサイトに「FILEUPLOAD-262 Processing of multipart/form-data request failed. null」という今回の事象まんまで2014年11月にバグレポートが上がっているものの、未解決状態のまま放置されています。プライオリティもMinor扱い。

とりあえず、事象とキーワードがわかったので、適当な語句を選んで検索を仕掛けてみると、類似する事象はいくつか見つかるのですが、どれもこれも原因と対策がセットになった結論まではでていません。
みんなお手上げ状態なのでしょうか…

普段使わないような設定を変えてみたり、ライブラリに依存しないよう自前のルーチンに置き換えてみたりいろいろと試してみたのですが、原因はもっと単純なところにあった、というしょうもないオチでした。


2017/05/15 追記

Subversionをweb経由で使用していて、Apacheのログに「Could not get next bucket brigade」という記載があった場合、これもESETが原因である可能性があります。
ESETのWebアクセス保護機能を止めたところ問題なく処理が完了するようになりました。

また、きちんと再現テストはしていないのですが「ModSecurity: Error reading request body: Partial results are valid but processing is incomplete」「ModSecurity: Request body (Content-Length) is larger than the configured limit」といった内容が記載がされた場合もESETに起因する可能性がありそうな。

小型なのにフルキーボードを搭載しているPORTABOOKを年末から年始にかけての激安販売で手に入れた方も多いと思います。自分もその一人です。

PORTABOOKには最初からWindows 10が搭載されているわけですから、無料のアップデートが提供されているうちはできるだけ最新にしたいと思うのは当然のこと。
しかし、PORTABOOKは本体ストレージの容量が32GBと少なく、Windows 10の大型アップデートを適用しようとすると不要なアプリケーションを消してから臨む必要がありました。

今回のCreators Updateもご多分に漏れず、Windows 10の更新アシスタントをダウンロードし、実行すると下記のような画面が表示されます。

2017-04-07 (1)

エラーコードとして表示されている「0xc190020e」をMicrosoftのサイトで調べてみると───

コンピューターにインストールするための十分な空き領域がないことが わかった場合は、MOSETUP_E_INSTALLDISKSPACE_BLOCK (0xC190020E) が 返されます

容量不足のようです。

更新アシスタントを起動すると行われるインストール要件チェックで、空き容量も含めてすべての項目で「問題なし」と判定され、インストールイメージのダウンロードがはじまっているにも関わらずです。

「ディスククリーンアップ」などを使ってめいっぱい不要なものを削除をしても、確保できる空き領域は10GB弱くらい。
この状態で更新アシスタントを実行してもやはり同じメッセージが表示されます。

PORTABOOKの本体ストレージはeMMCなので換装も増設もできず、諦めるしかないのか…と思いかけていたのですが、アップデートを適用する方法を見つけることができました。

結論を書いてしまうと、PORTABOOKではオンラインでダウンロードしながらアップデートする方法では使えません。
代わりに、一度USBメモリなどにインストールメディアを作成し、そこからインストールする方法が使えます。
また、この方法でも本体ストレージだけでは容量不足を回避できないので、Windows 10のセットアップ時にテンポラリとして外部の記憶装置(USBメモリ)を用いる必要があります。

用意するもの

IMG_2932

 

  • 4GB以上のUSBメモリ(Windows 10のインストールメディア作成用)
  • 16GB程度のUSBメモリ(テンポラリ用)
  • USBハブ

今回、8GBと16GBのUSBメモリを用意し、8GBのほうにWindows 10のインストールメディア用、16GBのほうをテンポラリ用として作業を行いました。

手順

事前準備として、USBメモリをUSBハブに挿しUSBハブをPORTABOOKに接続します。

Microsoftのサイト( https://www.microsoft.com/ja-jp/software-download/windows10 )にアクセスします。
画面中ほどの「ツールを今すぐダウンロード」をクリックします。

2017-04-15

ダウンロードした「MediaCreationTool」をダブルクリックし、実行します。

2017-04-15 (1)

ライセンス条項を確認し、「同意する」をクリックします。

2017-04-15 (3)

「別のPCのインストールメディアを作成する(USBフラッシュドライブ、DVD、またはISOファイル)」を選択し、「次へ」をクリックします。

2017-04-15 (4)

アーキテクチャが「64ビット(x64)」になっていることを確認し、「次へ」をクリックします。
通常、「このPCにおすすめのオプションを使う」がチェックされていると、自動的に「日本語」「Windows 10」「64ビット(x64)」になっているはずです。

2017-04-15 (5)

使用するメディアを選択します。
今回はUSBメモリにインストールメディアを作成するので、「USBフラッシュドライブ」を選択し、「次へ」をクリックします

2017-04-15 (14)

USBメモリのドライブを選択(インストールメディア用の容量が小さいほう)し、「次へ」をクリックします。

2017-04-15 (15)

メディアを選択するとWindows 10のダウンロードがはじまるので、終了するまで待ちます。
(フレッツ光環境では30分程度でダウンロードできました)

2017-04-15 (17)

続いてダウンロードの検証がはじまるので、待ちます。

2017-04-15 (19)

検証が終わるとメディアの作成が始まります。
待ちます。

2017-04-15 (20)

しばらくするとメディアの作成が完了し、画面が変わります。
「完了」をクリックします。

ダウンロードがはじまってから、ここまで1時間弱くらいかかりました。

2017-04-15 (22)

  1. インストールメディアからセットアップを実行する。

作成したUSBメモリの中にある「setup」をダブルクリックし、実行します。

2017-04-15 (27)

「更新プログラムをダウンロードしてインストールする(推奨)」を選択し、「次へ」をクリックします。

2017-04-15 (6)

ライセンス条項などを確認し、「同意する」をクリックします。

2017-04-15 (7)

更新プログラムのダウンロードがはじまるので、待ちます。

2017-04-15 (8)

更新プログラムのダウンロードが終わるとインストールがはじまります。

2017-04-15 (9)

2017-04-15 (10)

PORTABOOKにWindows 10 Creators Updateを入れようとする方は、すでに「ディスククリーンアップ」ツールなどで極限まで空き領域を確保している状態だと思うので、ステップ1を飛ばします。
ステップ2でテンポラリ用の容量の大きいほうのUSBメモリを指定し、「続行」をクリックします。

2017-04-15 (11)

インストール時に引き継ぐものを選択し、「インストール」をクリックします。
以後は通常のインストールです、ひたすら待ちます。

2017-04-15 (12)

無事、Creators Updateが適用できました。

2017-04-15 (13)

2016年3月にMicrosoftに買収されたXamarin。買収された直後からXamarin Studioの無償化が行われたわけですが、買収前にXamarinのサブスクリプションを購入していた私は、買収後のサブスクリプションライセンスの位置づけがどうなるのか明確な発表を見つけられずやきもきしておりました。

Xamarinサブスクリプションの更新時期がきてXamarinアカウントにログインするも、既にサブスクリプションは購入なくなっており、代わりに1カ月くらいの有効期限延長の手続きみたいなものが用意されていて実行すると期限が延長されました。
そして今回、その延長されたサブスクリプションライセンスもついに切れ「サブスクリプションの期限が切れたからCommunityに移行せい」みたいなことが表示されるようになりました。
同じ画面に表示されるにXamarin Studioの期限切れについてのFAQのリンクで、ついに答えを見つけました。

Visual Studioサブスクリプションを契約しているので、下記の項目が該当しそうです。

I’m an MSDN subscriber, how can I start using Xamarin?

If you want to use Xamarin with Visual Studio, please upgrade Visual Studio to the latest version and sign in with your MSDN account to activate Xamarin.

If you want to use Xamarin with Xamarin Studio on OS X, please visit your MSDN Subscription page, locate Xamarin Studio (For OS X) in your Subscription Benefits, and click “Register and Download”. You will need to create a Xamarin Account, or sign in with your existing Xamarin Account to redeem your licenses. Once you have redeemed your licenses, you can activate them by signing into Xamarin Studio with your Xamarin Account.

とりあえず、Visual Studioのサブスクリプションにログインしてみます。

1

「Tools」というブロックを右にスクロールしていくと「Xamarin Studio(for OS X)」という項目を見つけました。
そこから「Get Code」と書かれたリンクをクリックすると、次のような購入手続きのページに遷移しました。
(Xamarinをアクティベートした後なので、「Get Code」と表示されていた箇所が「Activate」と変わってしまっています。)

既にXamarinアカウントを持っているので、「I already have a Xamarin account」ボタンをクリックしてログインを行うと、登録済み情報がフォームに展開されました。

2

ここに掲載したスクリーンショットはXamarinのアクティベート後に撮り直したものなので請求金額が$897.00と表示されてしまっていますが、実際に購入手続きを行ったときは、そこから$897.00分値引きされて請求金額は$0.00と表示されました。

購入手続きを行うと、次のようなサンクスページに遷移します。

3

すでにXamarin Studioをインストール済みの環境なので、新たにダウンロードせず、既存のXamarin Studioを立ち上げます。
ログインを促されるのでMicrosoftアカウントでログインを行うとXamarin Studioの『BUSINESS』が有効化されていました。

いつの間にかMicrosoftアカウントでもログインできるようになっています。
古い環境を確認すると、Xamarin Studio 6.1.5まではXamarinアカウントだけ、6.2からはMicrosoftアカウントとXamarinアカウントの両方が使えるようです。

一通りアクティベート作業を行った後にスクリーンショットを撮っているので、「本当にタダなのか!?」という不安が残ってしまいます。
念のためXamarinアカウントの「Billing History」から請求書を確認します。

ちゃんとディスカウントされて請求金額が$0.00になっていました。

4

ちなみに、Xamarinサブスクリプションで購入していた製品は『Xamarin.Android』だけだったのですが、今回はすべての製品が使えるようになっています(^-^;

インターネットでゲームを購入するときに非常に便利なSteam。
普段はPayPal経由で支払いをしているのですが、ふと「コンビニで支払いってどうやるんだろう?」と思い試してみたときの記録です。

  1. カートにゲームを追加します。

欲しいゲームのストアページなどから「カートに入れる」ボタンをクリックし、ショッピングカートに追加します。
ほかに欲しいゲームはなかったので「自分用に購入」ボタンをクリックし次に進めます。

1

  1. 支払い方法を選択します。

ドロップダウンをクリックすると選べる支払い方法のリストが表示されます。
この中から「コンビニ」を選択し「続ける」ボタンをクリックします。

支払い方法の選択画面でコンビニ店頭名や『ファミポート』『Loppi』など知っている店頭端末の名前が表示されなかったので、戸惑ったのですが、このあとの画面で選択するようです。

2

  1. 支払金額と契約条件を確認します。

内容を一読したら、契約条項にチェックを入れ、「Degicaに進む」ボタンをクリックし次の画面に進めます。

3

  1. 支払い情報の入力と支払いを行うコンビニを選択します。

支払い情報の入力と支払いを行うコンビニを選択します。
支払い情報で入力したメールアドレスに店頭端末で入力する受付番号などが送られてきます。

今回はローソンで支払いを行いたいので、ローソンをチェックします。
「購入」ボタンをクリックし次の画面に進めます。

4

  1. 支払い方法の確認を行います。

ゲーム本体の金額のほかに決済手数料がかかる旨、コンビニ店頭で支払いを行うための受付番号などとあわせて店頭での支払い手順が表示されます。
受付番号は、ひとつ前の画面で入力したメールアドレスにも送られてきます。

5

送られてくるメールアドレスは、以下のような内容です。
支払いを行うコンビニによって、受付番号や確認番号などが変わってくるようです。

5-0

Steamクライアントは、コンビニでの支払い待ち状態である旨が表示されます。

6

  1. コンビニ店頭で支払いを行います。

ローソンでは店頭端末Loppiを使って、支払いの申し込みを行います。
端末からの操作は、トップ画面の「各種番号をお持ちの方」から進むと簡単に進められます。

Loppiでの申し込み処理が完了するとレシートが発行されます。
このレシートを持ってレジに行きお金を払います。

5-1

レジで支払いを行うと領収書が発行されます。

5-2

  1. ゲームがライブラリに追加されます。

支払い完了後、どのぐらいで有効化されるのかと思ったのですが、タイミングが良かったのか数分と経たずに有効化されていました。

また、レジで発行された領収書は今回は使用しませんでしたが、トラブルなどが発生したときは必要になるのかもしれません。


今回は好奇心からコンビニ払いを試してみましたが、決済手数料を考えるとクレジットカードを使った支払いの方が安くて便利かもしれないですね。

そして、決済サービスのDegicaのサイト内で支払い手順がまるっと紹介されておりました(^-^;

パスワードがわからずログインできないWindowsに、どうにかしてログインしなくてはならないときに試した手順です。

2012年秋ぐらいの情報なので、リンク切れがあったり、手順が使えなくなっている可能性もあります。
パソコンの中のデータだけを取り出したい場合は、対象となるパソコンのハードディスクを取り出し、外付けHDDとして使えるケースに入れ、別のパソコンからつないでコピーした方が簡単でリスクが少ないと思います。

ここで記載された内容を権限を持たないコンピュータに対して行った場合、法的な責任を問われる可能性があります。また、コンピュータに修復できない深刻なダメージを与える可能性があります。
実際の作業にあたっては細心の注意を払い、ご自身の責任においてお試し下さい。

用意するもの

  • ブランクCD
  • USBメモリ

使ったもの

  • ophcrack

設定済みのパスワードの自動解析するツール(フリー)
http://ophcrack.sourceforge.net/

  • Kon-Boot

Windowsのパスワード画面を回避するツール($18.99≒1500円)
http://www.thelead82.com/kon-boot/konbootWIN.html

  •  Offline NT password & Registry Editor

Windowsのパスワードをクリアしたり、編集したりするツールhttp://pogostick.net/~pnh/ntpasswd/

 手順

  1. ophcrackのサイトからISOをダウンロードCDに焼いて、Windowsが入ったPCでブート
  2. ophcrack解析失敗
    (日本語ユーザ名かつパスワードが辞書にないっぽい)
  3. Kon-Bootのサイトでツールを購入
  4. レジストするとファイルがダウンロードできるようになるので、ファイルをUSBメモリにインストール
  5. Kon-BootをインストールしたUSBメモリからPCをブートする
    (USBメモリのKon-Boot→Windows起動という流れ)
  6. Windowsのパスワード回避成功
  7. データをバックアップ
    (この状態では、パスワード変更やリセットディスクの作成は行えない)
  8. Offline NT password & Registry Editorのサイトからファイルをダウンロード、USBメモリにインストール
  9. USBメモリからPCをブート、黒い画面でコマンドを叩きパスワードをクリア失敗
    (日本語ユーザ名が原因?)
  10. Administratorをパスワードなしで有効化
  11. パソコンを再起動しWindowsを通常起動、Administratorでログイン
  12. 目的のユーザのパスワードを変更

Windowsにログインすることが目的の場合、無効化されている(隠しアカウントになっている)Administratorユーザを有効化し、Administratorユーザでログインし、ユーザ管理ツールから目的とするユーザのパスワードを変更すればよいので、 手順の3~6、10~12だけでよいかもしれません。

コンピュータシステムについて、よくたずねられることに『保守』『保守契約』というものがあります。

システムは、「開発・構築をして、稼働し始めたら、おしまい」ということはなく、使いはじめたら日々問題なく安定して動かせるようにしていく必要があります。
この「問題なく安定して動かせるようにする」ことを『保守』、「保守を行います」という契約を『保守契約』と呼んでいます。

保守で行うこと

保守契約を結んだ場合、問題が起きたり問い合わせがあったときに即時対応できるよう、下記のようなことを行います。

  • 開発時に使用した資料や設計などドキュメントやプログラムソースコードの整理・管理
  • 開発・テストで必要になる環境の保持
  • システムを構成する製品のアップデートや業務上必要になる法制度の情報収集

これらは、いざというときに備える体制の準備です。

「システムを構成する製品のアップデートの情報収集」というのは重要な項目です。
近年はニュースなどで報道されているように、コンピュータやネットワークに対する不正な攻撃が日々とんでもなく発生しています。
構築時点では問題がないと判断されたソフトウェア製品も、稼働後になんらかのセキュリティ脆弱性が発見されることが多々あり、実際攻撃にも使用されています。
(参考事例: 『「PHPMailer」に重大な脆弱性、直ちにパッチ適用を』)
基本的に、システムの引き渡し後に発覚した脆弱性などの諸問題については、お客様の責任での対応・処置となります。
保守契約を結ぶことで、お客様に代わり構成する製品の脆弱性情報などを収集し、必要がある場合は、システムのアップデートなどを提案します。

必要に応じて下記のようなことを行います。

  • システムを構成するソフトウェアのアップデート前の事前検証
  • システムを構成するソフトウェアのアップデート
  • ハードウェアやネットワークのメンテナンス

中でも、「アップデート前の事前検証」というのは重要な項目です。
たとえば、多くのパソコンで使われているWindowsは、Windows 10になり従来のメジャーバージョンアップに匹敵するような大規模なアップデートが配信・適用されるようになりました。
事前検証なしでアップデートを適用してしまった場合、システムに重大な問題が生じ業務に支障をきたしてしまうことがあります。

私の経験では、2016年8月に配信されたWindows 10 Anniversary Update(以下、Anniversary Update)を適用した結果、Windowsのプリンタ管理方法に変更が生じて、それまで動いていたプログラムが動かなくなる現象が起きました。
帳票出力プログラムで帳票が出力できなくなるという致命的な問題でした。
経緯については、『Windows 10 Anniversary Update適用後にVB .NETで組まれたプログラムの動作が不安定になったら』にまとめました。

事前検証を行うことで、アップデート適用時のリスクをあらかじめ知ることができ、問題を回避できるようになります。

日常的な業務としては問い合わせ対応も行います。

  • 操作に関する問い合わせ
    「〇〇〇をしたいのだけれど手順はどうすればよいか」といった問い合わせです。
    お客様がシステムに慣れていくにつれ徐々に減っていきますが、年次処理などごくごくたまにしか使用しない機能を中心に割と頻繁に発生します。
  • 仕様に対する問い合わせ
    「これはできたかな?」「こうなるといいな!」といった問い合わせです。
    日常的にシステムを使っていただいていると常に発生する問い合わせで、システムの課題発見や機能改善につながります。
  • 調査
    「〇〇〇をしたら△△△になったんだけれど…」といった、システムを使っていて発生した事象に対する調査依頼などが該当します。
    調査の結果、なんらかの修正が必要になった場合、発生要因や納品後の経過時間などにより「瑕疵担保責任で対応」や「有償対応」にわかれますが、一般的に事象の発生原因の調査までは保守の範囲内で行います。

問い合わせや課題を管理し、お客様と開発者側で認識を共有することで、業務や要望の変化にシステムを適宜対応させることができるようになります。
(発生した事象が数年に一度あるかないかの例外中の例外なのか、頻度はそれほど高くはないがシステムとしても考慮すべき事象なのかを切り分け、改修の判断材料とするなど。)

保守契約を結んでいない場合はどうなるか

契約にもよりますが、納品・検収の一連の流れが完了した時点で、すべて忘れます。
(もちろん、瑕疵担保責任に備えた最小限の体制は敷きます(^-^;)

契約上問題がないのであれば、ソースコードなどデータ・ドキュメント類のバックアップなどは取りますが、契約によってはそれらをすべて返却または破棄することもあります。この場合は、作業をした人の記憶だけが頼りです。
また、開発で使用した開発環境などもハードディスク上から削除したり、クラウド上で作業を行った場合は契約解除したりしてしまいます。
保守が必要になったとき、「作ったところだから、なにかしらは知っているだろう」と思いたいところですが、あまり期待はできないと思います。

問題や問い合わせが発生した場合は、必要な資料やソースコードの取り寄せ、開発・検証環境の整備、仕様の確認、事象の調査…など、一連の作業を最初からやり直すので、対応完了までに多くの時間と費用が必要になります。

保守費について

一般的に、『保守費』はシステム構築にかかった費用から算出され、月額や年額などで保守業者へ支払います。
保守費の目安としては、構築費の10~25%程度が多く、15%前後が相場と言えると思います。

たとえば、350万円で構築したシステムの場合、年額で52.5万円程度(15%で計算)ならば、妥当と言える金額です。

ただ、保守費は契約内容により金額が大きく変動する部分です。
提示された金額を見て、「ん!?( ゚Д゚)  工工エエェェェェェェェ(゚Д゚)ェェェェェエエエ工工 」となった場合は、保守業者に保守の範囲と内容について確認をした方が良いと思います。

保守費は、「いざというときに備える体制の準備」に対しての費用と見ることができ、保険料や顧問料のような性質があります。
ですので、その月その年の中でなにも起きなかったとしても支払いの必要が生じます。

諸々の事情により「保守契約を結ばない」「保守契約を打ち切る」という選択をすることもあると思います。
この場合、保守が必要になった際に「スポット保守対応」として通常よりも割高な保守費を請求されることがあるので注意が必要です。
(会社によっては保守そのものを拒否されることもあるようです)

また、「構築時には保守契約を結ばなかったけれど、2年後に問題が生じ、やっぱり保守契約を結びたくなった」というケースもあるかと思います。
この場合、契約時点からの請求ではなく、構築時点に遡及して請求されることがあるので注意が必要です。
「構築時に保守契約を結んだものの途中契約を打ち切り、再度保守契約を結びたい」といったケースでも、打ち切った時点に遡って請求されることがあります。

保守契約を結べばシステムで起きる問題すべてに対応してもらえるのか?

「では、保守契約を結べばシステムで起きる問題すべてに対応してもらえるのか?」という疑問がわきますが、これはほとんどのケースで「NO」です。
保守契約を結んでいても、契約で定めた範囲を超える作業・負荷が生じた場合、別途費用が発生します。

たとえば、「月に3回までの問い合わせ、のべ20時間分まで対応」と定めてある場合、4回目以降の問い合わせや、1回目の調査でも20時間を超える作業が生じたときは、保守費とは別に費用が発生します。

「全部コミコミで面倒を見て!」と言いたくなるところですが、この場合、前述した構築費の10~25%で算出とはならず、過去の実績(類似するケースなど)や考えられるリスクなどから算出されると思います。
(技術者は起こりうる事象を多方面多角的に考え悲観的に見る傾向が強いので、それらすべてに対応するとしたら…と見積もり、おそらく高額になります(^-^; 逆に、著しく安すぎる金額が提示された場合は、起こりうるケースを過少に評価しすぎていて、実際に問題が起きたときに対応が取れないといったこともあるようです。)


『保守』について書きましたが、ぶっちゃけ『運用』と呼ばれる領域も含まれています。
定義的には、保守は問題が起きないように保持する業務、運用はシステムを安定して動かす業務とされていたはずです。
最近は、「運用」「保守」がセットになっていることが多く、どちらも「システムをうまいこと動かす」という目的は共通しているので、はっきりとわけずにモヤっとしたまま、ふたつまとめて「サポート」と呼んだりもします。
実際にどこまでを範囲とするのかは、契約次第といった感じでしょうか。

「保守契約を結んだ方がよいのか?」というのが一番の関心事だと思うのですが、私感では「いざというときに相談できる相手がいる」というのは大きなメリットだと思います。
システムを長く使い続けるためには日常的に課題を整理解決していく必要があり、円滑に課題を整理解決する手段として保守契約は有効な解なのではないかと思います。