yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/12 の記事
[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] [31]

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
ブログ - yamicha.com's Blog

 存在する記事 776 件の中から 31-35 件を表示しています。
谷悲歌
2010/01/18(Mon)00:27:51
 驚異的な発展を遂げつつある大国でありながら、未だに前時代的な厳しい検閲を続けており、各国から批判を浴びている中国ですが、ついにGoogle(現地名「谷歌」、「クーコー」と発音)が撤退をほのめかす事態となりました。Googleはすでに現地の検索エンジン「百度」に次ぐシェアを誇っており、非常に影響力の大きい企業であるだけに、中国政府としても神経を尖らせているようです。
 中国政府は厳しいインターネット検閲を導入しており、政府にとって都合の悪い情報を遮断したり、活動家らの通信を監視する上、参入してくる外資系企業には「協力」を求めるなど、ありとあらゆる手段で情報統制を実行しています。また、「金盾」といった強力な検閲システムの開発も進められており、総書記の胡氏はインターネット規制の甘さに不満をもらすなど、インターネットの自由がなおさら強く制限される可能性すら考えられる状況です。
 こうした政府の検閲を嫌う中国人は、内容が秘匿できない中国のメールアカウントではなく、Gmailなどの欧米のメールアカウントを使用し、通信内容の秘匿を図ろうとする傾向にあります。ところが、このほど中国人権活動家らのGmailアカウントが大規模なクラッキングを受けたというのです。
 クラッカーの正体や目的は不明ですが、中国政府が主導して攻撃を行っている可能性があるとされています。当然ながら中国側はこれを否定し、表面上は協力的な発言を行っていますが、実際に中国政府が本件を主導していたとしても、中国の体質からして全く不思議なことではありません。Googleが「撤退」を言い出した原因の1つとして、本件があることはおそらく間違いないでしょう。
 Googleは対抗措置として「協力」を一部解除し、今まで中国版Googleでは閲覧できなかった一部の情報を閲覧可能としました。Googleが中国政府をけん制し、譲歩を引き出すために「撤退」を言い出したのか、あまりの検閲のひどさに3億人市場を本気で捨てる覚悟をしているのかは定かではありませんが、ともかく現在の中国の言論統制が許されざるものであるのは言うまでもなく、悲観的な見方も決して少なくないながらも、本件が「アリの一穴」となることを期待します。
 かつて東欧の国々が連鎖的に民主化した際には、テレビの力も大きかったとされています。国家がどれほど情報を規制しようとも、海外から電波に乗って入ってくる情報まで統制することはできず、国民はリアルタイムに国外の情報を入手できたため、これが連鎖的な民主化の一助になったというのです。
 それからおよそ四半世紀後の現代においては、世界各国で瞬時にして情報の共有が可能なインターネットが普及し、より早く容易に様々な情報が手に入る時代となりました。現在の中国と東欧革命時の諸国とでは状況も違い、あれほどの成果を望むのは難しいとはいえ、少なくとも中国政府がインターネットの力に脅威を感じているのは確かです。「テレビの力による民主化」の次の世代では、果たして「インターネットの力による民主化」は実現されるのでしょうか。

 ところで、中国にインターネットの自由が存在しないのは前述の通りですが、中国政府がGoogleのメールなどへの接続を遮断したり、インターネット規制を強化するための方便として、次のような言葉が良く使われています。

「Googleがポルノ情報を流している」
「わいせつな有害情報を広める行為を取り締まる」

 以前の記事で日本での児童ポルノ規制問題を取り上げましたが、中国のケースは「有害情報の規制」の御旗が政府や捜査権力の力を強める結果となることを非常に明確に示す実例です。ただ、これが単に政府の権力行使の言い訳として使われている分には、まだ問題が大きいとはいえません。最も問題なのは、この御旗が絶対的な正義として担ぎ出されてしまった場合です。
 大変残念なことですが、各種詐欺やチェーンメールの中には、他人の善意を利用したものが少なからず存在しています。このほどハイチで発生した大地震に関しても、早くも便乗した詐欺の発生が確認されているそうです。うっかりこの種の詐欺やチェーンメールに引っかかると、自分では善意で行動を起こしたつもりでも、他人に迷惑をかけてしまったり、詐欺師に原資を提供してしまう結果ともなりかねません。
 また、以前に「スマイリーキクチ事件」なるものが発生したことがありました。これは「タレントのスマイリーキクチ氏がコンクリート詰め殺人事件にかかわっていた」なる事実無根のデマが流布され、結果として氏が悪質な脅迫や名誉毀損を受けたもので、氏にとっては迷惑以外の何者でもない事件です。しかし、加害者の中には遊び半分の者も多かったとみられますが、中には本気でこの情報を信じてしまい、正義感に基づいてキクチ氏への攻撃を行っていた者も存在したのではないでしょうか。このように、「正義感の暴走」は時として逆方向に作用し、大変望ましくない結果をもたらします
 児童ポルノ規制問題にも、この懸念は当てはまります。確かに、実写の児童ポルノには確実に被害者が存在しますので、作成は到底容認できるものではありません。また、不特定多数への流布によって被害が際限なく拡大していくため、流通を抑制する仕組みも望まれるのは言うまでもありません。これらの点に関しては、おそらくほとんどの人が同意されるのではないでしょうか。
 しかしながら、ここで児童ポルノの規制に「善意」や「正義」を見出してしまうと、単純所持規制の多大な弊害も忘れ、単純所持規制を徹底することこそ正義という錯覚に陥ってしまいかねません。これがいかなる危険をはらんでいるかは、中国の状況を見れば明らかでしょう。「わいせつな有害情報を広める行為を取り締まる」との御旗の下に、国民の自由が取り締まられてしまうのです。
 さらに、児童ポルノ問題に強い怒りと問題意識を覚え、規制こそ正義であるとの錯覚に陥った状態では、「児童ポルノを見ると犯罪を起こす」「創作画像の児童ポルノにも同様の効果がある」などといった全く事実無根のデマでさえ、スマイリー事件のデマ同様に信じ込んでしまう恐れがあります。情報を注意深く分析さえしていけば、この程度のデマになど大抵は気づけるはずなのですが、錯覚に陥った状態ではそこまでの分析は難しいどころか、規制こそ正義で反対者は反正義とまで思い込むに至り、理性的な反論さえも感情論によって否定されてしまう事態ともなりかねません。児童ポルノ規制を情報統制の面から懸念している人に対して「それは言い訳にならない。被害者の苦痛が分からないのか」と理由も根拠もない感情論で反論したり、果ては「反対者は児童ポルノ愛好家」などと事実無根の偏見に基づく主張を始めるなど、人格否定に結びつく場合すらあります。
 今の日本にはインターネットの自由がありますが、中国の一件は決して遠い世界の出来事ではありません。民主党は単純所持の規制に消極的ですが、自民党はかなり積極的に単純所持を禁止しようとしており、さらには創作物をも規制する動きも一部に存在しています。今後自民党が政権を取り返す可能性は十分にありますし、そうでなくてはならないと私も考えていますが、ともかく日本でも単純所持や創作物も含めた規制が導入される可能性は目の前に存在するのです。
 その上、マスコミの一部や規制を主張する団体などは、すでに単純所持も含めた児童ポルノ規制を「絶対的正義」であるかのように報じており、信じ込んでしまう人も出かねない状況です。また、規制の範囲や方法はともかくとして、児童ポルノを何らかの形で規制する制度自体の必要性については、おそらく多くの人の見解の一致するところですので、情報統制の懸念を抱く者でも規制自体には反対しないという、一見すると分かりづらい構図ともなっています。これらのことから、今後決して遠くないうちに、主に情報統制への危機感が薄い人を中心として「正義感の暴走」が発生し、そのまま危険な規制の制定にまで至る可能性は十分にあります。しかし、それがいかなる結果を招くかといえば、中国が非常に分かりやすい実例を示してくれています。
 そのような意味で、中国の一件は日本にも大きな教訓を与えているといえるでしょう。

 JPA 2.0で新しく追加されたアノテーションに、@MapKeyColumnや@MapKeyJoinColumnがあります。Wikibooksの説明によれば、@OneToManyなどのプロパティに対してこれらを付加すると、それらのデータをMapとして扱えるようになるものであるようです。すなわち、通常の@OneToManyではListやSetなどのコレクション、あるいは配列が使用され、要素を順次取得できる一方、@MapKeyColumnや@MapKeyJoinColumnではキーを基に値を取得できる模様です。私は使ったことがありませんが、@MapKeyなるものは1.0から存在しているようで、似たようなものかもしれません。
 Wikibooksのサンプルでは、「従業員の所有する電話の種類」がキーとして用いられています。「phones.get("WORK")」なら仕事用の電話番号データを記録したエンティティのインスタンスが取得でき、「phones.get("CELL")」なら携帯電話のデータのインスタンスといった具合です。
 実際にこれを使うべき状況は、かなり限定されるのではないでしょうか。基本的に以下の2つの要件を満たさなくては、わざわざ@MapKeyColumnや@MapKeyJoinColumnを使う必要性に乏しいためです。

1.複数のキーに対し、必ず値が割り振られるとは限らないこと。あるいは、作成時点ではいかなるキーが使用されるか分からないこと。
 電話の例で言えば、もし最初から「仕事場」「自宅」「携帯電話」の3種類の電話番号データの登録が必要であると分かっているなら、work,home,cellの3つのプロパティを記述し、それぞれを@OneToOneにすれば済む話であり、いちいち本機能を使用する必要はありません。
 本機能を使用するのであれば、後から区分が増える可能性がある場合(例えば「事務所」「個人用携帯電話」「緊急連絡先」など)、あるいは区分が大量に存在し、しかも大抵はその大半がnullとなり、わざわざ@OneToOneプロパティを大量に書くと逆に非効率的な場合などになるでしょう。

2.キーが重複しないこと。
 Mapの仕様上当然です。電話の場合であれば、仕事用、固定、携帯電話などの番号データを各1つずつしか持たないのが原則となります。携帯電話を2つも3つも持っている場合、わざわざ「CELL1」「CELL2」などと名づけるのは、分かりづらい上に非効率的です。

 @MapKeyColumnと@MapKeyJoinColumnの違いは、キーの扱い方にあります。@MapKeyColumnの場合は、次のようなテーブルが生成されます。
employee
id	fname	lname
1	Larry	Wall
2	Ada	Lovelace
3	Agner	Erlang

phone
id	empid	type	number
1	1	home	11111
2	2	work	22222
3	2	cell	33333
4	3	home	44444
5	3	cell	55555
 この場合、例えばAdaの電話番号Mapから"cell"を取得すると、phoneテーブルのid = 3にあたるデータのインスタンスが得られます。
 @MapKeyJoinColumnの場合は以下のようになります。
state
id	name
1	StateA
2	StateB
3	StateC

position
id	name
1	Governer
2	PosA
3	PosB

officer
id	state	pos	name
1	1	1	Haskell Curry
2	1	2	Ada Lovelace
3	2	1	Agner Erlang
4	3	1	Grace Pascal
5	3	3	Larry Wall
 この場合、キーはpositionにあたるエンティティのインスタンスです。

 どちらかといえば@MapKeyJoinColumnの方に目新しさがあるため、今回はひとまず@MapKeyJoinColumnを使用してみました。@MapKeyColumnより若干面倒ですが、割と簡単な部類です。
/WEB-INF
 /classes
  /com
   /yamicha
    /mapkeyjoin
     Office.java
     Account.java
     Value.java
     MapKeyJoinAccess.java
     MapKeyJoinServlet.java
  /META-INF
   persistence.xml
 persistence.xmlには特筆すべき部分はありません。
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database"
        value="MySQL" />
      <property name="eclipselink.logging.level"
        value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>
 Entityは以下の通り実装しました。
// Office.java
package com.yamicha.mapkeyjoin;

import javax.persistence.*;
import java.util.*;

