JavaプログラミングTips

 

java.util.Propertiesを用いたプロパティの取得方法. 1

プロパティの内容をMapに格納. 2

正規表現. 3

JFrameでGUI 3

eqaulsメソッドのオーバーライド(instanceofと内部的に用いるequals()メソッドの使い方)  5

DateFormatの使い方と問題点. 6

privateメソッドへのアクセス - リフレクション. 6

水平スクロールバーを持つJComboBox 8

Socketプログラミング(サーバ側). 8

Class.asSubclassの使い方. 10

CLI:Command Line Parser(コマンドライン引数解析ライブラリ). 10

Apache web server上でJava Web Startが起動するようにするには?. 11

web start での引数の与え方(Antとは違うので注意が必要). 12

web start でのリソースへのアクセス. 12

jarの使い方. 13

eclipseのプラグイン. 13

VisualEditor(VE)プラグイン. 13

VSSプラグイン. 13

Ant 14

Eclipseのnon-JavaロジェクトをJavaプロジェクトにするには. 15

Unsupported major.minor version 49.0 16

JNDI 19

カスタムAntタスク. 19

Javaデコンパイラ. 21

 

java.util.Propertiesを用いたプロパティの取得方法

 

クラス

java.net.URL;               // 今回ターゲットとするPropertiesファイルの参照位置を格納

java.io.InputStream;        // プロパティファイルへの入力ストリーム

java.io.OutputStream;      // プロパティファイルへの出力ストリーム

java.util.Properties;      // プロパティオブジェクト

 

メソッド

load(InputStream inStream);

InputStream inStream = new FileInputStream(“<ファイル名>”);

 

store()

setProperty()

getProperty()

 

String bis_properties_file = "/com/drkw/bis/bis.properties";         // パッケージルートから見たプロパティファイルの相対位置

 

       URL url = properties.getClass().getResource(bis_properties_file);   // プロパティファイルの参照位置をURLとして作成

// その際インスタンスからクラスオブジェクトを生成し、getResource()メソッドを呼ぶのがミソ

 

       String filename = url.getFile();                                     // 取得したURLをローカルファイル名に変換

       InputStream inStream = new FileInputStream(filename);               // 取得したファイル名からInputStreamを取得

       properties.load(inStream);                                          // プロパティをInputStreamからロード

       System.out.println(properties.getProperty("aaa"));                  // プロパティの値をキーから取得

      

       OutputStream outStream = new FileOutputStream(filename);            // 取得したファイル名からOutputStreamを取得

       properties.setProperty("aaa", "bbb");                               // プロパティのキーと値を設定

       properties.store(outStream, "Written by BISPropertiesConfigurator"); // プロパティをOutputStreamに保存

 

       // 別解

       inStream = url.openStream();                                        // URLクラスのopenStream()メソッドから、InputStreamを取得

       properties.load(inStream);                                          // この方法だとOutputStreamが入手できないのだが、ファイルの絶対パスが正確に入手できない場合

       System.out.println(properties.getProperty("aaa"));                  // こちらを使わざるを得ないと思われる。

 

 

プロパティの内容をMapに格納

 

        Set set = properties.entrySet();                                   // プロパティクラスはHashtableを継承するので、entrySet()メソッドが使える

                                                                           // entrySet()メソッドは、Set<Map.Entry<K,V>>、つまりMap.EntryオブジェクトをSetに突っ込んで返す

        Iterator it = set.iterator();                                      // Setを指すIteratorを取得する

        while (it.hasNext()) {                                      

            Map.Entry map = (Map.Entry)it.next();                          // Map.Entry(キーと値のペア)インタフェースをIteratorから取得

            System.out.println(map.getKey().toString() + "="

+ map.getValue().toString());

            // TODO: Implement MessgaeScheme building up

        }

 

正規表現

http://www.kt.rim.or.jp/~kbk/regex/regex.html#GROUPING

 

