yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2017/11 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
冒涜教育
2007/05/16(Wed)22:42:29
 道徳教育、正式教科化を見送り。戦後教育を受けた人であれば、大抵の人は道徳の授業を受けた経験があるはずですが、あれは「正式教科」ではなかったことになります。では何をもってすれば「正式」なのかといいますと、前提条件の「教科専門の免許」「検定済み教科書の使用」「成績の数値による評価」の3つを満たす必要があるのだそうです。
 言うまでもありませんが、このような前提条件に従わなければならない限り、道徳は永久に正式教科になってはいけません。特に「成績」など、道徳に成績をつけられたり、5段階評価されたりしてはたまったものではありません。教科の性質上、「答え」は十人十色なのですから、恣意的な方法以外では成績をつけることすらできません
 「恣意的」な例としては、国があらかじめ「正しい答え」を用意しておき、その答えに近い感想を述べたり提出したりした生徒に高評価、そうでない場合には低い評価を与えることなどが考えられます。または、国がこれに関与しなくても、教師が気に入る答えを出した生徒は高評価、そうでなければ低い評価にならざるを得ず、公平な成績付けなど望めません。
 このようなことが認められてしまうと、例えば道徳の授業で「戦争中、A君のお父さんは兵隊として戦って戦死してしまいました。これについてどう考えますか?」という問題が出たとして、国が「解答例」として「国や家族のために戦ったA君の父は偉いと思う」だの「こうした戦死者のおかげで私達の今の日本がある」だのといった答えを例示し、これをなぞるような答えには高評価、「A君が気の毒だ」「戦争で犠牲になるのは一般市民だけだ」「戦争は許せない」のような答えに低評価を与える危険が出てきます。高い成績を出したければ国が用意した「ひな形」に沿うような答えを出す必要があり、また教師もそのような答えが出るよう誘導することでしょう。このような道徳教育は一切不要です。
 道徳の授業自体はあって良いですし、道徳を重視する姿勢も悪くはありませんが、問題はこれが他ならぬ安倍内閣の教育再生会議に載せられたことです。皆様ご存知の通り、教育再生会議や安倍教育改革案で論じられるテーマといえばろくなものがありません。バウチャーといい、学力テストといい、議論の価値すらないものを結論ありきで議論した挙句、本当に採用してしまったりするのです。道徳にしても、一歩間違えば「道徳の押し売り」が始まりかねません。
 考えすぎと言うなかれ、実は似たようなことがすでに起こっているのです。福岡のとある中学校で何年か前に起きた問題なのですが、生徒に「赤紙」に似せたプリントを配り、そのプリントには「召集令状が届いたら、あなたは戦争に行きますか?」という設問がありました。そこで「戦争に行かない」選択をし、理由として「戦争は怖いし、人を殺したくない」と書いて提出した生徒が何人かいたそうですが、教師は何とそうした意見が述べられたプリントに「非国民」とだけ書いて返却したのです。
 これを書いた教師が一体何を考えていたのかは分かりませんが、もし道徳に数値評価が存在するようであれば、この「非国民」の生徒らの成績は相当低く評価されていたことでしょう。また、仮にこの教師が「戦争に行く」選択をさせるように授業を行い、その結果として「戦争に行かない」生徒に「非国民」などと書いてよこしたのだとすれば、授業が恣意的・誘導的に進められていたことになります。
 道徳教育は足し算や引き算ではないのですから、余程テーマからかけ離れた答えを除けば、基本的にあらゆる答えが許容されてしかるべきです。上記の例でいえば「戦争に行く。なぜなら家族や市民を守りたいから」と「戦争に行かない。戦力が不足すれば戦争が早く終結し、家族や市民を守れるから」は同等に扱われるべきで、国の意図や教師の好みでどちらかの成績が高くなるようなことがあってはなりません。また、「道徳の押し売り」があってもなりません。道徳の押し売りなど、本質は軍国教育と全く同じです。
 今回は何とか取り下げられましたが、道徳に点数をつけるなどとんでもない話ですし、そうでなくとも安倍内閣が道徳教育の変質を狙っている可能性は十分にあります。「非国民」などと書いてよこされるような道徳教育が「政府公認」になることのないよう、注意深く観察する必要がありそうです。

 さて、本日はEJBをと考えて開発していたのですが、何とAppServerがとんでもないことに。本当に想像を絶するようなことが起きてしまうものです。
 まず、「asadmin start-domain domain1」で起動しようとしたところ、なぜか例外を投げられて起動しません。これでデプロイしてサクサクとデバッグを進めるつもりであったにもかかわらず、これで一気に勢いをそがれました。無論、以前にEJBをデプロイして以降、AppServer周りには一切触れた覚えがありません。そもそも触れる理由がありません。
 このような場合はあわてずにログを見てみれば良いのですが、これまた奇妙なことにログの更新日時は書き換わっているにもかかわらず、内容は一切変更されません。つまり、ログを見て原因を特定することができないのです。原因不明の例外が発生する上、例外の原因も特定できないのでは、対処のしようがありません。
 これでは仕方がありませんから、AppServerを削除してインストールしなおすことにしました。とはいっても、現在使っているAppServerはglassfish b38ですから、単にディレクトリを削除するだけでアンインストール完了です(あくまでglassfishの場合。「Sun Java System Application Server」としてインストーラ付きで配布されているAppServerであれば、コントロールパネルからアンインストールします)。
 それが終わったらインストールを行うわけですが、せっかくインストールしなおすからには新しいバージョンを使いたいところです。glassfishにはいくつかのブランチが存在するのですが、今回ダウンロードしたのは「v2 Beta2」の「41d」でした。素直に「Main branch」からダウンロードすべきであったと、後に後悔することになるのでありました。
 とにかくこれをインストールし、setup.xmlを最小限編集し、起動してみました。見た目はb38とそれほど変わらないようです。しかし、ありがたいことにMySQLのXADataSourceで最初から入力されているクラス名が正しいものに直されています。しかもご丁寧にも、最初からプロパティを100個以上用意してくれています。これまでは「user」や「password」などの最小限のプロパティ(10個前後)しか用意されていませんでしたが、それが何と100個です。こちらは正直なところ邪魔です。
 b38の時に登録できずに散々困ったJMSリソースは普通に「new...」できるようになっていました。これならさほど苦労することなくJMSを設定することができます。これであっという間に設定が完了してしまいました。この時点ではアップグレードして良かったと考えた私ではありましたが、悲劇はこの後に訪れたのです。
 とりあえず最初にMessageDriven Beanでも動かしてみようと考え、以前に作った「備品台帳」プログラムをデプロイし、動作させてみることにしました。しかし、JMSでメッセージを送った直後からPCが非常に重くなり始めたのです。しかもJMSでMessageDriven Beanに送ったはずのデータはEntityに登録されていません。一体どうなっているのでしょうか。
 ひとまずログでも見てみようと、あらかじめ開いておいたログディレクトリのウィンドウを表示した時に、ようやくこの異常な重さの原因が分かりました。AppServerは(デフォルトの設定では)ログが2MB程度になると、そのログファイルを日付入りの名称にリネームし、新しいログファイルを作成するようになっています。つまり、リネームされた古いログのサイズはすべて2MB前後になります。そして、その2MBもある古いログのファイルが目の前で次々と生成されていくのです。
 この時点で何が起こっているのかが分かりました。何らかの理由によって処理が無限ループに陥っており、エラーか何かを延々とログに吐き出しているのです。とにかくAppServerを終了させなければなりませんが、stop-domainでは止まりません。タスクマネージャを使って必死で強制終了しましたが、タスクマネージャが表示されるまでに非常に時間がかかり、何とか強制終了した時にはログファイルが50個以上生成され、その総サイズは100MBを超えていました。もう少し強制終了が遅れていたら、このログがHDD容量を食い尽くしてしまい、面倒なことになっていた可能性があります。
 とにかく、このような危ないものはとても使えたものではありません。即座にアンインストールし、Main branchからb46をダウンロードしてきました。これをインストールした後、とにかくデータベースの設定を行い、適当なEJBを試してみることにしました。
 しかし、そこで待っていたのは原因不明のトランザクションエラーの嵐でした。しかもおかしなことに、データを単に読むだけならエラーが出ないにもかかわらず、EAGERリードであったり追加・更新・削除の動作であったりする場合にはエラーが出るのです。ログを見て分かるのは、少なくとも私のコーディングが間違っていないことだけです(以前に動作したものをテストに使っているのですから、コーディングが間違っているわけがありませんが)。
 しかも、これらの操作は時々動作することがあります。しかも、それがきっかり2回に1回であったり、8回に1回であったりと、奇妙な動作を見せることも分かりました(何度試しても全く動かないこともあります)。このようなことが本当に起こるのでしょうか。
 試しにMySQL側で「show processlist」してみたところ、AppServerがいくつかの接続をプールしており、接続が必要になった際には最後に使われた日時が最も古いものから使われていることが分かりました。つまり、2回に1回成功する場合には、接続のどちらか片方が正しく動作する側で、もう片方が動作しない側、というわけです。8回に1回であれば、接続8つのうち7つが動作しない接続、1つが動作する接続となります。
 実際にshow processlistの結果を見ながら、使えないらしい接続をkillして再接続させてみたところ、これで動作するようになる場合もありました。ところが、せっかく動作するようになったとしても、しばらく時間が経つと動作しなくなってしまいます。さらに、登録・更新・削除の動作は非常に成功率が低いです。これではとても開発どころではありません。
 この怪奇現象の数々、一体どのように考えれば良いのでしょう。結論としては「glassfishの信頼性はせいぜい新聞レベルであり、疑ってかかるべきである」といったところでしょうか。

 これでは何ともなりませんから、他の開発を。Java SE 6では「スプラッシュ」がサポートされています。アプリケーション起動時にアプリケーションのロゴが表示されるアレです。あれは単なる飾りではなく、起動の待ち時間によるイライラを軽減する効果を持っています。特にPhotoShopのスプラッシュなどは作業工程が表示されるため、起動のイライラがかなり軽減されます。
 それではまずスプラッシュを表示する方法から。とはいっても、さほど難しいことはありません。単に「-splash」引数を使えば良いのです。次のようなコマンドを打つことで、最初にAWTあるいはswingウィンドウが表示されるまでスプラッシュが表示されます。
