Duke 画像の再配布ページを作りました

かつて https://duke.kenai.com/ で配布されていた Duke の画像を再配布するページを作りました!
Redistribution of Duke images
https://yujisoftware.github.io/Duke/

これは何?

Java のマスコットキャラクター "Duke" の画像は、これまで https://duke.kenai.com/BSDライセンスのもと配布されていました。
しかし、この kenai.com は 2017年5月に閉鎖され、その影響で Duke の画像も取得できなくなってしまいました。


それは困る…、ということで再配布しようというのがこのページです。

ライセンス的に問題ないの?

上記のサイトで配布されていた画像は「BSDライセンス」なので、もとのコピーライトを保ったまま再配布するのは問題ありません。ただ、元ページにはBSDライセンスであることは明記されていたのですが、コピーライトが見当たらなかったので、ちょっと大丈夫か不安です…。*1

今後の予定

作っているときに気づいたのですが、現在 Open JDK で「Project Duke」が立ち上がっています。このプロジェクトで、公式に Duke を再公開していく予定だそうです。
CFV: New Project: Project Duke
OpenJDK Census

自分のページは、上記のプロジェクトでページが作られたタイミングでそこへのリダイレクトに変更する予定です。


ただ、それがいつになるかはわからないので、それまでのつなぎとして使っていただければと思います。
ぜひご利用ください!

*1:たぶん、色んな人が作った画像なので一律で明記できなかった?

JJUG CCC 2017 Spring ( #jjug_ccc ) - セッション資料の一覧

JJUG CCC 2017 Spring に行ってきました!

(感想をあとで書く)

さて、まだ公式で公開されていなかったので、残念ながら時間がかぶってしまって参加できなかったセッションもあったので、あとで読むために現時点で発表者の方が公開されている資料一覧をまとめしました。*1
(あとで JJUG CCC 2017 Spring のページにもリンクが載ると思うんですが、とりあえず自分の方で調べました)


Room A+B+C+D

Room C+D

Room E

*1:発表者のお名前は敬称略とさせていただきました。

今回も、JJUG CCC 2017 Spring の時間別タイムテーブル(セッション一覧)を作りました


5月20日(土) に開催されるJJUG CCC 2017 Spring「時間別」タイムテーブル(セッション一覧)が欲しかったので、前回同様にページを作りました!
JJUG CCC 2017 Spring - Timetable (非公式)
http://yujisoftware.github.io/jjug-ccc/2017-Spring/

新機能「お気に入り登録」

今回から「セッションのお気に入り登録」ができるようになりました!
お気に入り登録をすると、そのセッションが黄色くハイライトされます。


セッションタイトルを長押しするか、★ボタンをタップで登録できます。


ぜひご利用ください!!

パソコンのディスクアクセスランプがずっと点きっぱなしになってるときの調査方法

「なんかパソコンが遅いと思ったら、ディスクのアクセスランプがずっと点きっぱなしになってる…。なんでー!?」というときがたまによくあります。
そんなときの調査方法です。

ディスクアクセス原因の調査方法

まずは Process Monitor をダウンロードして起動します。
すると Filter 設定を聞かれるので、今回はそのまま OK ボタンをクリック。

続いて、ツールバーで、「Show File System Activity」のみを選択します。


すると、アクセスを行ったプロセスとパスの情報がバーっとすごい勢いで表示されます。


これを見ていてピンとくる場合もありますが…。
よくわからない場合は「Tools」→「Process Activity Summary」を表示します。
そんでもって、[File Events] 列をクリック(ソート)します。

上記の場合は avgcsrva.exe というプロセスが大量にディスクアクセスしているようです。
こいつが犯人ですね。


このプロセスの詳細を確認するには、メインウィンドウのリストから該当プロセスの適当な行をダブルクリックします。
そこから、Process タブや Stack タブを見ると詳細がわかります。

今回の場合は「AVG Scanning Core Module」(アンチウィルスソフト)がウィルススキャンを裏で勝手に行っていたのが原因のようです。
あとは、プロセスを殺すなり、設定をいじったりして止めれば解決です。


謎のディスクアクセスのせいでパソコンが重くなると イラっ(-_-) ときますよね…。
そんなときに、ぜひお試しください!

各言語での「翌月1日」の求め方

C# で「翌月1日」の DateTime を作るのに、こんなコードを書いてしまいました。

DateTime today = DateTime.Today;
DateTime nextMonth =
    new DateTime(today.Year, today.Month + 1, 1);

結果、12月1日になったら new DateTime(2017, 13, 1) となってしまい、「System.ArgumentOutOfRangeException: Year、Month および Day パラメーターが表現できない DateTime を示しています。」 で落ちました。
適当なツールだったからよかったものの、本番のコードだったらと思うとぞっとします。
(日付のバグはテストで見つけにくいです…)


そこで、復習を兼ねて各言語ごとの「翌月1日の求め方」を確認してみました。
もっといい方法があるよ!って場合は教えてください\(^o^)/

C#の場合

AddMonths メソッドを使います。

DateTime today = DateTime.Today;
DateTime nextMonth =
    new DateTime(today.Year, today.Month, 1).AddMonths(1);

ちなみに、これを new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1) って書くのはアウトです。
ほとんど起こらないぐらい極めててまれな確率ですが、第一引数の評価時と、第二引数の評価時で年をまたいだら日付がおかしくなるというバグになります。
現在時刻を処理するときは、変数に代入しておいたほうが安全です。