Stringsplit()は引数に正規表現を取り、文字列を分割する。

 

        String telegram = "0:1,00,00001,0,002730067,0,500000,1.45,0,2005/11/24,2,2005/11/18,08:40:01,1,0,1.5,2015/09/20,010,”

+ “273回 利付国庫債,273   国債,273 コツコサイ,1,0,,,,";

       

        Pattern pattern = Pattern.compile("[:,]+");                        // パターンとして、:もしくは,を持つ1個以上の文字列をマッチング対象と指定。

        String[] items = pattern.split(telegram);                        // 文字列を上記パターンに基づき、分割

 

 

 

JFrameGUI

 

public class MySwing extends JFrame {                  // JFrameを継承

   

    private JPanel panel;

    private JButton button1;

    private Dimension preferredSize;

   

    /** Creates a new instance of MySwing */

    public MySwing() {

        // set title

        this.setTitle("Hello JFrame");

        this.setBounds(50, 50, 500, 800);                                                // パソコンの画面(モニター)上での境界を指定

        preferredSize = new Dimension(500, 300);                                         // 望ましいサイズのDimensionオブジェクトを作成

        // set panel with no layout

        panel = new JPanel();

        panel.setLayout(null);                                                           // パネルはレイアウトを指定しなくても作成できる。その場合、

// そのパネル上の全てコンポーネントの大きさと境界はピクセル単位で指定する      @

        panel.setPreferredSize(preferredSize);        

        this.getContentPane().add(panel);                                                // パネルをペインに追加

        button1 = new JButton("Hello");               

        button1.addActionListener(new ActionListener() {                                 // JButtonオブジェクトにListnerオブジェクトを無名インナークラスとして追加

            public void actionPerformed(ActionEvent evt) {                               // この無名インナークラスはActionListenerインタフェースを実装しなければ

                JOptionPane.showMessageDialog(MySwing.this, "Hello JOptionPane!");       // ならないので、ここでactionPerformedメソッドを実装している。

            }

        });                                                                              // 無名インナークラス定義およびメソッドを閉じる

        button1.setBounds(30, 30, 100, 30);                                              // @でレイアウトを指定していないので、大きさと境界をピクセル単位で指定

        panel.add(button1);                                                             

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                             // デフォルトのクローズアクションの指定

        this.setPreferredSize(preferredSize);                                           

        this.pack();                                                                     // 望ましいサイズの指定があった場合に、大きさの調整をする

        this.setVisible(true);                                                           // JFrameを表示可能にする(showメソッドは非推奨メソッドになった)

 

        JOptionPane.showInternalMessageDialog(this.getContentPane(),                     // JPanelにも足せるが、レイアウト等を考慮する必要がある

    "Internal Dialog", "Internal Dialog Test", JOptionPane.INFORMATION_MESSAGE);  // Internal Frameとしての、JOptionPane

       this.setIconImage(new ImageIcon("H:/MyDocuments/Java/JavaGUIプログラミング" +     // IconImageの設定

                     "/MyEclipseFrame/src/nintoku.gif").getImage());

       this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);    }                      // 最大化指定

 

       /**

·                  Window Events              listened by WindowListener

·                  WINDOW_OPENED

·                  WINDOW_CLOSED

·                  WINDOW_CLOSING

·                  WINDOW_ICONIFIED

·                  WINDOW_DEICONIFIED

·                  WINDOW_ACTIVATED

·                  WINDOW_DEACTIVATED

*/

   

}

 

 

eqaulsメソッドのオーバーライド(instanceofと内部的に用いるequals()メソッドの使い方)

    public boolean equals(Object obj) {

        boolean result = false;

        if (obj instanceof BISMessage) {                                                 // 与えられた引数がオブジェクト型だろうが、比較先の型が抽象クラスだろうが、

             if (this.recordHeader.equals(recordHeader) &&                               // instanceofIS-A関係が真の場合、必ずtrueを返す。

                 this.recordNumber.equals(recordNumber) &&                               // むしろ、その後内部的に用いる内容の比較で==演算子をつかってしまったり

                 this.recordId.equals(recordId)) {                                       // 別の変数を比較してしまったりするところに落とし穴がある。

                result = true;

             }

        }

        return result;

    }

 

 

