2014年6月26日木曜日

Javaでジェネリックなインターフェースを作って実装で型パラメータを固定した場合にそれを取得する方法

こんなコードで取得できる。
public class Foo {
static interface Bar<K extends Enum<K>>{
}
enum Para{
HOGE,
FUGA,
}
static class FooBar implements Bar<Para>{
}
public static void main(String[] a){
Class<?> c = FooBar.class;
System.out.println(c);
for(Object o : c.getGenericInterfaces()){
ParameterizedType t = ParameterizedType.class.cast(o);
for(Type t2 : t.getActualTypeArguments())
System.out.println(t2);
}
}
}


実行結果

class Foo$FooBar
class Foo$Para 


あんまりやらないだろうけど。

2014年5月20日火曜日

はじめて個人でマイクロソフト Officeを買ってしまった

正確にいうと、Excel 2013。

Amazonで単品を購入。1万2千円くらいだった。もうちょっと出すと脱法的なOfficeスイートが買えるようだが、胡散臭いのは嫌いだし、そもそも俺が使いたいのはExcelのみだ。

ワードとパワーポイントはOpenOfficeとかGoogleで十分。俺はそもそもワープロ文書はめったに作らないし、プレゼンテーション資料は白黒の文字だけでしか作らない(営業資料とかでなくて報告書とかなので)。

しかしExcelだけは、やはり別格だと思うんだよね。表計算ソフトとしての機能もさながら、もはやグラフィックソフトと呼んでもいいくらいの、人類史上もっとも汎用性が高い万能ソフト。・・・Excel方眼紙は嫌いだけど。嫌いだけどたまには作るし。

つうか、こういうソフトもダウンロード販売になっていてちょっと戸惑った。ちょっと前に、近所のヤマダ電機の売り場で「売ってないなー」とか思ってた俺はもはや原始人だったようだ。

お。

インストール終わった。1Gくらいある普通の有償ソフトも買おうと思ったら居ながらにしてもうインストール完了。よい世の中になったものだ。

2014年5月16日金曜日

JPAを使ってみる。なるべく単純に。

JPAを試してみたい。Java SEで、Eclipse IDE for Java EE DevelopersとApache Derbyで、ひとまずエンティティの保存と取得まで。


まず、DBとしてApache Derbyを用意する。ダウンロード、展開の上、bin内のstartNetworkServer.batで起動しておく。


EclipseはEE版を利用する。これなら、新規プロジェクト作成時点で「JPA Project」なるものが選べる。

プロジェクト作成時のダイアログで、実装を選ぶことになるがここでEclipseLinkを選択かつダウンロードする。

できたプロジェクトのビルドパスに、derby.jarとderbyclient.jarを追加しておく。


Eclipseのプロジェクト内にJPA Contentなるものがあり、そこにpersistence.xmlというファイルが用意されている。

persistence-unit要素の中身がないので、書いてやる。



実際にはわりと紆余曲折あったのだが、とりあえずこうなった。


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
<class>mypackage.MyEntity</class>
<properties>
<property name="javax.persistence.schema-generation.create-database-schemas" value="true"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost/c:/D/Derby/MyData/JPA-TEST;create=true"/>
<property name="javax.persistence.jdbc.user" value="app"/>
<property name="javax.persistence.jdbc.password" value="app"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>

</persistence-unit>
</persistence>


実際には、JPAプロジェクトでpersisntence.xmlをダブルクリックして表示されるエディタのダイアログに適当なことを入力して生成したもの。

スキーマ自動生成のオプションがちょっとわかりにくい。のと、createを選択していても、一度生成済みなら生成しない(当然だが)ので、テストコードがIDの生成で失敗した後にIDの型を変えたら、今度はDBの方で型の不一致が起こった。で、drop & createでやり直したらうまくいった。


作ったエンティティというかモデルクラスというかは、これ。


package mypackage;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class MyEntity {
@Id
private String id = UUID.randomUUID().toString();
private String name;
private String description;

public void update(String name, String description){
this.name = name;
this.description = description;
}
public String id(){
return this.id;
}
public String toString(){
return String.format("%s(%s) : %s", name, id, description);
}
}


IDはひとまずサンプルにありがちなlongの連番にでもしようとして

 @ID
 @GeneratedValue(strategy=GenerationType.SEQUNCE)
 private Long id;

とかやったら、何かシーケンス生成でコケてた。調べるが面倒だし実はシーケンスのIDが好きでもないので、ランダム文字列を生成してみた。


このエンティティを新規に永続化・・・つうかDBに登録し、再度取り出すコードがこれ。

package mypackage;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class Main {
public static void main(String[] a){
String id;
{
EntityManagerFactory f = Persistence.createEntityManagerFactory("myUnit");
EntityManager em = f.createEntityManager();
EntityTransaction tx = em.getTransaction();
MyEntity foo = new MyEntity();
id = foo.id();
foo.update("Foo", "hogehoge");
tx.begin();
em.persist(foo);
tx.commit();
em.close();
f.close();
}
{
EntityManagerFactory f = Persistence.createEntityManagerFactory("myUnit");
EntityManager em = f.createEntityManager();
MyEntity foo = em.find(MyEntity.class, id);
System.out.println(foo);
}
}
}