@Entity @Table(name="mapkeyjoin_office" , schema="yamicha")
	public class Office implements java.io.Serializable{
	private int id;
	private String name;
	// 今回はサンプルにつき資産(asset)のみ
	private Map<Account , Value> assets;

	public Office(){
		assets = new Hashtable<Account , Value>();
	}
	public Office(String n){
		this();
		name = n;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@OneToMany(mappedBy="office" , fetch=FetchType.EAGER ,
		cascade=CascadeType.PERSIST)
		@MapKeyJoinColumn(name="account")
		public Map<Account , Value> getAssets(){
		return assets;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String n){
		name = n;
	}
	public void setAssets(Map<Account , Value> a){
		assets = a;
	}

	public void link(){
		for(Value v : assets.values())
			v.setOffice(this);
	}
}

// Account.java
package com.yamicha.mapkeyjoin;

import javax.persistence.*;
import java.util.*;

@Entity @Table(name="mapkeyjoin_account" , schema="yamicha")
	public class Account implements java.io.Serializable{
	private int id;
	private String name;

	public Account(){
	}
	public Account(String n){
		name = n;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String n){
		name = n;
	}
}

// Value.java
package com.yamicha.mapkeyjoin;

import javax.persistence.*;
import java.util.*;

@Entity @Table(name="mapkeyjoin_value" , schema="yamicha")
	public class Value implements java.io.Serializable{
	private int id;
	private int price;
	private Office office;
	private int account;

	public Value(){
	}
	public Value(int p){
		price = p;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="price") public int getPrice(){
		return price;
	}
	@ManyToOne @JoinColumn(name="office") public Office getOffice(){
		return office;
	}
	@Column(name="account") private int getAccount(){
		return account;
	}

	public void setId(int i){
		id = i;
	}
	public void setPrice(int p){
		price = p;
	}
	public void setOffice(Office o){
		office = o;
	}
	private void setAccount(int a){
		account = a;
	}
}
 Value.javaにint accountプロパティを書かない場合、EclipseLinkが例外を投げてきます。しかし、普通に考えて書く必要のある代物には見えないため、JPA 2.0の仕様で要求されているものかは不明です。しかもデプロイ時にテーブルはしっかり生成され、デプロイ自体にも成功するものの、クエリを発行する段階で初めてエラーを出してくるという謎の挙動を見せてくれます。
 いつもながらいい加減ですが、Servlet/EJBは以下の通りです。
// MapKeyJoinAccess.java
package com.yamicha.mapkeyjoin;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.*;

@Remote @Stateless(name="MapKeyJoinAccess" ,
	mappedName="ejb/MapKeyJoinAccess")
	public class MapKeyJoinAccess{
	@PersistenceContext(unitName="MySQL") private EntityManager em;

	public void regist(){
		// まず科目を作成
		Account cash = new Account("現金");
		Account checking_account = new Account("当座預金");
		Account accounts_receivable = new Account("売掛金");
		Account notes_receivable = new Account("受取手形");
		Account product = new Account("製品");
		Account equipment = new Account("備品");
		Account goodwill = new Account("のれん");

		// 登録
		em.persist(cash);
		em.persist(checking_account);
		em.persist(accounts_receivable);
		em.persist(notes_receivable);
		em.persist(product);
		em.persist(equipment);
		em.persist(goodwill);

		// 各オフィスに科目ごとの金額を登録
		// 北朝鮮支店
		Office dprk = new Office("北朝鮮支店");
		dprk.getAssets().put(cash , new Value(150000));
		dprk.getAssets().put(checking_account ,
			new Value(1750000));
		dprk.getAssets().put(accounts_receivable ,
			new Value(350000));
		dprk.getAssets().put(notes_receivable ,
			new Value(800000));
		dprk.link();
		em.persist(dprk);

		// ミャンマー支店
		Office myanmar = new Office("ミャンマー支店");
		myanmar.getAssets().put(cash , new Value(640000));
		myanmar.getAssets().put(checking_account ,
			new Value(4000000));
		myanmar.getAssets().put(accounts_receivable ,
			new Value(500000));
		myanmar.getAssets().put(goodwill , new Value(720000));
		myanmar.link();
		em.persist(myanmar);

		// 阿久根支店
		Office akune = new Office("阿久根支店");
		akune.getAssets().put(cash , new Value(75000));
		akune.getAssets().put(checking_account ,
			new Value(1800000));
		akune.getAssets().put(product , new Value(1500000));
		akune.getAssets().put(equipment , new Value(9800000));
		akune.link();
		em.persist(akune);
	}
	public List<Office> getOffices(){
		return (List<Office>)em.createQuery(
			"SELECT o FROM Office o").getResultList();
	}
	public Office getOffice(Object id){
		return em.find(Office.class , id);
	}
}

// MapKeyJoinServlet.java
package com.yamicha.mapkeyjoin;

import javax.servlet.annotation.*;
import javax.ejb.*;
import javax.annotation.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.persistence.*;
import java.io.*;
import java.util.*;

@WebServlet(name="mapkeyjoinservlet" , urlPatterns={"/*"})
  public class MapKeyJoinServlet extends HttpServlet{
  @EJB(beanName="MapKeyJoinAccess") private MapKeyJoinAccess ma;

  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    doPost(request , response);
  }
  public void doPost(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();

    ma.regist();

    List<Office> offices = ma.getOffices();
    for(Office o : offices){
      out.println(o.getName());

      Map<Account , Value> assets = o.getAssets();
      for(Map.Entry<Account , Value> e : assets.entrySet()){
        out.println("t" + e.getKey().getName() + ": " +
          e.getValue().getPrice());
      }
      out.println();
    }

    out.close();
  }
}
 これを実行してみると、次の結果が表示されました。
北朝鮮支店
	受取手形: 800000
	現金: 150000
	売掛金: 350000
	当座預金: 1750000

ミャンマー支店
	のれん: 720000
	現金: 640000
	売掛金: 500000
	当座預金: 4000000

阿久根支店
	備品: 9800000
	製品: 1500000
	現金: 75000
	当座預金: 1800000
 テーブルは以下の通りです。
mapkeyjoin_account
+------+----------+
| id   | name     |
+------+----------+
| 8751 | 現金     |
| 8752 | 当座預金 |
| 8753 | 売掛金   |
| 8754 | 受取手形 |
| 8755 | 製品     |
| 8756 | 備品     |
| 8757 | のれん   |
+------+----------+

mapkeyjoin_value
+------+---------+---------+--------+
| id   | price   | account | office |
+------+---------+---------+--------+
| 8759 |  350000 |    8753 |   8758 |
| 8760 |  150000 |    8751 |   8758 |
| 8761 |  800000 |    8754 |   8758 |
| 8762 | 1750000 |    8752 |   8758 |
| 8764 |  500000 |    8753 |   8763 |
| 8765 |  640000 |    8751 |   8763 |
| 8766 | 4000000 |    8752 |   8763 |
| 8767 |  720000 |    8757 |   8763 |
| 8769 | 9800000 |    8756 |   8768 |
| 8770 |   75000 |    8751 |   8768 |
| 8771 | 1800000 |    8752 |   8768 |
| 8772 | 1500000 |    8755 |   8768 |
+------+---------+---------+--------+

mapkeyjoin_office
+------+----------------+
| id   | name           |
+------+----------------+
| 8758 | 北朝鮮支店     |
| 8763 | ミャンマー支店 |
| 8768 | 阿久根支店     |
+------+----------------+
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

X度目の正直の夫婦別姓
2010/01/12(Tue)02:04:56
 通常国会への提出が予定されている、夫婦別姓その他の制度に関する改正案の概要が明らかになりました。提出までに案が修正されないとは限らず、また連立の意向によっては提出を断念せざるを得なくなる可能性も残されているとはいえ、少なくとも夫婦別姓制度は十分に現実味を帯びてきたといえるでしょう。同案では主に以下のような点を改正するものとしています。
  1. 夫婦同姓は残しつつ、夫婦別姓を選択可能にする。ただし、夫婦別姓であっても子どもは全員同姓とする。
  2. 結婚可能な年齢を男女ともに18歳に統一。
  3. 女性が離婚後、再婚できない期間を100日に短縮。
  4. 非嫡出子の法定相続分差別をなくす。
 このうち2の結婚年齢の統一については、これといった反対意見はなさそうです。現行の結婚年齢は以下のように定められていますが、
(婚姻適齢)
第七百三十一条
男は、十八歳に、女は、十六歳にならなければ、婚姻をすることができない。
 そもそも明らかに非合理的な規定ですので、残しておく理由が全く存在しません。残る問題は、男女とも16歳に統一するか、18歳に統一するか、あるいは全く別の年齢に統一するかですが、現行の婚姻適齢(16歳または18歳)を積極的に否定する理由が特に存在しないのであれば、他の制度との兼ね合いを考えて、18歳への統一が無難でしょう。
 次に3、現行では6ヶ月となっている女性の再婚禁止期間の短縮ですが、
(再婚禁止期間)
第七百三十三条  女は、前婚の解消又は取消しの日から六箇月を経過した後でなければ、再婚をすることができない。
2  女が前婚の解消又は取消の前から懐胎していた場合には、その出産の日から、前項の規定を適用しない。
 本規定は子どもの権利を保護するものであるため、その兼ね合いで問題が生じてくるのであれば、安易に賛成はできません。しかしながら、こちらも改正を求める声が高まっている民法772条を見てみると、
(嫡出の推定)
第七百七十二条  妻が婚姻中に懐胎した子は、夫の子と推定する。
2  婚姻の成立の日から二百日を経過した後又は婚姻の解消若しくは取消しの日から三百日以内に生まれた子は、婚姻中に懐胎したものと推定する。
 婚姻成立から200日以降の出生ならその婚姻相手との子、解消から300日以内の出生では離婚した相手との子であると推定される規定になっており、仮に再婚禁止期間終了後に即座に再婚したとしても、婚姻から200日後は必ず離婚から300日以上後となりますので、この観点からは特に矛盾はありません。仮に772条とは別の制度との兼ね合いで子どもの立場がまずくなるのであれば、私はこの改正に反対する用意がありますが、そうでないなら積極的に反対する理由はありません。
 4の法定相続分については、現状では以下のように定められています。