DateFormatの使い方と問題点

import java.text.DateFormat;

    public void process() {

        DateFormat df = DateFormat.getDateTimeInstance();                                // getDateTimeInstance()引数なしは、デフォルトのロケールに対して、

                                                                                         // デフォルトのフォーマットスタイルを持つ日付時刻フォーマッタを取得する。

        //DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,              // 引数dateStyle, timeStyle, aLocaleを指定して、自分の欲しいスタイルの

 //    DateFormat.MEDIUM, Locale.JAPAN);                                          // 日付時刻フォーマッタを取得できる。

        Date mydate = null;

        try {

            mydate = df.parse("2006/02/14 14:49:58");                                    // parse()メソッドはスレッドセーフではないため、同じインスタンスが別々のスレッドに

        } catch (ParseException pe) {                                                    // 同時にアクセスされてしまうと競合を起こす。インスタンスが別であれば競合は

            System.err.println(pe.getMessage());                                         //起こさないようなので、そのメソッドをsynchronizedにするなどの方策を採れば、

        }                                                                                //問題は回避できる。

        System.out.println(mydate);

    }

 

 

privateメソッドへのアクセス - リフレクション

import java.lang.reflect.Method;

import java.lang.reflect.Field;

 

public class Main {

       public static void main(String args[]) {

              HelloWorldRef hello = new HelloWorldRef();

              try {

                     String arg = "***";

                     // 引数オブジェクトのタイプを設定

                     Class[] clss = new Class[1];

                     clss[0] = arg.getClass();

                     // 引数オブジェクトの値を設定

                     Object[] objs = new Object[1];

                     objs[0] = arg;

                    

                     /*

                      * クラスオブジェクトから、メソッドを取得

                      * getDeclaredMethod()はそのクラス内で宣言されているメソッド(プライベートも含む)のみ抽出

                      * getMethod()publicメソッドのみ抽出

                      */

                     Method method = hello.getClass().getDeclaredMethod("sayHelloWorld", clss); 

                     //これを設定しておかないと、IllegalAccessExceptionが発生                                                                                                                                

                     method.setAccessible(true);                                                                                 

                    

                     // メソッドを実行

                     Object ret = method.invoke(hello, objs);

                     // 戻り値を表示

                     System.out.println(ret);

                    

                     /*

                      * クラスオブジェクトから、フィールドを取得

                      */

                     Field field = hello.getClass().getDeclaredField("hello");

                     field.setAccessible(true);

                     // フィールドの値を表示

                     System.out.println((String)field.get(hello));

                    

              } catch (NoSuchMethodException nsme) {

                     System.err.println(nsme.getMessage());

              } catch (NoSuchFieldException nsfe) {

                     System.err.println(nsfe.getMessage());

              } catch (IllegalAccessException iae) {

                     System.err.println(iae.getMessage());

              } catch (InvocationTargetException ite) {

                     System.err.println(ite.getMessage());

              }

       }

}

 

class HelloWorldRef {

       private String hello;

       public HelloWorldRef() {

              hello ="Hello World!" ;

       }

       private String sayHelloWorld(String deco)   {

              return deco + hello + deco;

       }

}

 

水平スクロールバーを持つJComboBox

public class HolScrollComboBox extends JComboBox {

 

    public HolScrollComboBox() {

            super();

            setUI(new HolScrollComboUI());                                    // 独自のUIをセット

      }// end of default constructor

   

    public class HolScrollComboUI extends BasicComboBoxUI {