Java の場合

Date and Time API を使うと便利です。

 LocalDateTime nextMonth = 
     LocalDateTime.now()
                  .truncatedTo(ChronoUnit.DAYS)
                  .withDayOfMonth(1)
                  .plusMonths(1);

ちなみに、年月までで切り捨てる処理を truncatedTo(ChronoUnit.MONTHS) って書いたら、 ''java.time.temporal.UnsupportedTemporalTypeException: Unit is too large to be used for truncation'' でした。

JavaScript の場合

C#Java と異なり、範囲外の値を入れると繰り越し・繰り下げしてくれます。
なので、単純に加算するだけでオーケー。

let now = new Date();
let nextMonth =
    new Date(now.getFullYear(), now.getMonth() + 1, 1);

一番わかりやすいですが、最初にも書いたように C#Java ではだめなので要注意ですね…。

main メソッドは private クラスに書いても動く?

static なメンバー・クラス*1は、以下のように "private" として宣言できます。
この時、"java Main$Internal" と打ってこの private クラス内の main メソッドを起動できるのでしょうか。

class Main{
    private static class Internal{
        public static void main(String[] args){
            System.out.println("Hello world!");
        }
    }
}

答え:できる

Java の main メソッドは、以下のすべての条件を満たしている必要があります。*2

  • public かつ static メソッドであること
  • 戻り値の宣言は void であること
  • メソッド名は main であること
  • 引数は1つであること
  • 引数で String の配列を受け取ること


メソッドに関しては制約がありますが、クラスに関してはロードできれば OK とのこと。
なので、private なクラスでも問題なく起動できるようです。


そもそも、javap してみた限り、コンパイルした段階で private クラスであるという情報は消えるていので、判断しようがなさそうです…。

*1:「static 内部クラス」と書かれていることもありますが、これは間違い。言語仕様の 8.1.3 で「static ならば内部クラスではない」と明記されています。

*2:Java 仮想マシン仕様には、5.2 仮想マシンの開始 で「その *public クラス* の メソッド void main(String[]) を起動する」とりますが、これは誤訳か原文の間違いかと。

64bit 版の Windows に Java 1.1 をインストールする

誰得な気がしなくもないですが。


Java 1.1 は、いまでも Oracle Java Archive からダウンロードできます。
Java Archive Downloads - Java SE 1.1


しかし、これを 64bit 版の Windows にインストールしようとすると、インストーラの一部が 16bit アプリケーションなので、途中でエラーになります*1

                                                    • -

サポートされていない 16 ビット アプリケーション

                                                    • -

64 ビット バージョンの Windows での非互換性のため、プログラムまたは機能である
"\??\C:\USERS\TEST\APPDATA\LOCAL\TEMP\~EXB0000\setup.exe" を開始または実行できません。ソフトウェア製造元に問い合わせて 64 ビット Windows 互換バージョンが利用可能であるかどうか確認してください。

回避策

ReactOS プロジェクトの成果物を使えば、上記のエラーを解消してインストールができます。
(大抵の古い 16bit インストーラーは、これを使ってインストールができます)


まずは前段階として、Java のインストールファイルを入手します。

  1. jdk-1_1_8_010-windows-i586.exe を実行
  2. 前述のエラーダイアログが表示されたら、OKボタンを押さずに "%TEMP%\~EXB0000" *2を開く
  3. フォルダ内のファイルを、すべて適当なフォルダーにコピー
  4. エラーダイアログを閉じる

続いて、ツールをダウンロードして実行します。

  1. ReactOSInstallSheild Engine 3.0 16bit ランチャー解凍ツール (Is3Engine.zip) をダウンロード
  2. "Is3Engine.zip" を展開
  3. 展開すると "setup32.exe" があるので、コピーした Java インストーラと同じフォルダへ移動
  4. "setup32.exe" を実行

これで昔懐かしいインストーラが起動するので、あとは指示に従ってインストールすれば完了です。

ところで動くの?

「インストールできても、動くの?」と思うかもしれませんが、大丈夫です、動きます。
Windows の互換性すごい…。

D:\Java>C:\Program Files (x86)\Java\jdk1.1.8\bin\java.exe -version
java version "1.1.8"

D:\Java>:\Program Files (x86)\Java\jdk1.1.8\bin\java.exe Main
Hello world!


初期の Java に触れてみたいという方はお試しあれ。

*1:Java 自体は 32bit アプリケーションです。

*2:ファイル名を指定して実行ダイアログで、"%TEMP%\~EXB0000" と入力すれば開きます