「Java」カテゴリーアーカイブ

iTunesで再生チャートランキングを定期的に自動で作りたい(3)

ひとまず、作ってみた。

MySQLでデータ管理をして、プログラムを実行すると、前回からの再生回数が差分として登録される。

DBはざっとこんな構成でテーブルは2つのみ。

mysql> desc tbm_track;

+———————-+————–+——+—–+———+——-+

| Field | Type | Null | Key | Default | Extra |

+———————-+————–+——+—–+———+——-+

| Track_id | int(11) | NO | PRI | NULL | |

| Name | varchar(160) | YES | | NULL | |

| Artist | varchar(80) | YES | | NULL | |

| Album_Artist | varchar(45) | YES | | NULL | |

| Album | varchar(200) | YES | | NULL | |

| Genre | varchar(45) | YES | | NULL | |

| Kind | varchar(45) | YES | | NULL | |

| Size | int(11) | YES | | NULL | |

| Total_Time | int(11) | YES | | NULL | |

| Disc_Number | int(11) | YES | | NULL | |

| Disc_Count | int(11) | YES | | NULL | |

| Year | int(11) | YES | | NULL | |

| Date_Modified | datetime | YES | | NULL | |

| Date_Added | datetime | YES | | NULL | |

| Bit_Rate | int(11) | YES | | NULL | |

| Sample_Rate | int(11) | YES | | NULL | |

| Play_Count | int(11) | YES | | NULL | |

| play_date | datetime | YES | | NULL | |

| Play_Date_UTC | datetime | YES | | NULL | |

| Sort_Atrist | varchar(45) | YES | | NULL | |

| Compilation | varchar(45) | YES | | NULL | |

| Persistent_ID | varchar(45) | YES | | NULL | |

| Track_Type | varchar(45) | YES | | NULL | |

| Location | varchar(500) | YES | | NULL | |

| File_Folder_Count | int(11) | YES | | NULL | |

| Lobrary_Folder_Count | int(11) | YES | | NULL | |

+———————-+————–+——+—–+———+——-+

26 rows in set (0.02 sec)

mysql> desc tbl_update

-> ;

+————————+————-+——+—–+———+——-+

| Field | Type | Null | Key | Default | Extra |

+————————+————-+——+—–+———+——-+

| Track_ID | int(11) | NO | PRI | NULL | |

| Update_data | datetime | NO | PRI | NULL | |

| Type | varchar(45) | YES | | NULL | |

| Play_Count | int(11) | YES | | NULL | |

| Incremental_Play_Count | int(11) | YES | | NULL | |

+————————+————-+——+—–+———+——-+

5 rows in set, 1 warning (0.02 sec)

mysql>

Javaのソースはひとまず動かしたレベル。XMLの読取はhttp://d.hatena.ne.jp/terazzo/20080524/1211656594を参考にして、そこのソースは割愛。

import java.io.IOException;

import java.net.URL;

import java.util.Date;

import java.util.List;

import java.util.Map;

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.EntityTransaction;

import javax.persistence.Persistence;

import javax.persistence.Query;

import org.xml.sax.SAXException;

import sample.plist.PropertyListUtils;

public class ItunesList {

/**

* @param args

*/

public static void main(String[] args) {

// TODO 自動生成されたメソッド・スタブ

ItunesList t = new ItunesList();

try{

t.printTracks();

}catch (Exception e){

e.printStackTrace();

}

}

private static final String TEST_FILE_PATH = “file:C:\\Users\\jun\\Music\\iTunes\\iTunes Music Library.xml“;

public void printTracks() throws IOException, SAXException {

// xmlファイルの読み込み

//URL url = getClass().getResource(TEST_FILE_PATH);

URL url = new URL(TEST_FILE_PATH);

Object content = PropertyListUtils.load(url);

Map tracks = (Map)*1 {

try{

Integer track_id_xml = (Integer)xml_track.get(“Track ID”);

//すでにDBに登録済みかチェック

boolean already_rip_check=false;

for(TbmTrack tbm_track_db : db_mater_list){

if(tbm_track_db.getTrack_id() == track_id_xml.intValue()){

//再生回数を更新

already_rip_check = true;

if*2.intValue() ){

TblUpdate update = this.setTblUpdate(tbm_track_db,(Integer)xml_track.get(“Play Count”));

em.persist(update);

tbm_track_db.setPlay_Count*3;

}

break;

}

}

if(!already_rip_check){

//該当レコードが無いので新規追加

TbmTrack track = setTbmTrack(xml_track);

em.persist(track);

}

}catch (Exception e){

e.printStackTrace();

}

}

tx.commit();

em.close();

emf.close();

}