            protected ComboPopup createPopup() {

                  BasicComboPopup popup = new BasicComboPopup(comboBox) {     // BasicComboPopupを継承する無名クラスを宣言

                        protected JScrollPane createScroller() {              // createScroller()をオーバーライド

                              return new JScrollPane(list,

                                          ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,

                                          ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

                        }// end of method createScroller

                  };

                  return popup;

            }// end of method createPopup

      }// end of inner class HolScrollComboUI

 

}

 

 

 

Socketプログラミング(サーバ側)

サーバのソケットを閉じるときは、finallyブロックにて、ServerSocketSocketを別々に閉じるのが望ましい。

 

public class MockServerSocket implements Runnable {

 

    private static Logger logger = BISLoggerHandler.getLogger(MockServerSocket.class);

 

    private ServerSocket serverSocket;

    private Socket serverSideSocket;

    private BufferedReader reader;

    private BufferedWriter writer;

 

    public MockServerSocket() {

        logger.debug("Mock Server Socket is starting up...");

        try {

            serverSocket = new ServerSocket(31001);

        } catch (IOException ioe) {

            logger.info(ioe.getMessage());

        }

    }

   

    public void run() {

        try {

              logger.info("Mock server starts listening...");

            serverSideSocket = serverSocket.accept();

            reader = new BufferedReader(new InputStreamReader(serverSideSocket.getInputStream()));

            writer = new BufferedWriter(new OutputStreamWriter(serverSideSocket.getOutputStream()));

            writer.write("Hello BISSocketTest!");

            writer.newLine();

            writer.flush();

            Thread.sleep(10000);

        } catch (IOException ioe) {

            logger.debug(ioe.getMessage());

        } catch (InterruptedException ie) {

            logger.debug(ie.getMessage());

        } finally {

              try {

                   serverSideSocket.close();

            } catch (IOException ioe) {

                logger.debug(ioe.getMessage());

            }

              try {

                     serverSocket.close();

            } catch (IOException ioe) {

                logger.debug(ioe.getMessage());

            }

              logger.info("Mock server terminated.");

        }

       

    }

}

 

Class.asSubclassの使い方

このメソッドはいわゆるクラスリテラルもしくはClass.getClass()で参照することが出来る、「Classクラスのインスタンス」が、継承関係に則ってキャスト出来るかどうかを検証し、出来る場合はキャストされた参照を返し、出来ない場合は例外ClassCastExceptionを投げる。具体的に以下の親子関係が存在するとしよう。

 

Object <- Parent <- Child  Parentは、Objectを継承し、ChildParentを継承する)

       <- String           Stringは、Objectを継承する)

 

このとき、以下のコードは:

      try {

            Class<?> cp = Parent.class;

            Class<?> co = cp.asSubclass(Object.class);

            //Class<?> cs = co.asSubclass(String.class);    // 継承関係に無い

            Class<?> cp2 = co.asSubclass(Parent.class);

            //Class<?> cc = cp2.asSubclass(Child.class);    // Parent.classChild.classにはキャスト出来ない

      } catch (ClassCastException e) {

            e.printStackTrace();

      }

コメントアウトしてあるところを実際に実行すると例外が投げられる。    

 

 

CLI:Command Line Parser(コマンドライン引数解析ライブラリ)

import org.apache.commons.cli.Options;

import org.apache.commons.cli.Option;

import org.apache.commons.cli.CommandLineParser;

import org.apache.commons.cli.CommandLine;

import org.apache.commons.cli.BasicParser;

import org.apache.commons.cli.ParseException;

import org.apache.commons.cli.HelpFormatter;

 

 

               // Usage

               Options options = new Options();                                          // OptionオブジェクトのコレクションCommandLineParserオブジェクトに渡される

               Option optionM =