java -splash:splashimagefile ClassName
 スプラッシュに関するコーディングをしていなくても、このコマンドだけでスプラッシュを使用することができます。JARの場合はマニフェストでスプラッシュを指定できるそうです。逆に言えば、splash引数がなければスプラッシュは使えないという奇妙な仕様になっており、コード内でスプラッシュを生成して使用することはできません。
 ただ、Graphics2Dでスプラッシュの上から描画を行うことはできます。まず適当に「logo.gif」を作成しまして、とりあえず作業状況進捗バーでも描画してみましょうか。
// Main.java
public class Main{
	public static void main(String args[]) throws Exception{
		Frame f = new Frame();
	}
}

// Frame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;

public class Frame extends JFrame implements WindowListener{
	public Frame() throws Exception{
		addWindowListener(this);

		SplashScreen ss = SplashScreen.getSplashScreen();
		if(ss != null){
			SplashThread st = new SplashThread(ss);
			st.start();

			synchronized(this){
				for(int i = 0; i < 50; i++){
					try{
						wait(100);
					}catch(InterruptedException e){
					}
					st.setProgress((double)i / 50);
				}
			}

			st.end();
			ss.close();
		}

		setSize(200 , 200);
		setVisible(true);
	}
	public void windowActivated(WindowEvent e){
	}
	public void windowClosed(WindowEvent e){
	}
	public void windowClosing(WindowEvent e){
		dispose();
	}
	public void windowDeactivated(WindowEvent e){
	}
	public void windowDeiconified(WindowEvent e){
	}
	public void windowIconified(WindowEvent e){
	}
	public void windowOpened(WindowEvent e){
	}
}