(法定相続分) 第九百条  同順位の相続人が数人あるときは、その相続分は、次の各号の定めるところによる。
(中略)
四  子、直系尊属又は兄弟姉妹が数人あるときは、各自の相続分は、相等しいものとする。ただし、嫡出でない子の相続分は、嫡出である子の相続分の二分の一とし、父母の一方のみを同じくする兄弟姉妹の相続分は、父母の双方を同じくする兄弟姉妹の相続分の二分の一とする。
 すなわち、非嫡出子は嫡出子の半分しか遺産を受け取れないという規定です。本問題については以前に取り上げている通りですが、法ができた当初は非嫡出子の権利が非常に低かったものとみられ、本規定は非嫡出子を差別しているというより、むしろ一定の法的な権利を与えたものと考えることができます。事実、本規定が最初に合憲とされた最高裁判決(「平成3(ク)143」、1995年7月5日)では「非嫡出子にも一定の法定相続分を認めてその保護を図ったものであると解される」と指摘されています。
 ただ、その後の社会の変化などもあり、少なくとも現代では「非嫡出子の権利を保護するために半分の権利を与えている」のではなく、「非嫡出子は相続において差別されている」とみなす意見が大勢でしょう。現時点において同様の裁判が起こされた場合には、違憲判決が下される可能性も十分に出てきていますので(最近の判決で今井氏が違憲判断を出し、竹内氏が「相続時なら合憲だが現時点では違憲の可能性が高い」と指摘するなど)、改正を迫られるのも時間の問題です。遅かれ早かれ改正の必要が生じるのであれば、ここでの改正は無難な選択でしょう。
 そして本改正案でおそらく最も重要なのが、1の夫婦別姓制度です。私はかねてから本制度を導入すべきと主張してきましたが、自民党政権下ではまるで実現の見通しが立ちませんでした。ところが、まだ改正されると決まったわけではないものの、民主党政権になって一気に実現の可能性が高まっており、政権交代の効果の大きさを実感するばかりです。政権交代といえば大きな変革を期待するような雰囲気がありますが、二大政党制において大変革が発生する余地は少なく、また政権交代のたびに経済や外交が根本から変わってしまうようでは国が成り立ちません。むしろ本改正案のような、地味なれど重要な改正こそが大事なのです。
 夫婦別姓には反対論もありますが、なぜかその大半が「家族の一体感が損なわれる」なる全く意味不明な主張を繰り返すばかりで、何ら建設的な議論ができない状態です。もし本当に家族の一体感が損なわれるというのなら、主張者はまずそれを示す根拠の提示を行わなくてはなりません。それができないのであれば、「家族の一体感」なる言い分は主張者の妄想であると断じられても仕方がありません。特に同制度に反対する政治家は、国民に対してその根拠をはっきり提示しなくてはならないはずです。
 また、仮に夫婦別姓制度が「家族の一体感」に何らかの影響を与えるとしても、主張者はさらにそれが社会にどれほどの影響を与えるのかを説明しなくてはなりません。もし夫婦別姓が家族の一体感に影響を与える場合があるとしても、それを選ぶかどうかは夫婦の裁量にゆだねられているわけですから、それを禁じるのは他人の家庭に干渉する行為に他なりません。他人の家庭に干渉することがやむを得ないほど社会に多大な損失を与えるのであれば、夫婦別姓を認めないのは仕方がありませんが、そうでなければ認めない理由はありません。
 このように書くと、必ず「夫婦別姓を主張する側に証明責任がある」などと責任転嫁を図ろうとする主張者が現れますが、失笑を禁じえません。夫婦別姓の導入は制限を緩和する行為であり、夫婦別姓を規制するのは自由を制限する行為です。日本では拳銃を所持する自由、酒を飲んで運転する自由などは認められていませんが、これらはいずれも社会を危険にさらすなど、自由を認めるべきでない正当な理由があるためです。すなわち、もし自由を制限しなくてはならないのであれば、制限するに足る理由を提示しなければなりません。立証責任が自由を制限しようとする側にあるのは明白にもかかわらず、これを相手側に押し付けようとする行為は、もはや夫婦別姓を論じる以前の問題であると言わざるを得ません。逆に夫婦別姓を義務化するのであれば、夫婦同姓を否定する理由を提示しなくてはなりませんが、現在提案されているのは選択制ですので、この懸念はありません。
 無論、「現行制度を変更するのであれば、変更するに足る理由が必要である」という主張まで否定する気はありません。しかし、夫婦別姓を導入すべき理由としては、名前を変更する必要があるのは社会生活上不便である、各所への改姓手続きに手間がかかって非合理的、周囲の人間にも手間や混乱を強いる可能性がある、夫婦どちらかが負担を受忍しなくてはならないのは不合理、離婚や再婚などのたびに子の姓までがコロコロと変わる事態になりかねない、別姓のために事実婚を選択せざるを得ないケースもあり、法が時代に追いついていないなど、現実的かつ具体的なものが複数提示されており、これらを否定するだけの反論は未だに見たことがありません。「家族の一体感」なる抽象的かつ事実かどうかすら分からない反対理由を壊れたレコードのように叫び続けるだけでは、これらの賛成理由に対抗できないのは明らかです。改正すべき理由を否定できるだけの反論がなく、しかも自由への制限を緩和する方向の改正である以上、改正を行わない理由がありません。
 一方、もし夫婦別姓で「家族の一体感が損なわれる」ことが証明され、しかも社会に対して夫婦別姓のメリットを帳消しにして余りあるほどの多大な損害を与えると証明された場合、あるいは「家族の一体感」とは全く別の説得力のある理由が提示された場合には、私は夫婦別姓に反対する用意があります。しかしながら、そのようなものはただの一度として提示されたためしがありません。少なくとも、別姓制度に反対している保守派の政治家とやらが、そうしたものを提示したという話は聞きません。これではどうあがいても、反対側にくみできるはずがありません。この有様では、「家族の一体感」なる取って付けたような理由を持ち出すより、「自分が気に入らないから反対する」と正直に述べた方が、到底賛成はできないにしても、まだ好感が持てるというものです。
 ただ、今回の改正案で残念なのは、「子どもの姓は統一」とされてしまっている点です。連立相手や党内の保守派に配慮する意味があるらしいのですが、これでは決して十分な改正案とはいえません。子の出生届時のみ結婚して即座に離婚するような事実婚の形がすでに存在し、事実婚の配偶者に結婚と同じだけの権利があるとみなす判決などにより、司法が事実婚を追認しているのが現状である以上、これらを制度上からも認める改正案こそが求められているはずで、不十分な改正では効果も不十分なものとなってしまう可能性があります。しかし、このまま連立他党の同意が得られず廃案にするよりは、ひとまず夫婦別姓を確実に成立させ、後から改正案を検討しようとする意図であるなら、やむを得ない妥協ではあります。
 子どもの別姓に関しては、ことさら反対派が「家族の一体感」を持ち出そうとする部分ではありますし、確かに過渡期にはそのような問題が発生する可能性は否定できません。しかし、社会が「別姓で当たり前」の世の中となれば、そのような懸念はほとんど払拭されるはずです。なぜ兄弟別姓が奇異に見えるかといえば、現在の社会が同姓を前提としているためです。
 かつて中国には「避諱」の文化がありました。これは高い地位にある人、例えば皇帝の名前を使ってはいけないというもので、皇帝の名前が含まれた地名や官職名が変更されたり、文章ではわざと漢字を避けたり崩したりして書かれるほどの徹底振りでした。一方、日本には貴人の名前の一部または全部を拝借する文化があり、ある有名人が活躍したり話題になった時期には、命名にその名前や漢字が多く使われる傾向にあるようです。このような価値観の文化においては、「避諱」の習慣は理解しがたいものに映ります。また、欧米には親や親族の名前を子に命名する文化がありますが、もし日本でこのようなことをすれば紛らわしいことこの上なく、制度上認められない場合さえあります。しかし現実に、欧米ではこれが普通に行われているのです。
 すなわち、子どもが別姓に違和感を感じるとすれば、それは社会が同姓前提であるために他ならず、別姓が当然の社会では違和感など感じる余地もないのです。無論、過渡期の間だけなら子どもたちが違和感を感じる可能性は残されていますが、それを理由に改正を否定するのであれば、一時的な混乱が生じる可能性のある改正はすべて否定されてしまいます。
 細部をどうするかはともかく、夫婦別姓には現実的なメリットが多く存在する上、少なくとも現状では否定すべき理由が無根拠の主張を除いて一切示されておらず、しかも合理的根拠のない自由への制限を取り去るものである以上、どう見ても当然導入すべき制度です。民主党政権には一刻も早い導入を期待します。

 JPA 2.0でようやく導入された悲観的ロックですが、これに言及したサイトをいくら回ってみても、「悲観的ロックは遅い」の大合唱です。確かに悲観的ロックは時として遅くなる方法ですが、それも状況次第であって、必ずしも遅くなるとは決まっていないはずです。それとも、JPAの悲観的ロックはそれほどひどいのでしょうか。
 ここに数十人の人間がいるとして、これらの人々が1人ずつしか通れない入り口があるとします。人々が我先にと入り口に殺到するものの、それでも1人しか通ることができず、全員が入りきるまで殺到を繰り返すより、全員が整列して順番を待つ方が早いと考えるのは当然な気がしますが、これだけ各サイトで遅いと強調されているからには、JPAでは何かのメカニズムによって楽観的ロックが早い、あるいは悲観的ロックが遅いのかもしれません。もしそうであるなら、悲観的ロックは極限まで避けなくてはならない可能性も出てきます。
 重要な問題ですので、実際に書いて調べてみました。ただ、いつもながら大変いい加減なコードですので、本質的でない点でオーバーヘッドが生じている可能性が否定できません。したがって、決して結果を鵜呑みにしてはいけません。
/WEB-INF
 /classes
  /com
   /yamicha
    /lockcomp
     LockCompareAccess.java
     LockCompareServlet.java
     SampleTable.java
  /META-INF
   persistence.xml
 まずpersistence.xmlはおおむねいつも通りですが、ロギングレベルがFINEでは無駄にログを吐き出してしまい、それでリソースを食われて結果が変化しては困りますので、SEVEREにしてみました。OptimisticLockExceptionはWARNINGですので、これでログは抑制されます。関係ありませんが、severeを辞書で引いてみたところ、「1. extremely bad or serious」「2. causing somebody to suffer, be upset or have difficulties」とありました。ログとしては前者の意味としても、GlassFishとEclipseLinkの数々の不可解な動作によって散々SEVEREを投げられた私にとっては、明らかに後の意味を含んでいます
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0"
  xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database" value="MySQL" />
      <property name="eclipselink.logging.level" value="SEVERE"/>
    </properties>
  </persistence-unit>
</persistence>
 Javaコードは以下の通りです。トランザクションをコンテナに任せると都合が悪いため、今回はUserTransactionを使用しました。OptimisticLockExceptionが投げられた場合はロールバックして作業をやり直しています。
 なにぶんいい加減なコードですので、不可解なオーバーヘッドが含まれているかもしれません。
// SampleTable.java
package com.yamicha.lockcomp;

import javax.persistence.*;

// カウンタとバージョンを持つだけの単純な Entity
@Entity @Table(name="lockcomp_table") public class SampleTable
	implements java.io.Serializable{
	private int id;
	private int counter;
	private int version;

	public SampleTable(){
		counter = 0;
	}
	public SampleTable(int i , int c){
		id = i;
		counter = c;
	}

	@Id @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="counter") public int getCounter(){
		return counter;
	}
	@Version @Column(name="version") public int getVersion(){
		return version;
	}

	public void setId(int i){
		id = i;
	}
	public void setCounter(int i){
		counter = i;
	}
	public void setVersion(int i){
		version = i;
	}
}

// LockCompareAccess.java
package com.yamicha.lockcomp;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.List;
import java.util.ArrayList;
import javax.transaction.*;

// トランザクションを自分で制御する必要があるので BEAN を設定
@TransactionManagement(TransactionManagementType.BEAN)
  @Remote
  @Stateless(name="LockCompareAccess" , mappedName="ejb/LockCompareAccess")
  public class LockCompareAccess{
  @PersistenceContext(unitName="MySQL") private EntityManager em;
  // UserTransaction は @Resource をつけるだけで取得できる
  @Resource private UserTransaction ut;

  // 前処理
  public void regist(){
    try{
      ut.begin();
      em.persist(new SampleTable(1 , 0));
      ut.commit();
    }catch(Exception e){
      throw new RuntimeException(e.toString());
    }
  }
  // カウンタのインクリメント
  private void addCount(LockModeType mode) throws Exception{
    ut.begin();

    SampleTable sample = em.find(SampleTable.class , 1 , mode);
    sample.setCounter(sample.getCounter() + 1);
    em.merge(sample);
    em.flush();

    ut.commit();
  }
  // 成功するまで更新処理を繰り返すメソッド
  public void add(LockModeType mode){
    while(true){
      try{
        addCount(mode);
        break;
      }catch(OptimisticLockException e){
        try{
          ut.rollback();
        }catch(Exception re){
          throw new RuntimeException(e.toString());
        }
      }catch(Exception e){
        // 念のため、OptimisticLockException 以外を投げた場合の処理
        // RuntimeException を送出して処理を終わらせる
        try{
          ut.rollback();
        }catch(Exception re){
          throw new RuntimeException(e.toString());
        }
        throw new RuntimeException(e.toString());
      }
    }
  }
  // カウンタ値の取得
  public int getCounter(){
    return em.find(SampleTable.class , 1).getCounter();
  }
  // 後処理
  public void remove(){
    try{
      ut.begin();
      em.remove(em.find(SampleTable.class , 1));
      ut.commit();
    }catch(Exception e){
      throw new RuntimeException(e.toString());
    }
  }
}

// LockCompareServlet.java
package com.yamicha.lockcomp;

import javax.servlet.annotation.*;
import javax.ejb.*;
import javax.annotation.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.persistence.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;

@WebServlet(name="lockcompareservlet" , urlPatterns={"/*"})
  public class LockCompareServlet extends HttpServlet{
  @EJB(beanName="LockCompareAccess") private LockCompareAccess ca;

  // 使用するスレッドの数
  // あまり多すぎるとリソースを消費する他、データベースの
  // 接続プールが足りなくなってエラーを出したりするため、
  // 環境に合わせた値に設定する
  // 十分な処理能力とデータベース接続能力がある場合、
  // この値ではおそらく小さすぎる
  private static final int THREAD_COUNT = 10;

  // カウンタを更新するスレッド
  class LockThread extends Thread{
    private LockModeType mode;

    public LockThread(LockModeType m){
      mode = m;
    }
    public void run(){
      ca.add(mode);
    }
  }

  private List<Thread> createThreads(LockModeType mode , int count){
    List<Thread> threads = new ArrayList<Thread>(count);
    for(int i = 0; i < count; i++)
      threads.add(new LockThread(mode));
    return threads;
  }
  private void startAll(List<Thread> threads){
    for(Thread t : threads)
      t.start();
  }
  private void joinAll(List<Thread> threads){
    for(Thread t : threads){
      while(t.isAlive()){
        try{
          t.join();
        }catch(InterruptedException e){
        }
      }
    }
  }

  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();

    ca.regist();

    out.println("楽観的ロックの時間を計測しています。");
    List<Thread> optimistics = createThreads(
      LockModeType.OPTIMISTIC , THREAD_COUNT);
    long opt_time = new Date().getTime();
    startAll(optimistics);
    joinAll(optimistics);
    opt_time = new Date().getTime() - opt_time;

    // 正しくカウンタが更新されているかを確認するために
    // カウンタの値を表示する
    out.println("カウント: " + ca.getCounter());

    out.println("悲観的ロックの時間を計測しています。");
    List<Thread> pessimistics = createThreads(
      LockModeType.PESSIMISTIC_WRITE , THREAD_COUNT);
    long pes_time = new Date().getTime();
    startAll(pessimistics);
    joinAll(pessimistics);
    pes_time = new Date().getTime() - pes_time;

    out.println("カウント: " + ca.getCounter());

    ca.remove();

    out.println("楽観的ロック: " + opt_time);
    out.println("悲観的ロック: " + pes_time);

    out.close();
  }
}
 これを実際に動かしてみたところ、楽観的ロックの場合はどうしても1300〜1400ms必要なところを、悲観的ロックなら400ms以下で終わらせてしまいます。楽観的ロックの場合、最悪のケースを想定すると、10個のスレッドがいっせいに処理を行ってコミットしようとして9スレッドが失敗し、その9スレッドがまた処理をしてコミットしようとして8スレッドが失敗、といった具合に9+8+7+...+2+1回も失敗する恐れがあり、遅くなるのは当然です。
 このケースはあくまで極端な例であって、楽観的ロックの方が軽い局面も多いとはいえ、JPA 2.0でも悲観的ロックが特にひどいわけではないようです。状況次第では、むしろパフォーマンスの改善のために悲観的ロックを取り入れる選択肢さえあります。何にしても、JPA 2.0に悲観的ロックが導入された点と、JPA 2.0の仕様をろくすっぽ実装していない中では珍しくGlassFish v3 Preview + EclipseLinkが悲観的ロックをサポートしている点はありがたいです。
 JPA 2.0の新機能としては、悲観的ロック以外にもUnidirectional OneToManyを試してテーブルが生成されずに撃沈したり、@MapKeyColumnの対応が中途半端でそのままでは動作せず、ログのクエリから方法を推理して強引に動作させてみたりしていますが、これらについては次の機会としておきます。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