new Option("m", true, "running mode <dev|uat|prd>");                 // Optionオブジェクト。いろいろな方法で作成できる。

               optionM.setRequired(true);                                                // 必須オプションとして指定。指定がない場合、MissingOptionExceptionが返される。

               optionM.setArgName("mode");                                               // 引数として(ヘルプに)表示される値を指定

               options.addOption(optionM);

               CommandLineParser parser = new BasicParser();

               CommandLine line = null;

              

               try {

                     line = parser.parse(options, args);                                  // コマンドラインの解析

               } catch (ParseException pe) {

                     HelpFormatter formatter = new HelpFormatter();

                     formatter.printHelp(TicketClipper.class.toString(), options, true);  // ヘルプ分の出力

                     System.exit(2);

               }

 

               // Obtain the running mode from option value

              mode = line.getOptionValue("m");                                           // オプションパラメタの取得

 

 

Apache web server上でJava Web Startが起動するようにするには?

新しいMIMEタイプをweb serverに設定する必要がある。

Web サーバを設定して、拡張子 .jnlp を持つすべてのファイルが application/x-java-jnlp-file MIME タイプとして設定されるようにする。

Apache Web サーバの場合、${APACHE_HOME}/conf/mime.types 設定ファイルに次の 1 行を追加する必要があります。

application/x-java-jnlp-file jnlp

注意!

これで安心と思って、以下のようにやってもうまくいかない。

http://localhost/basind.jnlp

これだと(何故か)ブラウザは依然として.jnlp ファイルの内容を表示してしまう。

ちゃんと立ち上げるには、

http://ibtkygsw87083/basind.jnlp

として、(localhostではない)ホスト名を指定する必要がある。

また、.jnlpファイル内でのcodebase属性の値がおかしい場合もうまく動かなくなることがある。(Apacheから起動しようとしているにもかかわらず、:8080を指定していたりなど)

 

IIS web

 

 

 

 

web start での引数の与え方(Antとは違うので注意が必要)

<application-desc main-class="Main">
    <argument>arg1</argument>
    <argument>arg2</argument>
</application-desc>

 

web start でのリソースへのアクセス

web startアプリケーション内部からリソースへアクセスするには以下のようにする。

1.   アクセスしたいリソースをJarファイルに閉じ込める

2.   URLオブジェクトを経由してロードする。その際は以下のコマンドを使用する

URL url = this.getClass().getClassLoader().getResource(“<アクセスしたいリソースへのJarファイル内でのパス>”)

注)Jarファイル内でのパスの先頭に”/”は不要

 

ここには様々な落とし穴が待ち構えているので、それらを回避する方法を述べておこう。

1.<アクセスしたいリソースへのJarファイル内でのパス>の先頭には原則”/”はつけない。この場合、アプリケーションはこのクラスのルートを起点にリソースを探しにいく。

たとえば、アプリケーションのソースファイルの配置が以下のような場合、で

 

${APP.ROOT}

 |- src

     |- com

         |- drkw

              |- Hoge.class

 

このときあるプロパティファイルdefault.propertiesconfフォルダの中に格納したいといった場合に、Hoge.class内で以下のようにURLを取得しようと考えたとき、

URL url = this.getClass().getClassLoader().getResource(“conf/default.properties”)

 

このconfフォルダは${APP.ROOT}直下ではなく、${APP.ROOT}/srcの下に配備する必要がある。

 

2.Eclipseのクラスパス

log4j.propertiesなどのリソースはEclipseにて各テスト対象クラスの実行メニューからクラスパスとしての登録も必要。

 

注2)log4jの呼び方

これも癖があるので、具体例を示しておく。

 

    URL url = tsa.getClass().getClassLoader().getResource(“config/log4j.properties”);

    PropertyConfigurator.configure(url); 

    System.out.println(url);

 

出力例:

Eclipseからmainの場合

file:/H:/Development/TraderSalesAdmin/build/config/log4j.properties

 

web startの場合

jar:file:C:/Program%20Files/JavaSoft/Cache/javaws/http/Dlocalhost/P8080/DMTraderSalesAdmin/DMlib/RMTraderSalesAdmin.jar!/config/log4j.properties

 

 