// SplashThread.java
import java.awt.*;

public class SplashThread extends Thread{
	private SplashScreen ss;
	private volatile boolean loop;
	private Graphics g;

	private double progress;
	public SplashThread(SplashScreen ss){
		this.ss = ss;
		g = ss.createGraphics();
		loop = true;
	}
	synchronized public void run(){
		while(loop){
			draw();
			try{
				wait(50);
			}catch(InterruptedException e){
			}
		}
	}
	public double getProgress(){
		return progress;
	}
	public void setProgress(double p){
		if(p > 1)
			p = 1;
		if(p < 0)
			p = 0;
		progress = p;
	}
	synchronized public void end(){
		loop = false;
		interrupt();
	}
	public void draw(){
		Dimension d = ss.getSize();
		int width = d.width - 2;
		int height = d.height - 1;

		g.setColor(Color.black);
		g.fillRect(1 , height - 5 , width , 5);

		int len = (int)(progress * width);

		g.setColor(Color.blue);
		g.fillRect(1 , height - 5 , len , 5);

		g.setColor(Color.white);
		g.drawRect(1 , height - 5 , width , 5);

		ss.update();
	}
}
 後はこれを引数付きで実行します。
java -splash:logo.gif Main
 注意点としては、スプラッシュ画像の範囲を超えて描画することはできません。ですから、例えばスプラッシュの下に文字列を表示したければ、スプラッシュ画像の下にある程度の余白を用意しておかなければなりません。ワク線などはあらかじめ画像に入れ込んでおくか、自分でワク線を描画しても不自然にならないような画像を作っておく必要があります。
 とにかく実行してみましょう。正しく進捗状況が表示されるでしょうか。


 このロゴは手元にあったものを使用したものであり、アプリケーションの内容(単にウィンドウを表示するだけ)とは一切関係ありません。

 これがスプラッシュ機能ですか。Java SE 6のウリの1つにしている割には、どうも不便さが目立ちます。しかし、VMの起動時からしっかりスプラッシュを表示してくれるため、起動開始直後から表示できるのがメリットでしょうか。実際、上記の進捗状況バーにしても、最初に画像が表示され、少し遅れてバーが表示されます。バーは起動直後に描画するようにしているのですが、それでもスプラッシュの方が先に表示されることを考えると、スプラッシュはおそらくmain()に入る前から表示されているのでしょう。自分でスプラッシュを表示するのであれば、バーが表示されるタイミングでスプラッシュを表示することしかできません。
 しかし、自分でスプラッシュを使えた方が自由度が高いことは言うまでもありません。しかもこれならJava SE 6でなくても使えます。SE 6のスプラッシュ機能の利点と欠点を習得したからには、こちらも試してみたいところです。