捜査権力乱用排除対策記事
2010/01/04(Mon)23:21:58
 2009年12月22日、政府は犯罪対策閣僚会議を開き、「児童ポルノ排除対策ワーキングチーム」なる対策チームを設置しました。9つの省庁で連携して児童ポルノへの対策を調査・検討するもので、6月にも報告書をまとめるとしています。実際にどうなるかは不明ですが、この報告書の内容やチームの提言によっては、後に何らかの法改正がなされる可能性も否定できません。
 法改正の話はかねてから存在しており、決して今回突如として出てきたものではありませんし、民主党は自民党に比べて規制強化に慎重な姿勢を取っていますので、急進的な規制強化の可能性は政権交代以前よりもむしろ縮小していると考えるべきでしょう。しかしながら、本問題をめぐるマスコミ報道には非常に不適切、あるいは恣意的なものが散見され、そのような記事にだまされてしまう人がいないとも限りませんので、以下に問題点をまとめておきます。
 2009年11月17日、読売新聞が自社のサイト上で「民・自・公が児童ポルノの単純所持を禁止する改正案をまとめた」旨の報道を行いました。かねてから民主党は児童ポルノの単純所持禁止に慎重な姿勢を見せており、政権交代によって単純所持の規制は遠のいたとするのが大方の見方ですので、この記事に従うなら民主党は唐突に方針を転換したことになります。
 ところが、この記事はまもなく削除されてしまいました。代わりに掲載されたのは、「自民党が」そのような改正案を提出するという内容の記事でした。その後、読売新聞が本件の訂正や謝罪を行ったとの続報は見当たらず、前の記事は「なかったこと」にされてしまったようです。同社からの公式なアナウンスが存在しないとみられる以上、なぜこのような誤りが発生したのかは不明ですが、自民党側の不確実なリークに基づく不確かな記事であるとも、世論の動向を見るための「観測気球」であるとも考えられます。
 読売新聞は以前より児童ポルノ規制に積極的なスタンスを取っており、社説などでも単純所持を規制すべきと主張していますが、本件の手口はさすがに陰険過ぎると言わざるを得ません。何らかの問題に複数の結末が考えられる場合、新聞社はあらかじめ複数の記事を用意しておくといいますので、今回のミスも単に記事を取り違えただけと考えられないわけではありませんが、それならそれで経緯を洗いざらい公開して謝罪すれば何の問題もないはずです。それをひっそり闇に葬ろうとしている以上、大っぴらに謝罪して誤記事配信の事実が知れ渡ると困る事情、すなわち偽情報リークや観測気球などを疑われても仕方がありません。
 その本題の児童ポルノ規制問題ですが、私は児童ポルノを規制すること自体に反対するつもりはなく、むしろ不十分な部分があるなら強化も必要であると考えています。実写の児童ポルノには必ず被害者が存在し、児童ポルノ作成とはすなわち性的虐待や搾取を意味しますので、決して作成を許容するわけにはいきません。また、写真などの媒体の受け渡しによって無尽蔵に被害が拡大してしまうため、流通に歯止めをかける仕組みも必要です。これらの規制の必要性に関しては、ほとんどの人が賛同するのではないでしょうか。
 しかしながら、単純所持となると話は違ってきます。単に写真などを所持するという「状態」ではなく、積極的な入手など何らかの「行為」が立証されることを罪の構成要件とし、しかも適用範囲を厳密に定めるなど、極めて厳密・厳格な法案が作成されたのであれば、私もそれに賛成する用意はありますが、あいまいな要件による単純所持の禁止には慎重にならざるを得ません
 今からおよそ2000年前、中国には政敵などを陥れる呪術がありました。今で言う「わら人形」のようなもので、迷信の一種です。ところが、実はこの呪術はただのまじないなどではなく、実際に大変強力な効果を持つものでした。なぜなら、時の政権がこれを厳しく規制したためで、政敵が呪術を行ったように見せかければ、文字通り相手を「呪殺」することができたのです。
 児童ポルノの単純所持規制にも、同様の問題が懸念されます。そもそも「児童ポルノ」の定義があいまいであるため、自分自身や我が子の写真が児童ポルノとみなされ、単純所持容疑で逮捕される可能性すらあります。無論、警察としてもアルバムに子どもの裸の写真がある家庭すべてを回って逮捕しているわけにはいきませんので、厳密には「違法だが黙認されている」状態になるものと予想されますが、それすなわち「いつでも法を適用して逮捕できる」状態を意味します。
 児童ポルノの要件を厳格に定めようにも、水着なり露出の多い衣服なりはどこまで許されるのか、自分自身や我が子などの裸の写真が罪に問われるのは理不尽ですが、それなら誰の写真を誰が所有するなら合法なのか、被写体が誰なのかはっきりしない場合はどうするのか、年齢の判別が困難な場合はどうするのかなど、無限に存在する疑問に対して逐一定義を与えるのは不可能ですから、最終的には「18歳未満と思われる人物が写った、わいせつな写真その他の媒体」のようなあいまいな定義になるのは見えています。
 それでは、一体何であれば「わいせつ」で、どのように年齢などを判断するのでしょうか。以前に「自衛隊を派遣したところが非戦闘地域だ」なる珍妙な主張を行った人がいましたが、実際問題として「摘発されたものが児童ポルノ」となる可能性が高いのです。何の変哲もない水着の写真であれ、明らかにわいせつに見えない写真であれ、自分や我が子の写真であれ、平気で児童ポルノ扱いされて逮捕されてしまう恐れがあります。
 これは決して大げさな話ではなく、現実に発生する可能性が十分に考えられる事柄です。例えば、警察に何らかの事件への関与を疑われた場合、その事件に関する証拠が十分にそろっていない状況では、警察は「別件逮捕」の手法を取ることがあります。何でも良いので適当な罪状で逮捕し、そこで強引に自白を取って起訴に持ち込もうという戦術です。あるいは、何らかの罪状で一旦逮捕した後、引き続き取り調べを続けるために再逮捕を繰り返す場合もあります。
 すなわち、何らかの事件に関して事実無根の嫌疑をかけられた場合、警察が何かしら理由をつけて家宅捜索を実施し、アルバムから自分や我が子の裸の写真を見つけるなり、適当な写真や映像、HDD内の画像などポルノでないものを児童ポルノ呼ばわりするなりして、不当に逮捕されてしまう可能性が十分にあるのです。もし容疑をかけられている事件が性犯罪であったりすれば、マスコミも大騒ぎしてほぼ確実に犯人にされてしまうでしょう。
 また、検索などで偶然に児童ポルノサイトに入り込んでしまったり、ウイルスやクラッカーの仕業で児童ポルノがHDD内などに保存されてしまう可能性もあり、外国では実際にウイルスによって児童ポルノがダウンロードされ、逮捕されかかる事態が発生しています。また、インターネットには「Webビーコン」と呼ばれるトラップがあり、簡単に言えば画像を目に見えない方法でこっそりWebページに埋め込むものなのですが、これでも画像は知らない間にダウンロードされてしまうため、逮捕される恐れがあります。
 このように、単純所持の規制を安易に認めるのは非常に危険で、しかもこれは「仮定の話」や「最悪のケース」ではなく極めて現実的なリスクです。しかしながら、マスコミの多くはこの懸念をそれほど大きくは取り上げておらず、あたかも単純所持規制が絶対的正義であるかのように報道するケースさえ見受けられます。仮に単純所持を何らかの形で規制するにしても、この懸念に関する議論は欠くべからずものであり、隠蔽することが許されるわけがありません。
 果ては、一部には創作物の作成や所持までもを規制しようとする動きさえありますが、論じる価値もないと言わざるを得ません。以下、毎日新聞の「クローズアップ」からの引用です。
 児童ポルノ根絶などに取り組むNGO「国際ECPAT」のカルメン・マドリナン事務局長が来日し、国際情勢や日本の現状への危機感を次のように語った。

 現在、インターネット上では毎日新たに200枚もの児童ポルノ画像が増え続けている。国際刑事警察機構(インターポール)によれば、性的な画像を撮られネット上にさらされている子の数は1万人から10万人、その83%は6歳から12歳だ。より暴力的で低年齢化する傾向もある。

 規制に対しては「芸術的表現への検閲が強まる」「画像を見ることで実際の虐待が減っている」との主張もある。だが各国の法執行機関などが持ち寄ったデータでは、起訴された画像所有者の約4割が実際の性的虐待に関与し、約15%が試みようとしている。画像を見ることと性的虐待には因果関係があると言える。

 コンピューターや漫画などバーチャル(疑似的)な画像の規制も課題だ。国際的には児童ポルノや虐待の定義を広げる流れにある。日本は世界的にみてバーチャルな児童ポルノの生産・輸出国で、まねようとする国も出てきている。無視できない現実だ。

2009/12/31 クローズアップ2009:児童ポルノ 画像バーチャル化「日本は生産・輸出国」より引用
 ざっと読むと分かりづらいのですが、これは最初の段落を除いてすべてECPATのカルメン・マドリナン氏の主張を記載したものであって、何らかの裏づけのある新聞記事というわけではありません。しかしながら、どう見ても明らかに不当な言い分が散見されるにもかかわらず、新聞社として誤解を招かないための注釈や問題提起を入れないのは、良く見積もっても怠慢、悪く見れば世論操作であると指摘されても仕方がありません。
 表現としてまず問題なのは、以下の「事実と言わんばかりの憶測」です。