jarの使い方

オプション:

       -f アーカイブファイルの指定

       -t アーカイブファイルの中身を列挙

       -x 指定されたファイルを抽出

 

例)

jarファイルの中身を見るには,

Ø       jar –tf <jarファイル名>

 

jarファイルの中身を取り出すには、

Ø       jar –xf <jarファイル名> <取り出したいファイル名>

 

注)Error in JAR zip-style comment? というメッセージが帰ってきた場合、jarのバグの可能性が高い。

このメッセージが返ってきたら、which jarUNIXの場合)でどのjarコマンドを使っているかを確認しよう。

(筆者はgcc/3.3/bin/jar-tfをオプションを使って中身を見ようとしてこのメッセージが出たが、j2sdk1.4.2_04/bin/jarで同じjarファイルに同じコマンドを適用したら正常に結果が返ってきたということがあった)

 

eclipseのプラグイン

eclipseでは、拡張キットがプラグインという形でインストールできる。

実に様々なプラグインが提供されている(らしい)。

 

VisualEditorVE)プラグイン

JFrame等のGUIコンポーネントを動的に表示しながら編集できるようにするプラグイン。

Eclipse3.1.2では、以下のプラグインのインストールを必要とする。

 

VE 1.1.0.1, GEF 3.1.1, EMF 2.1.2

 

VSSプラグイン

VSSプロジェクトとEclipseのプロジェクトを連携させるには、該当Eclipseプロジェクトを右クリックし、<Team><Share project>で以下のダイアログを開く。

後は、ユーザ名、フォルダ名等を指定すればOK

 

Ant

DefaultAntのクラスパスの指定にはバグがあるようです。(Eclipse 3.2

 

デフォルトのクラスパスの指定は以下だが、

 

(少なくとも筆者の環境では)これでは動かない。v3232m.jarがないためである。

上手いことこのjarファイルに対する依存性を取り除けないので、たとえば以下のようにExternalJarファイルを追加すると動くようになる。

 

 

 

 

Eclipsenon-JavaプロジェクトをJavaプロジェクトにするには

この現象(Javaプロジェクトがnon-Javaプロジェクトとして扱われてしまう)は特にCVSからコードを引っ張ってきたときに起こりやすい。

.projectファイルの内容がたとえば以下のような場合、

 

1

<?xml version="1.0" encoding="UTF-8"?>

<projectDescription>

       <name>BasIndServer</name>

       <comment></comment>

       <projects>

       </projects>

       <buildSpec>

       </buildSpec>

       <natures>

       </natures>

</projectDescription>

 

これを以下のように書き換える。

 

2

<?xml version="1.0" encoding="UTF-8"?>

<projectDescription>

       <name>BasIndServer</name>

       <comment></comment>

       <projects>

       </projects>

       <buildSpec>

              <buildCommand>

                     <name>org.eclipse.jdt.core.javabuilder</name>

                     <arguments>

                     </arguments>

              </buildCommand>

       </buildSpec>

       <natures>

              <nature>org.eclipse.jdt.core.javanature</nature>

       </natures>

</projectDescription>

 

Unsupported major.minor version 49.0

クラスファイルをコンパイルしたjavacのバージョンとそれを実行しようとしているVMjava)のバージョンが異なっているときに出る。

これを解消するには、Eclipseの場合以下を確認して、リビルドすればよい。

 

(コンパイラのバージョン)

 

実行するライブラリのバージョン

 

 

 

Incompatible JVM

 

PATHJDK1.4.1よりか高いバージョンのJDKもしくはJREが含まれていない可能性が高い。

また、JAVA_HOME環境変数をUserVariableではなく、SystemVariableに入れたら動くかも。(これはJAVA_HOMEがさらに別の環境変数を使用していたりする場合に特に当てはまる)

 

 

 

 

JNDI