private TblUpdate setTblUpdate(TbmTrack tbmtrack,Integer fromXml){

TblUpdate update = new TblUpdate();

update.setTrack_ID(tbmtrack.getTrack_id());

update.setUpdate_data(new Date());

update.setPlay_Count(tbmtrack.getPlay_Count());

update.setIncremental_Play_Count(fromXml.intValue() – tbmtrack.getPlay_Count());

return update;

}

private TbmTrack setTbmTrack(Map xml_track) {

TbmTrack track = new TbmTrack();

track.setTrack_id*4;

track.setAlbum*5;

track.setAlbum_Artist*6;

track.setArtist*7;

if(xml_track.get(“Bit Rate”) != null){

track.setBit_Rate*8;

}

track.setCompilation*9;

track.setDate_Added*10;

track.setName*11;

track.setGenre*12;

track.setKind*13;

track.setSize*14;

if(xml_track.get(“Disc Number”) != null){

track.setDisc_Number*15;

}

if(xml_track.get(“Disc Count”) != null){

track.setDisc_Count*16;

}

if(xml_track.get(“Year”) != null){

track.setYear*17;

}

if(xml_track.get(“Date Modified”) != null){

track.setDate_Modified*18;

}

if(xml_track.get(“Sample Rate”) != null){

track.setSample_Rate*19;

}

if(xml_track.get(“Play Count”) != null){

track.setPlay_Count*20;

}

if(xml_track.get(“Play Date”) != null){

track.setPlay_Date(new Date(((Integer) xml_track.get(“Play Date”)).longValue()));

}

track.setPlay_Date_UTC*21;

track.setCompilation*22;

track.setPersistent_ID*23;

track.setTrack_Type*24;

return track;

}

public static List getAllRecordsTbmTrack(EntityManager em){

Query q = em.createQuery(“select t from TbmTrack t”);

List list = q.getResultList();

return list;

}

}

*1:Map) content).get(“Tracks”);

int i=1;

EntityManagerFactory emf = Persistence.createEntityManagerFactory(“JPA_test”);

EntityManager em = emf.createEntityManager();

// DBの最新情報を取得

List db_mater_list = getAllRecordsTbmTrack(em);

EntityTransaction tx = em.getTransaction();

tx.begin();