// Main.java
public class Main{
	public static void main(String args[]) throws Exception{
		Main m = new Main();
		m.main();
	}
	public void main(){
		SplashFrame sf = new SplashFrame(300 , 100);
		sf.start();
		synchronized(this){
			for(int i = 0; i < 5; i++){
				sf.setText("Please wait for " + 
					(5 - i) + " second(s) about.");
				try{
					wait(1000);
				}catch(InterruptedException e){
				}
			}
		}

		sf.end();

		TestFrame f = new TestFrame();
	}
}

// SplashFrame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SplashFrame extends JFrame implements Runnable{
	private Image splash;
	private volatile boolean loop;
	private Thread thread;

	private Image surface;
	private Graphics g;

	private int width;
	private int height;
	private String text;

	private Object lock = new Object();
	public SplashFrame(int w , int h){
		Toolkit tool = Toolkit.getDefaultToolkit();
		splash = tool.getImage("logo.gif");
		text = "";

		Dimension d = tool.getScreenSize();
		int sw = d.width;
		int sh = d.height;

		int x = sw / 2 - w / 2;
		int y = sh / 2 - h / 2;

		setUndecorated(true);
		setBounds(x , y , w , h);
		setVisible(true);

		surface = createImage(w , h);
		g = surface.getGraphics();

		loop = true;
		width = w;
		height = h;

		thread = new Thread(this);
	}
	public String getText(){
		return text;
	}
	public void setText(String t){
		text = t;
	}
	public void start(){
		thread.start();
	}
	public void run(){
		synchronized(lock){
			while(loop){
				repaint();
				try{
					lock.wait(50);
				}catch(InterruptedException e){
				}
			}
		}
	}
	public void end(){
		synchronized(lock){
			loop = false;
			lock.notify();
			g.dispose();
			dispose();
		}
	}
	public void paint(Graphics graphics){
		if(g == null)
			return;

		g.setColor(Color.black);
		g.fillRect(0 , 0 , width , height);

		g.drawImage(splash , 0 , 0 , null);

		g.setColor(Color.white);
		g.drawString(text , 5 , height - 5);

		g.drawRect(0 , 0 , width - 1 , height - 1);

		graphics.drawImage(surface , 0 , 0 , null);
	}
}