JNDIを使ってDNSサーバ(tk1p0317inf.tokyo.dresdnerkb.com)に問い合わせをして、引数で与えられたホスト名を解決する。

 

import java.util.*;

import javax.naming.*;

import javax.naming.directory.*;

 

public class DNSSample {

 

      public static void main(String[] args) {

            // Must provide 1 argument that holds the name of the host/server.

            String name = args[0];

            Properties props = new Properties();

            props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");

            props.put(Context.PROVIDER_URL, "dns://tk1p0317inf.tokyo.dresdnerkb.com");

            try {

                  InitialDirContext idctx = new InitialDirContext(props);

                  Attributes attrs = idctx.getAttributes(name);

                  NamingEnumeration allAttr = attrs.getAll();

                  while (allAttr.hasMore()) {

                        Attribute attr = (Attribute) allAttr.next();

                        System.out.println("Attribute: " + attr.getID());

                        NamingEnumeration values = attr.getAll();

                        while (values.hasMore())

                              System.out.println("Value: " + values.next());

                  }

            } catch (NamingException e) {

                  e.printStackTrace();

            }

      }

}

 

 

カスタムAntタスク

antライブラリのTaskクラスを継承して、execute()メソッドをオーバーライドしたクラスを実装することで、カスタムAntタスクが定義できる。

この例は標準出力に”Hello AntTask!”と出力するタスクを定義している。

 

import org.apache.tools.ant.Task;

import org.apache.tools.ant.BuildException;

 

public class MyAntTask extends Task {

 

      // Actual task

      public void execute() throws BuildException {

            System.out.println("Hello AntTask!");

      }

     

}

 

Antbuild.xmlファイルからは以下のようにして呼び出す。

       <!--タスクの定義:タスク名、タスクを実装しているクラス名、そのクラスへのクラスパスを指定-->

      <taskdef name="myanttask" classname="aks.MyAntTask" classpath="lib/myanttask.jar"/>

     

     

      <target name="customanttask" depends="archive">

            <myanttask/>      <!--カスタムタスクの実行-->

      </target>

 

filesetも扱える応用例)

import java.io.File;

import java.util.Iterator;

import java.util.Vector;

import org.apache.tools.ant.BuildException;

import org.apache.tools.ant.DirectoryScanner;

import org.apache.tools.ant.Task;

import org.apache.tools.ant.types.Mapper;

import org.apache.tools.ant.types.FileSet;

import org.apache.tools.ant.util.FileNameMapper;

 

public class ReportCompileTask extends Task {

 

    private File file;

    private Vector<FileSet> filesets = new Vector<FileSet>();

    private FileNameMapper fileNameMapper = null;

   

    public ReportCompileTask() {

    }

 

    public void setFile(File file) {

        this.file = file;

    }

 

    public void addConfiguredMapper(Mapper mapper) {

        add(mapper.getImplementation());

    }

 

    public void add(FileNameMapper fileNameMapper) throws BuildException {

        if (this.fileNameMapper != null) {

            throw new BuildException("Only one mapper may be added to the "

                + getTaskName() + " task.");

        }

        this.fileNameMapper = fileNameMapper;

    }

 

    public void addFileset(FileSet set) {

        filesets.add(set);

    }

 

    protected synchronized void checkConfiguration() throws BuildException {

        if (file != null && file.exists() && file.isDirectory()) {

            throw new BuildException(

                              "Use a resource collection to ReportCompileTask directories.");

        }

    }

 

    public void execute() throws BuildException {

        checkConfiguration();

        //doSomething();

    }

 

    protected void doSomething() throws BuildException {

    }

 

}

 

 

Javaデコンパイラ

http://allabout.co.jp/internet/java/closeup/CU20051206B/index.htm

 

$ Jad <クラス名>

Jadデコンパイラでクラスのデコンパイルができる。

 

TODO: JadClipseの研究

http://sourceforge.net/projects/jadclipse/

 

 

興味のあるクラス

Class

Method

Runtime