効率的なことやエラーハンドリング的なことはさておき、単純にした。

これで、実行結果は、

Foo(f2f37087-2919-4579-825d-4624f9711f0d) : hogehoge

実際、Derbyにijで接続して中身を見ると、MYENTITYという名前(クラス名を大文字にしたもののようだ)のテーブルが勝手に生成されており、上記のデータが1件入っていた。


JPQLの使い方はこれからだが、たとえそれをまったく使わなくて検索部分は普通にJDBCを使ったとしても、上記のようなエンティティの登録と取得が自動になれば楽には楽だろうと思える。とは言え、JPQLは悪くなさそうなので使ってみるつもりではある。クリテリアAPIは煩雑そうで、試してみる気力もわかない。メタモデルだったっけか?とかも。

persistence.xmlをいちいち書かなくてはいけないのだろうか。それが何とも面倒くさい。複雑なシステムであればそういった管理の必然性もあるだろうが、簡単なケースのためになんかもっとこう端折ってデフォルトの動作ならエンティティ別の記述はいらないとかないのだろうか?



補遺

しくじったときのスタックトレースから。

Internal Exception: java.sql.SQLSyntaxErrorException: スキーマ'ME'は存在しません
Error Code: 20000
Call: INSERT INTO MYENTITY (ID, DESCRIPTION, NAME) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(Foo : hogehoge)

当たり前だがこんな感じでSQLが自動生成されるわけで。わかっちゃいるけど、まあ納得という感じだ。


参考になった記事

なんとなく全体像:http://yoshio3.com/2011/12/19/java-persistence-api-for-begineers/
 とりわけ、このスライド:http://www.slideshare.net/OracleMiddleJP/the-detail-of-jpa-20
EclipseLink関連部分:http://www.vogella.com/tutorials/JavaPersistenceAPI/article.html

2014年4月29日火曜日

Windows8.1を購入

PCを新調した。

Windows8の評判がすこぶる悪いので迷ったけど、8.1はまあ良いというし、俺はわりと長く使うので新しいに越したことはないだろうと、Windows8.1搭載のPCを購入。

心配していた手持ちのソフトだが、Photoshop6.0とIllustrator9.0は無事インストールできた。最新機能が必要なわけでもないし、高いし、いまさら買いなおすのは御免なんだが、やはりGimpとかでは使い勝手がイマイチだからな・・・・。

まあ、よかったよかった。

2014年1月14日火曜日

OpenJDK

とりあえず備忘録として。IPAの調査。↓

http://ossipedia.ipa.go.jp/nfs/pdf_pub/1007/208/671/671.pdf

Linux + Tomcat あっさりメモ

実際にはCentOSで。とりあえずTomcatが動くようにするのに最低限やること。


(rootで)


yum list *java*opendk*     ←バージョン確認だけなので別にやらんでもいいと言えばいい

Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: ftp.kddilabs.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
Installed Packages
java-1.7.0-openjdk.x86_64               1:1.7.0.45-2.4.3.4.el6_5        @updates
Available Packages
java-1.6.0-openjdk.x86_64               1:1.6.0.0-1.66.1.13.0.el6       base
java-1.6.0-openjdk-demo.x86_64          1:1.6.0.0-1.66.1.13.0.el6       base
java-1.6.0-openjdk-devel.x86_64         1:1.6.0.0-1.66.1.13.0.el6       base
java-1.6.0-openjdk-javadoc.x86_64       1:1.6.0.0-1.66.1.13.0.el6       base
java-1.6.0-openjdk-src.x86_64           1:1.6.0.0-1.66.1.13.0.el6       base
java-1.7.0-openjdk-demo.x86_64          1:1.7.0.45-2.4.3.4.el6_5        updates
java-1.7.0-openjdk-devel.x86_64         1:1.7.0.45-2.4.3.4.el6_5        updates
java-1.7.0-openjdk-javadoc.noarch       1:1.7.0.45-2.4.3.4.el6_5        updates
java-1.7.0-openjdk-src.x86_64           1:1.7.0.45-2.4.3.4.el6_5        updates


$ yum install java-1.7.0-openjdk  (JRE)
$ yum install java-1.7.0-openjdk-devel (SDK)

yumで指定する時は.より後ろはいらないようだ。知らんかった。


(ここから一般ユーザ)

「JRE_HOMEは「/usr/lib/jvm/jre」、JAVA_HOMEは「/usr/lib/jvm/java」になります。」

なので、

# JRE_HOME=/usr/lib/jvm/jre
# JAVA_HOME=/usr/lib/jvm/java
# export JAVA_HOME
# export JRE_HOME


# curl -O http://ftp.jaist.ac.jp/pub/apache/tomcat/tomcat-7/v7.0.50/bin/apache-tomcat-7.0.50.tar.gz
# tar -zxvf apache-tomcat-7.0.50.tar.gz

これで起動はした。