だが各国の法執行機関などが持ち寄ったデータでは、起訴された画像所有者の約4割が実際の性的虐待に関与し、約15%が試みようとしている。画像を見ることと性的虐待には因果関係があると言える。
 この「因果関係があると言える」の部分はあくまで主張者の憶測です。かなり強い確定的表現がされているため分かりづらいのですが、所詮は主張者がそのように推理しているだけですので、「因果関係が存在する余地がないとは必ずしも言い切れない」と言い換えても何ら問題はありません。マドリナン氏が実際にこのような強い言い方をしたのであれば、氏には世論誘導の意図があると考えて間違いありませんし、一方で毎日新聞が勝手に要約なり翻訳なりしたのであれば、同社の姿勢に問題があります。
 論の中身にしても、まず「各国の法執行機関などが持ち寄ったデータ」なるものが大変にあいまいで、いかなるものであるのか全く分かりません。国ごとに規制の基準も違えば警察の能力も違う以上、データの選び方次第でいくらでも任意の結論を作り出せます。ただ、データそのものを疑っては話が進みませんので、ひとまずデータは正しいものと仮定してみます。
 ところが、このデータの分析がまた恣意的です。「起訴された画像所有者」と表現されているからには、単純所持や入手が規制されている国々のデータであると推測されますが、「規制されている国であえて画像を入手・所持する」行為は、規制されていない国でのそれとは訳が違います。他の問題に例えるなら、日本で「対人用の拳銃を持っている」として起訴された者の何割かが実際に人を殺傷していたとして、拳銃の所持が違法ではない米国でも拳銃所持者が同様の割合で人を殺傷していると考えるのは誤りです。したがって、少なくとも本件を日本に当てはめて考えるのは不可能です。
 また、児童ポルノ画像を所持あるいは入手したとしても、その中で起訴される者はごく一握りに過ぎず、氷山の一角であることは容易に想像できます。多数の所持者がいながら一部の人間のみが起訴される理由は、警察などの捜査網に引っかかったり、「偶然」といった言い訳ができないほど作為的に画像を入手した証拠が積み上がっていたり、捜査機関としても目こぼしができなかったりするほど大っぴらに、あるいは大量に児童ポルノを入手または所持、場合によっては作成していたためと考えるのが自然で、児童ポルノが規制されている国においてそれだけ危険な行為を取っている人というのは、児童ポルノを所持あるいは入手していても目立った行動はしない人に比べ、性的虐待に関与する確率が高いと考えても矛盾はありません。
 さらに、ごく常識的に考えて、「児童ポルノの所持」と「実際の性的虐待への関与」では、発覚する確率はどちらの方が上でしょうか。児童ポルノを所持していることなど容易に分かるものではありませんので、おそらく大半の人が後者と答えるはずです。それでは、「児童ポルノの所持が分かって起訴し、調べてみたら性的虐待に関与していた」ケースと「性的虐待が発覚し、余罪を追及したら児童ポルノを持っていた」ケースでは、どちらの方が発生しやすいといえるでしょうか。これでは、「犯罪者を調べたところ、そのほぼ全員が水分を摂取していた。すなわち、水分を摂取する行為は犯罪と因果関係がある」と定義するようなものです。
 加えて言えば、「因果関係」を主張するからには、「児童ポルノの所持」という原因があったからこそ「性的虐待」の結果を生み出した、すなわち児童ポルノの所持が犯罪を誘発するという証明が必要で、それが無理ならどうがんばっても「相関関係」を提起する程度が限度です(ただし、その相関関係の存在すら怪しいのは前述の通りです)。仮定としても絶対にあり得ない数値ではありますが、もし仮に「全世界の児童ポルノ所持者を1人残らず全員調べたところ、その4割が性的虐待に関与していた」としても、ここから得られる結論はせいぜい「児童ポルノ所持者の4割は犯罪性向を持っていた」程度のものに過ぎず、氏の言い分を肯定するような結論は全く出てきません。つまり、本調査結果から「因果関係」なるものを見出そうとする言い分自体、そもそも成り立ってさえいないデマに他なりません。
 この通り、マドリナン氏の言い分はあまりに低レベルな主張と断じざるを得ません。無論、マドリナン氏の主張が単なる推測であるなら、私の主張も推測であることに変わりはありませんが、少なくとも「児童ポルノ所持と性的虐待の関与には因果関係がある」という仮説は証明が不十分として棄却してしまって差し支えないでしょう。
 私がなぜ児童ポルノを規制すべしと主張するかといえば、「被害者」の存在があるためです。児童ポルノの作成を認めれば新たな被害者が生まれ、流通を認めれば被害が際限なく拡大します。したがって、被害者を極力出さず、また被害者のダメージを最低限に食い止めるには、どうしても規制が必要です。
 しかしながら、「バーチャルな画像」に被害者は存在しません。被害者が存在しないものを規制するためには、それが社会に対して害を与えること、具体的には犯罪を誘発してしまうことを証明しなくてはなりません。しかしながら、実際には「バーチャルな画像」が犯罪を誘発するか否かはおろか、実際の児童ポルノが犯罪を誘発するかさえ証明されていない有様です。マドリナン氏のいい加減な言い分は「妄想」ではありますが、「証明」に当たらないのは言うまでもありません。
 また、創作物にまで児童ポルノ法の適用範囲を広げるとなれば、なおさら問題が拡大するのは見えています。実写の場合であれば、実際には困難な状況も多いとはいえ、理論上は被害者の年齢を確認することで児童ポルノか否かを明確に線引きできますが、創作物では不可能です。設定上は大人でも画像は子どもに見える場合、あるいはその逆の場合にどうするかも全く不明ですし、人間外の種族などで人間より生命のスパンが短い場合、あるいは長い場合に年齢をどう判断するのかも分かりません。あるいは、子どもが大人の姿になったり、その逆となる創作物もあり得ます。一体どこまでが「わいせつ」なのかという線引きの問題も残っていますし、人間外の種族であったり、現実では原理上存在し得ない衣装や状況といったものに対して「わいせつ」の線引きするのはなお困難です。言うまでもなく、これを逐一法律で定義できるわけがありません
 それではどのように児童ポルノかを判別するかといえば、「摘発されたものが児童ポルノ」と定義する以外にはありません。何の変哲もない落書きの1つで、しかもそれが明らかにポルノと呼べないものであったとしても、逮捕される恐れが出てきます。実写の児童ポルノであれば、被害者保護のために規制は進めつつ、権力の乱用も防がなくてはならないというジレンマがあり、単純所持なども簡単には否定できない側面がありましたが、創作物規制に関しては論外の一言だけで十分でしょう。いちいち検討する価値すらなく、いかにも人権意識の低い国がやりそうな話です。もし海外のどこかの国で創作物が規制され、日本ではされなかったとしても、それは日本が「児童ポルノ取り締まり後進国」であるためではなく、「人権先進国」であるためですから、決して悪いことではありません。

 JPA 2.0では仕様に悲観的ロックが追加されています。JPA 1.0ではベンダ固有の方法で悲観的ロックを使用するしかなく、仕様自体は楽観的ロックにしか対応していませんでしたので、これはかなり評価できる改善点で、中には「悲観的ロックこそがJPA 2.0の主要かつ最大の変更点である」と評価する人もいるほどです。
 それほどの変更なのですから、早いうちに仕様の概要を確認してしまいたいのはやまやまですし、実際にそうしようと考えていたのですが、途中でバグとも仕様ともつかない不思議な現象が大量に発生し、想像以上に確認が阻害されています。ロックして欲しくない状況でロックをかけることはあれ、ロックしなくてはならない状況でロックをかけないことはなく、API仕様自体は満足していないといえなくもありませんが、どうにも理不尽です。
 それでは、まず楽観的ロックと悲観的ロックの簡単なまとめより。

楽観的ロック(Optimistic Lock)
 「バージョン」あるいは「最終更新時間」のカラムを用意しておき、データを実際に書き込む際にバージョン番号を1つ増加するか、あるいは最終更新時間を書き換える。ただし、レコードを読み込んだ時点と書き込む時点で保存されているバージョンの値が異なる場合は、例外を出して処理を破棄する
 例えばスレッドAがレコードを読み込み、Bも同じレコードを読み込んだとする。この時点ではどちらもバージョン1であった。このままAとBがそれぞれレコードに何らかの処理を行ってコミットした場合、対策がなければ片方の変更が消滅してしまう。しかし、Aがコミットした際にバージョンが2に加算されるので、Bはバージョンの変更を検出し、例外を出してコミットに失敗する。失敗した場合には再び処理を最初からやり直さなくてはならない。

悲観的ロック(Pessimistic Lock)
 かなり一般的なロック。ロックといえば大抵はこれであるはずが、なぜJPA 1.0で実装されなかったのかは不明。JPA 1.0でもベンダによっては機能を提供していたが、各ベンダ固有の設定や記述が必要であった。レコードを読み込んでから書き込むまでの間はレコードに鍵をかけ、他のスレッドからの利用を遮断する(厳密には共有ロックと排他ロックの2つがある)。あるスレッドがロックをかけて処理している間、それを利用したい他のスレッドは待機する(あるいは即座に例外を出す)。この方式の欠点は、ペシミストの悲劇ことデッドロックを発生させやすい点。

 ちなみに、悲観的ロックはパフォーマンス的に楽観的ロックに劣るような言い方がされる場合もありますが、1000人が窓口に押しかけて1人だけが通され、999人は一旦戻った上で再び窓口に押しかける図と、1000人が行儀よく行列を作っている図では、後者の方が負担が軽いのではないかという印象を私は持っています。ロックの仕様にもよりますので、そのうちJPA 2.0で調べてみたい点です。
 今回はごく単純にfindメソッドでロックをかけることにして、各種ロックの仕様を確認してみました。ちなみに、引数にLockModeTypeを渡せるfindメソッドはJPA 2.0で追加されており、楽観的ロックと悲観的ロックの考え方の違いがここにも現れています。
 なお、悲観的ロックの場合、SQLが「まだ見ぬレコード」をロックできたりするのですが、JPA 2.0上でそれができるのか、いかなる条件で成立するのかは未確認です。JPQLを使えばできる可能性は高そうですが、これも今後の課題です。
 以下、いつもながら大変いい加減なコードです。今回もEJBをclassesに設置し、@WebServletを使用しました。
/jpa20
 /WEB-INF
  /classes
   /com
    /yamicha
     /jpa20
      @Entity Product.java
      @Entity Maker.java
      @Stateless ProductAccess.java
      @WebServlet ProductServlet.java
   /META-INF
    persistence.xml
 persistence.xmlではlogging.levelをFINEに設定し、生成されたクエリをログに吐き出すようにしておきました。
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database"
        value="MySQL" />
      <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>
 ソースは以下の通りです。
// Product.java
package com.yamicha.jpa20;

import javax.sql.*;
import javax.persistence.*;