for (Map xml_track : tracks.values(

*2:xml_track.get(“Play Count”) != null) &&

tbm_track_db.getPlay_Count() != ((Integer)xml_track.get(“Play Count”

*3:Integer)xml_track.get(“Play Count”

*4:Integer)xml_track.get(“Track ID”

*5:String)xml_track.get(“Album”

*6:String)xml_track.get(“Album Artist”

*7:String)xml_track.get(“Artist”

*8:Integer)xml_track.get(“Bit Rate”

*9:String)xml_track.get(“Compilation”

*10:Date)xml_track.get(“Date Added”

*11:String)xml_track.get(“Name”

*12:String)xml_track.get(“Genre”

*13:String)xml_track.get(“Kind”

*14:Integer)xml_track.get(“Size”

*15:Integer)xml_track.get(“Disc Number”

*16:Integer)xml_track.get(“Disc Count”

*17:Integer)xml_track.get(“Year”

*18:Date)xml_track.get(“Date Modified”

*19:Integer)xml_track.get(“Sample Rate”

*20:Integer)xml_track.get(“Play Count”

*21:Date)xml_track.get(“Play Date UTC

*22:String)xml_track.get(“Compilation”

*23:String)xml_track.get(“Persistent ID”

*24:String)xml_track.get(“Track Type”

ScheduleBoard to Googleカレンダー

以前、書いたエントリ以降、仕事で使っているスケジュールボードからGoogleカレンダーに移行するコードを書いたんだけれども、どうにも動作が不安定だったが原因が分かった。

#ま、端的にデバック不足だが。

CalendarQueryクラスを使う場合、デフォルトの25個までしか結果が得られないのでsetMaxResultsで上限をあげてやる必要がある。あと、デバッグしていて気がついたのはCalendarService.queryの応答は一定ではないということ。クエリーを投げるたびに結果が異なっていた(ので、バグを見つけづらかった)。

ただ、これでようやく解決。スケジュールボード → Googleカレンダーは安定して動くようになったので、後は逆だが、逆アセンブル(使用許諾で禁止されている)しない限り難しそうだ。。。となると、windowsGUIJavaから操作。面倒だなぁ。

Java5、GoogleカレンダーAPI独り言

久々にコーディングしての気づき。

StringTokenizerは非推奨

StringTokenizer は、互換性を維持する目的で保持されているレガシークラスであり、新規コードでは使用が推奨されていません。この機能の使用を考えているなら、String の split メソッドまたは java.util.regex パッケージを代わりに使用することをお勧めします。

次の例は、String.split メソッドを使用して文字列を基本的なトークンに分割する方法を示します。

 String[] result = "this is a test".split("\\s");

for (int x=0; x<result.length; x++)

System.out.println(result[x]);

知らなかった。

拡張for文(for/inステートメント)を使ってみた。コードは気持ち短くなった。

public class ScheduleBoardScheduleList {

private List<ScheduleBoardSchedule> scheduleBoardScheduleList;

public ScheduleBoardScheduleList(){

scheduleBoardScheduleList = new ArrayList<ScheduleBoardSchedule>();

}

public void addScheduleBoardScheduleList(ScheduleBoardSchedule sbs){

scheduleBoardScheduleList.add(sbs);

}

public List<ScheduleBoardSchedule> getscheduleBoardScheduleList(){

return scheduleBoardScheduleList;

}

@Override

public String toString() {

StringBuffer sb = new StringBuffer();

for(ScheduleBoardSchedule sbs : scheduleBoardScheduleList){

sb.append(sbs.toString());

}

return sb.toString();

}

}

アノテーションの使い勝手はまだ試せていないので分からない。

com.google.gdata.data.calendar.CalendarEventEntry#setQuickAdd

良く分からないが、trueとしてしまうと、時刻指定ができない模様。サンプロコードを見るかぎりは、

eventContent = new String("Tennis with John April 11 3pm-3:30pm")

としておいて、

myEntry.setContent(new PlainTextConstruct(eventContent));

myEntry.setQuickAdd(true);

で直近の該当時刻にスケジュールを登録されていた。日付を5/11のように指定すると日付は正しく反映されるが

時刻は反映されない。ただし、JavaDocを見ても良く解らんが、どうも日本では未公開の機能のようなので

突っ込まないこととした。。

set whether gd:content is quickadd info This will only effects Insert semantics.

Googleカレンダーで遊ぶ

会社で使っているスケジュールボードをリモートからも見たくてGoogleカレンダーと同期できないか思案してのPG。

久々なので、Eclipse3.6の環境をきれいにクリーンインストールしてからスタート。

まずは、GDateのサンプルをダウンロード。Eclipseで新規Javaプロジェクトを構築して解凍した一式を配置。

ただ、J2EEライブラリへのパスが無かったので、 GlassFishのライブラリを追加。最初は該当JARを探すも、

1.windows>設定>サーバ>ランタイム環境より、追加でJ2EEコンテナを追加

2.プロジェクトのビルドパスに ライブラリの追加>サーバ・ランタイムを行う

で適当なライブラリを追加してくれるので、コンパイルは通るようになる。

今回動かしたいカレンダーのサンプルのREADME.txtを見ると

The application can be built and run using the provided Ant build file found at

gdata/java/build.xml. The sample can be run in the following manner:

1. Edit gdata/java/build.properties to enter your Google Account username and

password, as well as the feed URI on which you want to test the sample.

2. Invoke the sample using the following commandline:

ant -f gdata/java/build.xml sample.calendar.run

とあるので、gdate直下(今回はプロジェクト直下)にbuild-samplesスクリプトは以下の、build.propertiesをコピーして、build.samples.xmlのsample.calendar.runを実効

すると

Buildfile: C:\Users\jun\workspace\GoogleCalenderSample\build-samples.xml

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

sample.calendar.build:

sample.calendar.run:

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

sample.calendar.build:

sample.calendar.eventfeed.run:

[java] java.lang.NoClassDefFoundError: sample/calendar/EventFeedDemo

[java] Caused by: java.lang.ClassNotFoundException: sample.calendar.EventFeedDemo

[java] at java.net.URLClassLoader$1.run(Unknown Source)

[java] at java.security.AccessController.doPrivileged(Native Method)

[java] at java.net.URLClassLoader.findClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] Could not find the main class: sample.calendar.EventFeedDemo. Program will exit.

[java] Exception in thread "main"

[java] Java Result: 1

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

sample.calendar.build:

sample.calendar.calendarfeed.run:

[java] java.lang.NoClassDefFoundError: sample/calendar/CalendarFeedDemo

[java] Caused by: java.lang.ClassNotFoundException: sample.calendar.CalendarFeedDemo

[java] at java.net.URLClassLoader$1.run(Unknown Source)

[java] at java.security.AccessController.doPrivileged(Native Method)

[java] at java.net.URLClassLoader.findClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] Could not find the main class: sample.calendar.CalendarFeedDemo. Program will exit.

[java] Exception in thread "main"

[java] Java Result: 1

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

sample.calendar.build:

sample.calendar.aclfeed.run:

[java] java.lang.NoClassDefFoundError: sample/calendar/AclFeedDemo

[java] Caused by: java.lang.ClassNotFoundException: sample.calendar.AclFeedDemo

[java] at java.net.URLClassLoader$1.run(Unknown Source)

[java] at java.security.AccessController.doPrivileged(Native Method)

[java] at java.net.URLClassLoader.findClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

[java] at java.lang.ClassLoader.loadClass(Unknown Source)

[java] Could not find the main class: sample.calendar.AclFeedDemo. Program will exit.

[java] Exception in thread "main"

[java] Java Result: 1

BUILD SUCCESSFUL

Total time: 1 second

と出る。解凍したパッケージを適切にプロジェクトに配置できていなかったので修正して実施。

(SRCフォルダと、build.xmlの関係が不適切だった)

Buildfile: C:\Users\jun\workspace\GoogleCalendarTest\gdate\build-samples.xml

sample.appsforyourdomain.dependencies:

template.require.service.jar:

BUILD FAILED

C:\Users\jun\workspace\GoogleCalendarTest\gdate\build-samples\appsforyourdomain.xml:40: The following error occurred while executing this line:

C:\Users\jun\workspace\GoogleCalendarTest\gdate\build-samples\core.xml:61: Missing dependency jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\build-samples/..//lib/gdata-appsforyourdomain-${appsforyourdomain.spec.version}.jar

Please run "ant appsforyourdomain.build.appsforyourdomain".

Total time: 322 milliseconds

今度は、version.propertiesを適当なフォルダに置けていなかった。

配置を修正してひとまず、サンプルは動いた。でも、内部エラーも出ている。今日はひとまずここまで。

Buildfile: C:\Users\jun\workspace\GoogleCalendarTest\gdate\build-samples.xml

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

[javac] Compiling 2 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\classes

[javac] 注:C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\CommonUtils.java は推奨されない API を使用またはオーバーライドしています。

[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\lib\sample-util.jar

sample.calendar.build:

[javac] Compiling 4 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\classes

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedPartialDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\CalendarFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\AclFeedDemo.jar

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

[javac] Compiling 2 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\classes

[javac] 注:C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\CommonUtils.java は推奨されない API を使用またはオーバーライドしています。

[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。

sample.calendar.build:

[javac] Compiling 4 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\classes

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedPartialDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\CalendarFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\AclFeedDemo.jar

sample.calendar.run:

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

[javac] Compiling 2 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\classes

[javac] 注:C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\CommonUtils.java は推奨されない API を使用またはオーバーライドしています。

[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\lib\sample-util.jar

sample.calendar.build:

[javac] Compiling 4 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\classes

sample.calendar.eventfeed.run:

[java] Your calendars:

[java]

[java] ��{�̏j��

[java] Printing all events

[java] All events on your calendar:

[java] test

[java] Full text query

[java] Events matching Tennis:

[java] Events from 2007-01-05 to 2007-01-07:

[java] Successfully created event Tennis with Mike

[java] Successfully created quick add event Tennis with John April 1

[java] Successfully created web content event World Cup

[java] Successfully created recurring event Tennis with Dan

[java] Event's new title is "Important meeting".

[java] Set a 15 minute EMAIL reminder for the event.

[java] Successfully deleted all events via batch request.

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

[javac] Compiling 2 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\classes

[javac] 注:C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\CommonUtils.java は推奨されない API を使用またはオーバーライドしています。

[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\lib\sample-util.jar

sample.calendar.build:

[javac] Compiling 4 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\classes

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedPartialDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\CalendarFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\AclFeedDemo.jar

sample.calendar.calendarfeed.run:

[java] Calendars in metafeed

[java]

[java] ��{�̏j��

[java] Calendars in allcalendars feed

[java]

[java] ��{�̏j��

[java] Calendars in owncalendars feed

[java]

[java] Creating a secondary calendar

[java] Updating the secondary calendar

[java] Deleting the secondary calendar

[java] The server had a problem handling your request.

[java] com.google.gdata.util.ServiceException: Internal Server Error

[java] Internal Error

[java] at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:624)

[java] at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:563)

[java] at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:552)

[java] at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:530)

[java] at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:535)

[java] at com.google.gdata.client.Service.delete(Service.java:1738)

[java] at com.google.gdata.client.GoogleService.delete(GoogleService.java:699)

[java] at com.google.gdata.data.BaseEntry.delete(BaseEntry.java:669)

[java] at sample.calendar.CalendarFeedDemo.deleteCalendar(CalendarFeedDemo.java:173)

[java] at sample.calendar.CalendarFeedDemo.main(CalendarFeedDemo.java:277)

sample.calendar.dependencies:

template.require.service.jar:

sample.core.dependencies:

core.sample.core.util.build:

[javac] Compiling 2 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\classes

[javac] 注:C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\CommonUtils.java は推奨されない API を使用またはオーバーライドしています。

[javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\util\lib\sample-util.jar

sample.calendar.build:

[javac] Compiling 4 source files to C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\classes

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\EventFeedPartialDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\CalendarFeedDemo.jar

[jar] Building jar: C:\Users\jun\workspace\GoogleCalendarTest\gdate\sample\calendar\lib\AclFeedDemo.jar

sample.calendar.aclfeed.run:

[java] Access control lists for your calendars:

[java] Calendar "":

[java] Scope: Type=USER ()

[java] Role: http://schemas.google.com/gCal/2005#owner

BUILD SUCCESSFUL

Total time: 21 seconds

 

PS:Eclipse3.6でAnt使ったが、Taskへのリンク機能が超便利。また、外部ファイルをproperty file属性で読み込んでいるのも知らないテクなので関心。Googleのサンプルでは、JARファイルのバージョンをversion.xmlとして外出しにして、指定したバージョンのファイルを取得する作りとなっていた。Eclipseプロジェクトのビルドパスが動的に指定出来れば良い手として使えそう。

Servlet#init とContext#initializer

J2EEアプリケーションの初期化処理を実装するにあたり、Servlet#init とContext#initializerのどっちが先か気になったので、WebLogic Server 9.2で試してみた。

結果はContext#initializerが先。

WebLogic独自仕様じゃないよね~と気になってググっていたら良いドキュメントを発見。

Servlet 3.0 仕様書邦訳版

http://www.cresc.co.jp/tech_info.html

以下、2.3 サーブレットのライフ・サイクル(Servlet Life Cycle)の2.3.2 初期化(Initialization)からの抜粋

この設定オブジェクトにより、そのサーブレットはウェブ・アプリケーションの設定情報からの名前-値の初期化パラメタにアクセスできる。この設定オブジェクトによりサーブレットはそのサーブレットの実行時環境を記述したオブジェクト(ServletContext インターフェイスを実装した)にアクセスできるようになる。ServletContextインターフェイスに関する更なる情報は第4章の「サーブレット・コンテキスト」を見られたい。

「オブジェクト(ServletContext インターフェイスを実装した)にアクセスできるようになる」とあるので、Servletの仕様としても間違い無いんだね。