// TestFrame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;

public class TestFrame extends JFrame implements WindowListener{
	public TestFrame(){
		addWindowListener(this);
		setSize(200 , 200);
		setVisible(true);
	}
	public void windowActivated(WindowEvent e){
	}
	public void windowClosed(WindowEvent e){
	}
	public void windowClosing(WindowEvent e){
		dispose();
	}
	public void windowDeactivated(WindowEvent e){
	}
	public void windowDeiconified(WindowEvent e){
	}
	public void windowIconified(WindowEvent e){
	}
	public void windowOpened(WindowEvent e){
	}
}
 SplashFrameでlockなるロック用変数を使用していますが、これはsynchronized(this)を用いるとバグが発生するためです。具体的には、どうやらJFrame内でsynchronized(this)が使用されているらしく、dispose()などを使うと固まってしまいます。それにしても、一体どういう仕様になっているのでしょう。dispose()の実行時に固まるためには、AWT/swingが別スレッドでsynchronized(this)されたリソース破棄ブロックを呼び出し、dispose()を呼び出したスレッドがそのスレッドにjoin()される、程度のことしか考えられないのですが。
 それでは実行してみましょう。こちらは標準のスプラッシュ機能を使っていないため、単に「java Main」で結構です。



 このように、手作りならかなり自由に扱えるスプラッシュを作成できるのですが、さすがに少々お手軽ではなくなっています。それほど色々な操作をする必要がなければ、バッチファイルか何かに-splash引数入りで実行動作をまとめておくのが良さそうです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 2]
<- 前の記事を参照 次の記事を参照 ->

Comments(2)
yamicha.com - 2007/05/20(Sun)20:59:37
>H.Mさん
モラル教育などが必要であることには異論ありません。道徳が不要かは別として。
しかし、失礼ですが
1.「道徳教育が必要でない(かつモラル教育は必要)」という論拠が一切ない
2.不特定多数の方が目にする場であるのに、敬語、やわらかい表現などを使用しない
という点の方が強く気になりました。
不特定多数が閲覧し、通常は不適切とされる表現が特に許可されていない場においては、
適切な言葉を使用するのがモラルであり、マナーであり、エチケットであるかと存じます。

H.M - 2007/05/19(Sat)21:44:59
道徳教育は必ずしも必要ではない。
今必要とされる教育はモラル教育であり、マナー教育であり、エチケット教育である。

戦争観念云々は世界情勢がしっかり見極められるであろう高校以降に日本史及び世界時の授業で解の無い設問として出せばいい。

- Blog by yamicha.com -