@Entity @Table(name="jpa20_product" , schema="yamicha")
	public class Product implements java.io.Serializable{
	private int id;
	private String name;
	private int price;
	private int lock_version;
	private Maker maker;
	private int stock;

	public Product(){
	}
	public Product(String s , int i){
		name = s;
		price = i;
		stock = 0;
	}

	@Id @Column(name="id") @GeneratedValue public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@Version @Column(name="lock_version")
		public int getLockVersion(){
		return lock_version;
	}
	@ManyToOne @JoinColumn(name="maker") public Maker getMaker(){
		return maker;
	}
	@Column(name="stock") public int getStock(){
		return stock;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setLockVersion(int l){
		lock_version = l;
	}
	public void setMaker(Maker m){
		maker = m;
	}
	public void setStock(int s){
		stock = s;
	}
}

// Maker.java
package com.yamicha.jpa20;

import javax.sql.*;
import javax.persistence.*;
import java.util.*;

@Entity @Table(name="jpa20_maker" , schema="yamicha")
	public class Maker implements java.io.Serializable{
	private int id;
	private String name;
	private int lock_version;
	private List<Product> products;

	public Maker(){
		products = new ArrayList<Product>();
	}
	public Maker(String s){
		this();
		name = s;
	}

	@Id @GeneratedValue @Column(name="id") public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}
	@Version @Column(name="lock_version")
		public int getLockVersion(){
		return lock_version;
	}
	@OneToMany(cascade=CascadeType.ALL ,
		fetch=FetchType.EAGER , mappedBy="maker")
		public List<Product> getProducts(){
		return products;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
	public void setLockVersion(int l){
		lock_version = l;
	}
	public void setProducts(List<Product> p){
		products = p;
	}

	public void link(){
		for(Product p : products)
			p.setMaker(this);
	}
}

// ProductAccess.java
package com.yamicha.jpa20;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.List;
import java.util.ArrayList;

@Remote @Stateless(name="JPA20ProductAccess" , mappedName="ejb/JPA20ProductAccess")
	public class ProductAccess{
	@PersistenceContext(unitName="MySQL") private EntityManager em;

	// サンプルデータ登録メソッド
	// どの企業もいまやオラクルの配下
	public void regist(){
		Maker sun = new Maker("San Microsystems");
		sun.getProducts().add(new Product(
			"GrassFish Application Server" , 1200000));
		sun.getProducts().add(new Product(
			"Soralis" , 1300000));
		sun.link();
		em.persist(sun);

		Maker olacre = new Maker("Olacre");
		olacre.getProducts().add(new Product(
			"Olacre Database System" , 450000));
		olacre.link();
		em.persist(olacre);

		Maker bae = new Maker("Bae Systems");
		bae.getProducts().add(new Product(
			"EuroLogic Application Server" , 1400000));
		bae.getProducts().add(new Product("JRocket" , 320000));
		bae.link();
		em.persist(bae);

		Maker mesql = new Maker("MeSQL AB");
		mesql.getProducts().add(new Product(
			"MeSQL Enterprise Support" , 85000));
		mesql.link();
		em.persist(mesql);

		em.flush();
	}
	public List<Maker> getMakers(){
		return (List<Maker>)em.createQuery(
			"SELECT m FROM Maker m").getResultList();
	}
	public List<Product> getProducts(){
		return (List<Product>)em.createQuery(
			"SELECT p FROM Product p").getResultList();
	}
	public void addStock(Object id , int value , LockModeType mode){
		Product p = em.find(Product.class , id , mode);

		try{
			Thread.sleep(1000);
		}catch(InterruptedException e){
		}

		if(value != 0){
			int stock = p.getStock() + value;
			if(stock < 0)
				throw new RuntimeException(
					"在庫が足りません。");
			p.setStock(stock);

			em.merge(p);
		}
		em.flush();
	}
	public Maker getMaker(Object id){
		return em.find(Maker.class , id ,
			LockModeType.PESSIMISTIC_WRITE);
	}
}

// ProductServlet.java
package com.yamicha.jpa20;

import javax.servlet.annotation.*;
import javax.ejb.*;
import javax.annotation.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.persistence.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;

@WebServlet(name="jpa20servlet" , urlPatterns={"/*"})
  public class ProductServlet extends HttpServlet{
  @EJB(beanName="JPA20ProductAccess") private ProductAccess pa;

  class AddDataThread extends Thread{
    private String thread_name;
    private LockModeType mode;
    private PrintWriter out;
    private int id;
    private int value;
    private ProductAccess pa;

    public AddDataThread(String n , LockModeType mode , PrintWriter out ,
      int id , int value , ProductAccess pa){
      thread_name = n;
      this.mode = mode;
      this.out = out;
      this.id = id;
      this.value = value;
      this.pa = pa;
    }
    public void run(){
      try{
        pa.addStock(id , value , mode);
      }catch(Exception e){
        synchronized(out){
          out.println(thread_name + " 例外:<br />");
          e.printStackTrace(out);
        }
      }
    }
  }

  public void doGet(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    doPost(request , response);
  }
  public void doPost(HttpServletRequest request ,
    HttpServletResponse response) throws IOException{
    // この種のプログラムは JSF などに書くべきではあるものの
    // Servletで書く方が楽というのは明らかにすさんでいる気が...
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type" , "text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();

    out.println("<html>");
    out.println("<head>");
    out.println("<title>ProductServlet</title>");
    out.println("</head>");
    out.println("<body>");

    if("regist".equals(request.getParameter("type"))){
      pa.regist();
    }
    if("maker".equals(request.getParameter("type")) &&
      request.getParameter("id") != null){
      int id = Integer.parseInt(request.getParameter("id"));

      Maker maker = pa.getMaker(id);

      out.println("<b>" + maker.getName() + "</b><br />");
      out.println("製品数:" + maker.getProducts().size() +
        "</b><br />");
      for(Product p : maker.getProducts())
        out.println(p.getName() + "<br />");
      out.println("<br />");
    }
    if("add".equals(request.getParameter("type")) &&
      request.getParameter("id") != null){
      String lock = request.getParameter("lock");
      LockModeType mode = LockModeType.OPTIMISTIC_FORCE_INCREMENT;
      if("optimistic".equals(lock)){
        mode = LockModeType.OPTIMISTIC;
      }else if("optimistic_force_increment".equals(lock)){
        mode = LockModeType.OPTIMISTIC_FORCE_INCREMENT;
      }else if("pessimistic_read".equals(lock)){
        mode = LockModeType.PESSIMISTIC_READ;
      }else if("pessimistic_write".equals(lock)){
        mode = LockModeType.PESSIMISTIC_WRITE;
      }else if("none".equals(lock)){
        mode = LockModeType.NONE;
      }
      int id = Integer.parseInt(request.getParameter("id"));
      int value = Integer.parseInt(request.getParameter("value"));

      Thread t1 = new AddDataThread(
        "Thread1" , mode , out , id , value , pa);
      Thread t2 = new AddDataThread(
        "Thread2" , mode , out , id , value , pa);

      t1.start();
      t2.start();

      try{
        t1.join();
        t2.join();
      }catch(InterruptedException e){
      }

      out.println("LockModeType: " + mode.toString());
    }

    List<Product> records = pa.getProducts();

    out.println("<form method=\"POST\" action=\"?\">");

    out.println("製品リスト");
    out.println("<table border=\"1\">");
    out.println("<tr>");
    out.println("<td bgcolor=\"#CCDDFF\">Check</td>");
    out.println("<td bgcolor=\"#CCDDFF\">メーカー</td>");
    out.println("<td bgcolor=\"#CCDDFF\">製品</td>");
    out.println("<td bgcolor=\"#CCDDFF\">在庫</td>");
    out.println("</tr>");

    for(Product record : records){
      out.println("<tr>");
      out.println("<td><input type=\"radio\" name=\"id\" value=\"" +
        record.getId() + "\"></td>");
      out.println("<td><a href=\"?type=maker&id=" +
        record.getMaker().getId() + "\">" + record.getMaker().getName() +
        "</a></td>");
      out.println("<td>" + record.getName() + "</td>");
      out.println("<td>" + record.getStock() + "</td>");
      out.println("</tr>");
    }
    out.println("</table>");

    out.println("在庫を<input type=\"text\" name=\"value\" value=\"0\" />" +
      "個増やす(マイナスで減らす)<br />");

    String labels[][] = {
      {"楽観的書き込み" , "optimistic_force_increment"} ,
      {"楽観的読み込み" , "optimistic"} ,
      {"悲観的書き込み" , "pessimistic_write"} ,
      {"悲観的読み込み" , "pessimistic_read"} ,
      {"なし" , "none"}
    };
    out.println("ロック方式: <select name=\"lock\">");
    for(String[] label : labels){
      out.println("<option value=\"" + label[1] + "\">" +
        label[0] + "</option>");
    }
    out.println("</select><br />");

    out.println("<input type=\"submit\" value=\"送信\" />");
    out.println("<input type=\"hidden\" name=\"type\" value=\"add\">");
    out.println("</form>");

    out.println("<form method=\"POST\" action=\"?\">");
    out.println("<input type=\"submit\" value=\"サンプルデータ登録\" />");
    out.println("<input type=\"hidden\" name=\"type\" value=\"regist\">");
    out.println("</form>");

    out.println("</body>");
    out.println("</html>");

    out.close();
  }
}
 在庫データの更新を行うと、全く同じ作業を行うスレッドが2つ生成され、ロックがぶつかる状況を作り出します。また、仕様として在庫追加欄に0を渡すとレコードの更新は行われず(OPTIMISTIC_FORCE_INCREMENTの動作確認のため)、また在庫が負数に達すると例外を投げます。
 ところが、これを実際に動かしてみると、予想だにしない動作が大量に発生しました。私の設定ミスか、バグか、仕様か、暫定実装なのかは全く不明ですが、指示していないロックをかけたり、指示以上のロックをかけたりはするものの、ロックをかけるよう指示してかけないことはないので、かなり解釈が難しいです。なお、バージョンは「GlassFish v3.0-Preview (build 47.4)」ですが、GlassFishなりEclipseLinkなりを新しくすれば動作が変化するかもしれません。
  • OPTIMISTIC
     データを変更した場合は@Versionカラムの値が1つ増加し、片方のスレッドはOptimisticLockExceptionを出して失敗します。変更しなかった場合(在庫追加欄に0を渡した場合)は@Versionの値は変わらず、スレッドは両方とも成功し、例外も出ません。
  • OPTIMISTIC_FORCE_INCREMENT
     @Versionの値を強制的に1つ増やす機能のはずなのですが、この@Version値の変更自体も更新の一種とみなされているのか、在庫数を変更した場合は「FORCE_INCREMENT効果で+1 -> データ変更で+1」という理屈がまだ成り立つとして、在庫を変更しなくても@Versionの値が+2されます。すなわち、1度の更新で@Versionが2つずつ増えていきます。
     無論、片方のスレッドはOptimisticLockExceptionを投げてきます。OPTIMISTICと違い、在庫の値を変更したか否かにかかわらず、片方のスレッドは例外を出します。これはFORCE_INCREMENTの性質からして当然です。
     在庫を負数にして例外を出した場合は、いくらFORCE_INCREMENTとはいっても@Versionの値は変更されません。
  • PESSIMISTIC_READ
     悲観的読み込みのはずが、ログを見るとFOR UPDATEを使っています。LOCK IN SHARE MODEではありません。また、在庫数を変更した場合には、@Versionの値はしっかり更新されています。FOR UPDATEが使われているだけはあり、片方のスレッドの処理が終わってからもう片方のスレッドの処理も行われ、例外を出さずに両方の処理が反映されます(在庫数は2度増減、@Versionは2増加)。2度目の処理で在庫数が負数になってしまうような在庫追加数を指定(在庫が3つある状態で-2など)すると、先に動いたスレッドの処理は反映され、後に動いたスレッドは例外(ProductAccess.javaに書いておいたRuntimeException)を投げます。
  • PESSIMISTIC_WRITE
     ログを見る限り、なぜか動作はPESSIMISTIC_READと全く同じです。
  • NONE
     NONEというからにはロックなどしないと考えていたら、しっかり@Versionの値はインクリメントされ、しっかりOptimisticLockExceptionを投げてきました。OPTIMISTICと何ら変わりません。
 せめて仕様かバグか暫定実装かが分かれば相応の対処ができますが、どこまで正しい動作なのか判別のつけようがなく、どうにもやりづらいです。
 試しに@Versionアノテーションを削除してロックの動作を確認してみましたが、楽観的ロックの際に例外を投げてくるのは当然として、悲観的ロックを使っていても以下のような例外が出るのはどういうわけでしょうか。何か「必ず楽観的ロックを使う」ような設定があって、私が間違ってそれを使用している可能性もないではありませんが、大変不思議です。

javax.persistence.PersistenceException: Invalid lock mode type on for an entity that does not have a version locking index. Only a PESSIMISTIC lock mode type can be used when there is no version locking index.
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

60*60*24*30秒ルール
2009/12/27(Sun)23:51:22
 内閣が「1ヶ月ルール」を無視して中国側との会見を設定したことについて、「天皇の政治利用」との批判がなされています。問題山積みの内閣の状況からすれば、この問題はさして重要なものとはみなされていないようで、事実として数週間もしないうちにほとんど忘れ去られています。私も当初は静観するつもりでしたが、今後またもや同様の状況が発生した際、いちいち同様の騒ぎを繰り返すのは大変非合理的ですので、あえてここで取り上げておきます。
 まず「1ヶ月ルール」とは何かといいますと、外国の要人が天皇との会見を希望する場合に、事の大小や相手国の立場にかかわらず、1ヶ月以上前に文書によって申請しなければならないという慣例のことです。これは1995年(自民・社民・さきがけ政権時)に文書化されたものですが、特に拘束力はなく守られない場合もあったため、2004年に天皇が腫瘍摘出手術を行ってからは、健康上の理由もあって厳格に適用されるようになったとされています。ただ、2005年のスマトラ沖地震によってタイが大きな被害を受けた際には、事情が事情だけにルールの適用が見送られ、タイ側との会見が実現しています。
 本件が政治利用であるとされるのは、米国などを含めてあらゆる国に対して等しくこのルールを適用してきたはずが、「政治的な重要性」を理由に本ルールを無視し、中国側との会見が設定されたためのようです。
 結局、本件については宮内庁長官の羽毛田氏が「政治的利用じゃないかといわれれば、そうかなという気もする」「こういうことは二度とあって欲しくない」などと発言し、これに対して小沢氏が反論、これに羽毛田氏が再反論するなど、泥沼化の様相を見せはしたものの、うやむやのまま終息に向かっている状況です。どちらの言い分が守られるべきかも合意を見ておらず、再び似たような状況が発生する可能性は否定できません。
 ここで私の意見を述べておくなら、私は小沢氏と羽毛田氏の両方の言い分を支持しません。「1ヶ月ルール」に対する主張だけを見比べてみれば、小沢氏の方に正当性があるものの、氏が述べた理由は完全に破綻しており、およそ支持できるものではないためです。
 まず重要な点として、この「1ヶ月ルール」は何らかの法によって厳密に定められたわけではなく、ただの慣例に過ぎません。したがって、慣例に反するようなケースが発生することは十分に予想できたはずで、法的義務も何もない慣例ルールを絶対視して「ルールに反するのは天皇の政治利用」などとは本末転倒もはなはだしい言い分です。
 ましてや、法で厳密に定められたわけでもない慣例を絶対視し、これを義務として扱うのであれば、慣例を定める立場にある者が天皇に関して立法に匹敵する権限を持つことになりかねず、天皇の権力が恣意的に利用されてしまう恐れがあります。そして実際、現状ではあくまで慣例は慣例に過ぎないはずが、それを無視すればこれだけ批判の大合唱を浴びるとなれば、実質的に慣例を破る行為は非常に難しく、現状でもその懸念は存在しているといえるでしょう。
 この点からすれば、小沢氏が怒って「あいつ(羽毛田氏)こそどうかしている。天皇の権威をかさにきている」と吐き捨てたのは、言い方にこそトゲがありますが、ある意味では事実です。1つの庁の長官である役人が、厳密に法にて定められたわけでも何でもない「慣例」の遵守を政府に対して強要する権限など、持っていようはずがありません。
 そもそも、私はこうした「慣例」自体に大きな疑念を持っています。今回の問題が発覚するまで、一体どれほどの国民が「1ヶ月ルール」なるものの存在を認識していたのでしょうか。かく言う私も全く知りませんでした。また、社民党党首の福島氏が本ルールを知らなかったと言っていることからして、議員の間にも知らない人は存在するようです。
 これは一体何を意味するのでしょうか。すなわち、国民も議員も知らない場所で、下手すると立法並みの権限を持つ「慣例」がひっそりと作られ、既成事実とされていっているのです。これはあくまで慣例に過ぎないはずですが、前述の通り破ることは非常に困難です。小沢氏らの政治利用以前の問題として、このような慣例至上主義こそ権力の恣意的な利用に結びつきかねません。
 また、「天皇の健康上の理由」なる言い分にも注意が必要です。確かに、「公務」なるものによって天皇という尊い一個人の健康が損なわれるのは避けるべきですから、健康への配慮に反対する理由はありません。しかしながら、健康問題を理由とした慣例をなし崩し的に認めてしまうと、やはり上記のような問題が発生する可能性がありますし、最悪の場合には天皇の健康を名目にした権力利用が行われてしまわないとも限りません。これでは「健康に配慮」どころか、健康までもが道具にされてしまいます。したがって、健康問題を含むいかなる理由があろうと、慣例には慣例以上の価値を持たせてはいけません
 そもそも本件自体、実際には単に「慣例」に反しただけに過ぎず、厳密に法によって定められた規定を破る違法行為を行ったわけでもなく、法による規制でも何でもない「慣例」を無視した程度で違憲批判もへったくれもなく、本来なら別に政治問題にも何にもならなかったところを、宮内庁や長官の羽毛田氏が無駄に騒ぎ立てて政治問題に仕立て上げてしまった部分があります。さらに、これを政府・与党攻撃の好機と見た野党が「悪乗り」し、マスコミも騒ぎに便乗し、慣例問題よりもまず「中国憎し」が頭にある人々も騒ぎを大きくし、無用な騒動を作り出してしまいました。こうなると、天皇会見問題が別の意味で「政治問題」化してしまうのですから、皮肉としか言いようがありません。
 一方、小沢氏や政府側の言い分の不当性にも触れておかなくてはなりません。例えば小沢氏は、本会見を「天皇陛下ご自身に聞いてみたら、手違いで遅れたかもしれないが会いましょうと必ずおっしゃると思う」などと正当化していますが、これは全く本質的な主張ではないばかりか、別の疑念を生み出しています。小沢氏が「天皇がやると言ったら正当で、そうでなければ不当である」と考えているなら、天皇の立場上まずあり得ないとはいえ、仮に天皇が拒絶したなら自分の非を認めるのでしょうか。もしくは、仮に天皇が会見を断った場合、天皇が会見に同意した相手とのみ会見を設定すべきと考えているのでしょうか。そうなると、それこそ天皇の権力が恣意的に使われる事態になりかねませんが、小沢氏がいかなる考えを持っているのかが気になります。
 さらには、政府は「中国は重要だから政治的利用ではない」などといった主張も行っているようですが、この言い分は完全に破綻していると言わざるを得ません。もし本気でそのようなことを言っているのであれば、今回のようなゴタゴタが二度と発生しては困りますので、政府は「1ヶ月ルールに縛られない重要な国リスト」と「慣例を無視するまでもない取るに足らない国リスト」を一覧にして公開し、どの国なら慣例を無視するまでもないほど重要でないのか明確にしなくてはなりません。それができないのであれば、このような意味の分からない主張はやめるべきです。
 そして私は何より、今回の件によって「慣例」に過ぎないものが法と同等の権威を持ってしまうことを強く危惧しています。実際にそのような意見もマスコミなどを中心に散見され、見過ごせない状態になっています。もし1ヶ月ルールに合理性があり、これを絶対に遵守する必要があるというのなら、国民の代表たる議会が法的なルールとして明確に定めれば良いことです。いつ、どこで、誰が、どのように、何の目的で作ったとも知れない「慣例」が法律並みに機能し、しかもそれを役人が運用できるのであれば、それは不健全な状態であると言わざるを得ません。

 GlassFish v3の目玉といえば、ここまでに使ってみたServlet 3.0やJSF 2.0の他、EJB 3.1とJPA 2.0が代表的です。当初はEJBを動かすことができませんでしたが、DIの方法を色々と試してみたところ、何とかEJBとJPAが動作しましたので、その覚書をしたためておきます。
 Servlet 3.0とEJB 3.1の面白い点として、以前まではこれらをそれぞれwarとjarに格納し、earを作ってデプロイする仕組みとなっていましたが、今回からはEJBをclasses以下に配置し、すべてwarとして格納してデプロイしてしまっても正しく認識されます。その際にapplication.xmlもweb.xmlも書く必要がないため、単純なServlet + EJBであればXMLを1つも書かなくても動作してしまいます。このような仕様となったためか、GlassFish v3 PreviewのAdminコンソールでは「Enterprise Application」や「EJB Application」などといった区分がなくなっており、すべて「Applications」として管理されています(正式版でどうなるのかは不明)。その際、リストの「Engines」項目に[ejb, jpa, web]などと表示され、何が含まれているのかが分かるようになっています。
 JPAを使用する場合はpersistence.xmlを書かなくてはなりませんが、EJB + JPA + Servletであっても必要なXMLはこれだけです。しかも全部classesに格納できるため、構成が非常にすっきりします。さらに、デバッグに便利なディレクトリデプロイを使用する場合、warのルートになるであろうディレクトリ1つ指定するだけで平然と動くため、動作テストを行うにも大変便利です。
 本来ならJPA 2.0の目玉である悲観的ロックやCriteria APIなども使ってみるべき場面ですが、なぜかGlassFishの調子が非常に悪く、v2であれば明らかに動作するコードでも例外を投げてきたり、persistence.xmlでcreate-tablesを設定していてもテーブルを作ってくれる時と作ってくれない時があったり(何度もリデプロイを繰り返すと「そのうち作成される」という素敵な状態)、ジェネリックス対応のcreateQueryなどに至っては実装されていなかったりするため、今後の楽しみにしておきます。
 今回はとにかくEJB + JPA + Servletを動かすのみであるため、以下のような大変単純な構成としました。
/WEB-INF
 /classes
  /com
   /yamicha
    /ejb31test
     EJB31Test.java
     EJB31Servlet.java
     Persistence20Table.java
  /META-INF
   persistence.xml
 当初、META-INFをルートに置くかclassesに置くかで迷いましたが、Servletのclasses内にEntityクラスを置く場合には、META-INFもclassesに置くのが正解でした。これ以外のXMLは不要で、すべてアノテーションで代用しています。
 Servlet 3.0のアノテーション及びEJBをclassesに置いている以外の点は、ほとんど以前までのEJBと同じです。ただ、以前のTopLinkはEclipseLinkに名称変更されており、persistence.xmlもそれに伴ってプロパティ名などが変わっています。
<?xml version="1.0" encoding="UTF-8"?>

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MySQL" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/MySQL</jta-data-source>
    <properties>
      <property name="eclipselink.jdbc.driver"
        value="com.mysql.jdbc.Driver" />
      <property name="eclipselink.ddl-generation"
        value="create-tables" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="database" />
      <property name="eclipselink.target-database" value="MySQL" />
      <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>
 後はごく普通のEJBとServlet 3.0です。
// WEB-INF\classes\com\yamicha\ejb31test\EJB31Test.java
package com.yamicha.ejb31test;

import javax.ejb.*;
import javax.annotation.*;
import javax.persistence.*;
import java.util.List;

@Remote @Stateless(name="EJB31Test" , mappedName="ejb/EJB31Test")
	public class EJB31Test{
	@PersistenceContext(unitName="MySQL") private EntityManager em;

	public void addRecord(String msg){
		em.persist(new Persistence20Table(msg));
	}
	public List<Persistence20Table> getRecords(){
		return (List<Persistence20Table>)
			em.createQuery(
			"SELECT p FROM Persistence20Table p").
			getResultList();
		// JPA 2.0 にはせっかく以下のような
		// TypedQuery<T> createQuery(String , Class<T>)
		// おあつらえむきのものがあるのに
		// どういうわけか JAR に含まれていない...
	}
}

// WEB-INF\classes\com\yamicha\ejb31test\Persistence20Table.java
package com.yamicha.ejb31test;

import javax.sql.*;
import javax.persistence.*;

@Entity @Table(name="per20table" , schema="yamicha")
	public class Persistence20Table
	implements java.io.Serializable{
	private int id;
	private String name;

	public Persistence20Table(){
	}
	public Persistence20Table(String s){
		name = s;
	}

	@Id @Column(name="id") @GeneratedValue public int getId(){
		return id;
	}
	@Column(name="name") public String getName(){
		return name;
	}

	public void setId(int i){
		id = i;
	}
	public void setName(String s){
		name = s;
	}
}


// WEB-INF\classes\com\yamicha\ejb31test\EJB31Servlet.java
package com.yamicha.ejb31test;

import javax.servlet.annotation.*;
import javax.ejb.*;
import javax.annotation.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.persistence.*;
import java.io.*;
import java.util.List;

@WebServlet(name="ejb31servlet" , urlPatterns={"/*"})
	public class EJB31Servlet extends HttpServlet{
	@EJB(beanName="EJB31Test") private EJB31Test test;

	public void doGet(HttpServletRequest request ,
		HttpServletResponse response) throws IOException{
		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();

		test.addRecord("EJB 3.1");
		test.addRecord("Java Persistence API 2.0");
		test.addRecord("Servlet 3.0");
		test.addRecord("JSF 2.0");

		List<Persistence20Table> records = test.getRecords();
		for(Persistence20Table record : records)
			out.println(record.getName());

		out.close();
	}
}
 よりいっそう「必要な部分だけ書けば動く」ようになっており、昔の惨劇としか言いようがなかったEJBとは大違いです。
カテゴリ [開発魔法][社会問題] [トラックバック 0][コメント 0]

2009年のニュース
2009/12/20(Sun)08:24:10
 今年も国内外で様々な事件や動向が発生したものですが、年末の風物詩といえば「今年のニュース」です。米国でオバマ氏の新政権が発足し、そして日本でも政権交代が発生するなど、今年は主に政治の面で激動の年でしたが、経済の低迷や冤罪事件、臓器移植問題、芸能人の麻薬汚染など見過ごせない問題も非常に多く存在しました。大量の人命が失われた福知山線事故や秋葉原通り魔などの衝撃的なニュースと違い、見た目のインパクトはそれほど大きくないものの、考えさせられるニュースが多い印象です。
 全国紙では読売新聞が「〜年読者が選ぶ10大ニュース」、毎日新聞が「〜年重大ニュース」と題した投票型のニュースランキングを毎年開催しており、インターネット上からも投票や閲覧が可能となっています。読売新聞のものは国内と海外が別扱いとなっており、それぞれ10項目を自由に選んで投票するシステムなのですが、10大ニュースに選ばれた10個を的中させた人には賞金が贈呈される仕組みとなっているため、賞を狙うなら「自分が選ぶ10大ニュース」ではなく「他の人が投票しそうなニュース」に投票することになり、バイアスが生じます。芸能、スポーツ、天皇ネタが非常にランクインしやすいのも特徴です。
 毎日新聞はカテゴリ(社会、国際、経済、政治など)ごとに1つのニュースに投票し、それぞれのカテゴリでトップを選定する方式ですが、海外各地で戦争や武力侵攻、テロ、革命、大事故などが大量に発生し、経済も国内外でボロボロ、政治も汚職や政争で散々たる有様であったとしても、「社会」に該当する事件が「上野動物園のパンダの赤ちゃん誕生」程度しかなければ、社会ではそれが選ばれる一方、国際などではトップニュースが1つしか選ばれません。非常に偏った選定方式といえるでしょう。
 なお、読売新聞の2009年国内10大ニュースでは、次の10個が選ばれています。
  1. 衆院選で民主308議席の圧勝、歴史的政権交代で鳩山内閣発足
  2. 日本でも新型インフルエンザ流行
  3. 「裁判員制度」スタート
  4. 日本がWBC連覇
  5. 酒井法子容疑者、覚せい剤所持で逮捕
  6. 天皇陛下即位20年
  7. 高速道「上限1000円」スタート
  8. イチロー選手が大リーグ史上初の9年連続200安打
  9. 巨人が7年ぶり21度目日本一
  10. 「足利事件」の菅家さん釈放 DNA鑑定に誤り
 今年は大事なニュースが大量にありながら、「巨人」が入っているのが不思議です。WBCとイチローも含めれば、スポーツ関係からは3つもランクインしており、例によって芸能人と天皇もランクインしています。結果、足利事件が10位に追いやられる有様です。WBCや芸能人より余程重要なはずで、天皇即位20年と言っている間に菅家さんは17年も牢獄につながれていたのですから、評価のひどさにもほどがあります。冤罪を遠い世界の出来事と考える風潮は未だに根強いようです。
 1位が政権交代なのは大方の予想通りとして、10位外には11位に英国人殺害事件の犯人逮捕、12位に金配り、13位にアカデミー賞、14位に松井選手のニュースが入っています。一方、台風による死者・行方不明者58人のニュースは17位、鳩山氏の偽装献金は25位、日本航空が26位、臓器移植法改正が28位と、かなり重要なニュースが軒並みスポーツや芸能より大きく下に位置しており、毎年恒例ながら非常に不思議です。日本は災害列島ですから災害は他人事ではありませんし、日本航空の問題は日本経済にかかわり、臓器移植に至っては国民全員に関係があるはずですが、この関心の低さはどうしたものでしょうか。
 それでは以下、当ブログ恒例の「今年の10大ニュース」です。

1.民主党圧勝で政権交代実現
 93年の自民党下野は到底「政権交代」と呼べる代物ではありませんので、実質的には戦後日本初の政権交代です。93年に連立を組んだ大量の中小規模政党は、96年には選挙協力を名目に新進党を結成するわけですが、この時点での民主党は議席にして1割程度の第三の政党に過ぎませんでした。新進党瓦解後は生き残りが次々に民主党に合流し、13年後の2009年になってようやく政権交代が実現しましたが、その過程で壊し屋までもが合流した結果がこの騒ぎです。
 ひとまず政権交代が発生したのは良かったとしか言いようがありませんが、最近気がかりなのは政権交代を「魔法」か何かと勘違いしているらしい人が多い点です。武力革命ならまだしも、民主主義社会の中道政党同士の政権交代においては、政権交代直後に社会が劇的に変化するようなことはほぼありません。仮に前政権の間違いを正すにしても、突如としてそれを行うと社会や経済が大混乱に陥るため、時間をかけて少しずつ軟着陸させていくしかありません。ましてや、日本では60年間も実質的に政権交代が存在しなかったのですから、問題は簡単ではありません。
 ただ、民主党も「子ども手当て」のような無粋な政策は何とかならないものでしょうか。日本社会をゆがめている配偶者控除を廃止するのは評価できますし、それを子どもに振り向けるまでは目の付け所が優れているのですが、それを配るという発想にはあまりにも芸がありません。ある調査によれば、これによって自動車需要の向上が見込まれるそうですが、教育を充実するのに使える資金が自動車に消えるのでは意味がありません。
 自民党は金を配って政権を落としました。もし民主党が今から「子ども手当て」のような芸のないバラマキを破棄し、そのリソースを教育予算の向上や教育格差の排除など建設的な方向に振り向けるのであれば、マスコミは「話が違う」として批判の大合唱を始めるはずですが、分かっている人からは支持が得られるに違いありません。

2.足利事件の菅家さん釈放に続き、布川事件再審開始
 これも非常に重要なニュースです。冤罪といえば遠い世界の話のようですが、実際にはあらゆる人がそのリスクを背負っています。犯罪とは無縁の平和な日常を送っていたとしても、明日にも突如として嫌疑をかけられ、ほどなく逮捕され、拷問や恫喝ともいえる執拗な取り調べに加え、大事件であれば世論からも言われなき非難を浴び、抵抗したとしても別件逮捕で際限なく留置され、ついには「自白」させられる、という状況に置かれないとも限らないのです。
 足利事件はDNAが有罪の決め手となり、そして逆にDNAが冤罪の決め手ともなりましたが、いくらDNA鑑定技術が進歩したとしても、鑑定結果を盲信するのは誤りです。仮に鑑定が絶対に間違いないものであったとしても、意図的あるいは事故による検体のすり替えや鑑定誤り、本来証拠とはなり得ないものを鑑定して証拠とするなどの状況は防ぎようがありません。また、検察が検体を使い切ってしまえば、もはや追試は不可能となります。
 未だに自白偏重主義がまかり通っているのも問題です。一昔前の事件では、警察がどれほど探しても見つからなかったものが、逮捕した「犯人」が自白して証言した途端、探し終えたはずの場所から証拠品が見つかるなどという大変不自然なことが少なからず発生していますが、富山強姦冤罪事件などを見る限り、未だに自白信奉の風潮は根強く残っているようです。
 冤罪を防ぐには、取り調べの可視化も重要です。自民党政権下では実現の見通しが立ちませんでしたが、これも政権交代によって実現の見通しが立ってきました。

3.裁判員制度の開始
 裁判員制度自体は、実質的に「裁判員の判決も標準的な量刑の範囲に落ち着く」か「判例を外れた判決が2審以降で修正される」かのいずれかの経緯しかたどりようがなく、裁判の判決に画期的な影響を与える可能性は非常に低いのですが、私は同制度が裁判を分かりやすくし、かつ国民が法律や裁判に関心を持つきっかけとなるのであれば、全くの無駄ではないと考えていました。
 そして実際、裁判は多少なりとも分かりやすくなりつつあるようです。刑事裁判の被告人は本来なら裁判の主要人物のはずなのですが、実際には置き去りにされているという状況も、少しは改善される可能性が出てきました。まだまだ道半ばとはいえ、司法の側は少しずつ歩み寄っているといえるでしょう。
 ところが、国民が法律や司法に関心を持つことに関しては、あまり前進が見られないどころか、検察側が国民の知識のなさを逆用して量刑を煽り立てているような節さえあります。それを端的に表すのが、裁判員裁判のモデルケースとされた東京のバラバラ殺人事件で、検察は遺体の肉片の写真や生前の記録、またショッキングな言葉を強調するなどして、感情に訴えているとしか言いようのない方法を用いていました。
 このような方法を用いられては、被害者のショッキングな遺体の写真の有無、あるいは生前の幸せな思い出の有無など、事件に全く関係のない部分によって量刑が決まってしまう恐れがあります。そうした検察の情報を受け取る立場である国民の側も、例えば福岡の飲酒運転による3児死亡事故に対して、業務上過失致死であるとした1審判決に対して「3人も死亡したのだから、より罪の重い危険運転致死を適用しないのはおかしい」との意見も存在するなど(危険運転致死を適用しないとの判決は、罪の要件を満たさないと判断されたからであって、死亡した人数によって適用する罪を変えることはできない。「判決は事実誤認であるので同罪を適用すべき」と主張することはできる。なお、同事件の2審判決では危険運転致死が認定された)、感情論を見抜く目が十分とは言いがたい状況です。
 さらに、責務を終えた裁判員には過剰なまでの守秘義務が課せられ、以降の裁判員が先人の知見を生かしようのない状況に陥っています。この部分の改善も今後の課題でしょう。

4.バラク・オバマ大統領の政権が発足
 米国も日本も民主党は大変です。世界同時不況や失策が重なって前政権が敗北した点が同じなら、前政権の遺産を引きずっているせいで成果を出すことが難しく、何をどうあがいても必ず批判が飛んでくるのも同じです。一旦動き出したものを止めるのは非常に難しく、まず加速を緩めて、それから減速し、静かに停止させる必要があるのですが、進んでいる限りは文句を言われます。これは日本の民主党の経済政策についてもそうですし、米国民主党の海外派兵問題などでも同じです。
 ましてや、非常に強い権限を持つ大統領が、たかだか8年の共和党政権の遺産を処理するだけで、1年かけてもなかなか成果を挙げられないのに、それぞれ自己利益を優先する相手を連立に抱える日本の民主党が、50年以上の自民党の遺産をわずかな期間で処理するなど、人間にできることではありません。
 何をやっても文句を言われ、つくづく大統領とは大変なものです。

5.鳩山氏の偽装献金問題
 麻生氏といい鳩山氏といい、世襲議員にはまともな感覚が欠如しているのでしょうか。経済政策を行う上で、生活必需品など物の価値を認識していなくてはならないのは当然で、カップラーメンの価値も認識していなかったり、数億の金を受け取っても何とも考えないような人間が行う経済政策には、嫌でも疑問符をつけざるを得ません
 せめて代表選で岡田氏が選ばれればマシであった、と言いたいところですが、この人も政治家の世襲でこそないものの、イオンの御曹司です。また、自民党総裁の谷垣氏も世襲議員です。世襲だから感覚が異なっていると決め付けるのは乱暴ですが、一抹の不安を覚えるのは当然の反応でしょう。
 ただ、国民が世襲議員の感覚にあきれ果て、それが世襲でない議員を生み出したり、重要なポストに就けたりする原動力となれば、きっと世襲の傾向は終息に向かうはずです。事実、先の衆院選を見ていても、政党や政治家はかなり世襲の有無を気にするようになってきており、少なくともこの時点では、世襲を減少させる機運は十分にあるよう見受けられました。
 ところが、最近になって次のようなニュースを見かけました。「小泉進次郎氏ツアー、50人枠に5000人の応募」。2005年の低IQ選挙に引っかかった人々も、さすがに少しは懲りたかと考えていましたが、どうやら私の考えは大変甘かったようです。ましてや、世襲をとがめる機運など夢のまた夢です。日本の夜明けはまだまだ先のようです。

6.谷垣氏、自民党総裁に就任
 以前の参院選に加え、先の衆院選で敗北したことで、万年与党としての自民党の役割は終わりました。無残なまでにボロボロになってしまった自民党ですが、今後は二大政党の片方として復活を遂げ、存在感を発揮しなければなりません。それゆえに新総裁の責任は下手すると麻生氏以上に大きく、あえて火中の栗を拾った谷垣氏には、私もある程度の期待を持っていました。
 ところが、新スタートを切ったはずの自民党がまず言い出したのは、「自民党という名前に国民が拒否感を持っている」ことを理由とした党名変更でした。しかもその候補が「自由新党」「和魂党」という有様です。前者はまだしも、後者に至ってはいかにも右翼か何かのようで、未だに「イデオロギーの対立」の時代から頭の切り替えができていません。現代の選挙は浮動票が結果を左右するため、社会主義と保守主義の対立の時代と違い、保守を訴えたところでウリにも何にもなりません。
 また、「自民党というだけで話を聞いてもらえない」ほど嫌われているから「名前を変える」とは、国民の知性をあまりにも愚弄しています。名前が嫌われているのではなく、行動や体質が嫌われているのです。谷垣氏以下の自民党上層部の面々は、本気で自民党の「名前」が嫌われていて、それさえ変えれば支持が戻るとでも考えているのでしょうか。
 勝手に期待したのが悪かったとはいえ、谷垣氏には非常にがっかりさせられました。本当に復活を遂げる気があるのなら、もう少しまじめに立ち直りの方法を考える必要があります。

7.臓器移植法改正
 この問題は国民全員にかかわってくるはずなのですが、読売新聞の10大ニュースでは28位と非常に順位が低く、毎日新聞の投票でもほとんど票を集めていない(「政権交代」が同カテゴリにあり、カテゴリ当たり1つしか投票項目を選べないので当然といえば当然ですが)のが気になります。果たしてどれほどの国民が、改正臓器移植法の概要を把握しているのでしょうか。
 私はかねてから臓器提供意思表示カードを所持しており、提供する旨記載してあるため特に問題はありませんが、改正臓器移植法では家族同意のみで臓器を提供できるようになるため、臓器を提供したくない人はカードなどで意思を明確にし、それを携帯するなどしておく必要があります。さもなければ、改正臓器移植法が成立した以上、家族同意のみで勝手に臓器を提供されたとしても文句は言えません。
 また、臓器を提供する意思がある場合であっても、改正臓器移植法では本人の同意がなくても提供できるようになるからと、意思を表明しないでおくのも得策ではありません。家族同意があれば提供できるとはいえ、家族が本人の意思を図りかねて臓器提供を拒絶する可能性を考えると、やはり意思を明確にしておいた方が無難です。
 意思を明確にされていない皆様におかれましては、提供の意思の有無にかかわらず、カードなどで意思を明確にされることをおすすめします。

8.金配りがついに実施される
 金配り自体は昨年末からほぼ決定されていたとはいえ、2009年に入ってついに現実に金が配られてしまいました。金を配って支持を集めようとは、さもしい麻生氏の考えそうなことですが、実際には全く逆の結末となった点だけが救いです。
 実際のところ、金配りが強行採決されたのは2009年に入ってからですので、この時点で採決がなされなければ、金配りは行われずに済みました。また、そもそもこれ自体が正気の沙汰ではないような策ですので、私は実際に強行採決がなされてしまう直前まで、多少なりとも断念の可能性に期待を持っていました。
 ところが、金配りはあっさり可決され、実行されてしまいました。この時点で衆院選と麻生内閣の命運は決まったと言っても過言ではないでしょう。果ては、金配りなど失策どころか愚策でしかないにもかかわらず、麻生氏はこれを実績であると勘違いしていたらしく、素直に非を認めればここまでの大敗はせずに済んだところを、なおさら泥沼にはまっていきました。
 今から考えても、金配りが実行されてしまったのは残念でなりません。金配りが唯一有意義であったのは、「金を配っても選挙に勝てるわけではない」と政治家に知らしめた点のみです。

9.新型インフルエンザ問題
 新型インフルエンザの危険性自体は、季節性とそれほど変わりません。健康な人であればほぼ確実に治癒します。持病のある人は注意が必要ですが、それは季節性インフルエンザにしても、単なる風邪にしても同じです。
 それより何より恐ろしいものは、過剰反応に他なりません。事実、所属生徒が新型インフルエンザに感染した学校に対して謝罪を要求する電話が入ったり、インターネット上での誹謗中傷が発生する有様です。致死率の低い新型インフルエンザでさえこれですから、もし本当に致死率の高い病気が発生した場合、いかなる事件が起こるか分かったものではありません。
 また、一部では病院が混雑・パンクするなどの問題も発生したようですが、こうなると本当に優先すべき人が十分な診察を受けられなくなる恐れがあるばかりか、病院を通じての感染の可能性さえ危惧されます。今回は致死率の低い新型インフルエンザであるため大した問題とはなりませんでしたが、もし今後本当に危険な病気が流行した場合には、一体どうなってしまうのでしょうか。

10.Oracle、Sun Microsystemsを買収
 いまやJavaといえば、大抵のPCに導入されているどころか、携帯電話などの小型機器にも入っているほどポピュラーな存在です。また、インターネット上にもJavaで動いているサーバーは数多く存在し、ほとんどの人が知らないうちに恩恵にあずかっている技術です。
 そのJavaの作成元であるSun Microsystemsが、2009年4月にデータベースの巨人であるOracleに買収されたのですから、今年の10大ニュースに含める価値は十分にあるというものです。さすがに経済ニュースとして新聞社のサイトにも記載されはしましたが、本件は読売や毎日のニュース投票の選択肢にすら存在せず、日本での扱いが大変に小さいのが疑問でなりません。ビッグスリーの問題であれば多くの人が知っていますが、実際にGM車を用いたことのある人はそれほど多くはなさそうです。一方、今回の買収問題はあまり大きく報じられていませんが、知らないうちにJava技術を利用している人は多数に上ります。
 ちなみに、Oracleにとって買収の理由の1つとなったであろうMySQL ABは、2008年にSunに買収されており、OracleはSunごとMySQLを買い取ったという見方もできます。なお、MySQLはGoogleやYahooをはじめとした多くのサーバーで用いられている無償のデータベースで、これもまたほとんどの人が知らないうちに恩恵にあずかっているはずです。

 その他、上の10項目には入れませんでしたが、豪雨・台風被害、日本航空問題、日本郵政問題、釜山火災事故、米国の経済大混乱なども負けず劣らずであると考えています。10大ニュースというほどではないものの、注目度の観点からすれば、阿久根市の陰謀論市長・竹原氏の騒ぎも見過ごすわけにはいかない問題です。
カテゴリ [社会問題] [トラックバック 0][コメント 0]

<-前のページ [3] [4] [5] [6] [7] [8] [9] [10] [11] 次のページ->
- Blog by yamicha.com -